(61d00a474) v0.9.7.1
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 VPX_TEST_ACM_RANDOM_H_
|
||||
#define VPX_TEST_ACM_RANDOM_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
class ACMRandom {
|
||||
public:
|
||||
ACMRandom() : random_(DeterministicSeed()) {}
|
||||
|
||||
explicit ACMRandom(int seed) : random_(seed) {}
|
||||
|
||||
void Reset(int seed) { random_.Reseed(seed); }
|
||||
uint16_t Rand16(void) {
|
||||
const uint32_t value =
|
||||
random_.Generate(testing::internal::Random::kMaxRange);
|
||||
return (value >> 15) & 0xffff;
|
||||
}
|
||||
|
||||
int32_t Rand20Signed(void) {
|
||||
// Use 20 bits: values between 524287 and -524288.
|
||||
const uint32_t value = random_.Generate(1048576);
|
||||
return static_cast<int32_t>(value) - 524288;
|
||||
}
|
||||
|
||||
int16_t Rand16Signed(void) {
|
||||
// Use 16 bits: values between 32767 and -32768.
|
||||
return static_cast<int16_t>(random_.Generate(65536));
|
||||
}
|
||||
|
||||
int16_t Rand13Signed(void) {
|
||||
// Use 13 bits: values between 4095 and -4096.
|
||||
const uint32_t value = random_.Generate(8192);
|
||||
return static_cast<int16_t>(value) - 4096;
|
||||
}
|
||||
|
||||
int16_t Rand9Signed(void) {
|
||||
// Use 9 bits: values between 255 (0x0FF) and -256 (0x100).
|
||||
const uint32_t value = random_.Generate(512);
|
||||
return static_cast<int16_t>(value) - 256;
|
||||
}
|
||||
|
||||
uint8_t Rand8(void) {
|
||||
const uint32_t value =
|
||||
random_.Generate(testing::internal::Random::kMaxRange);
|
||||
// There's a bit more entropy in the upper bits of this implementation.
|
||||
return (value >> 23) & 0xff;
|
||||
}
|
||||
|
||||
uint8_t Rand8Extremes(void) {
|
||||
// Returns a random value near 0 or near 255, to better exercise
|
||||
// saturation behavior.
|
||||
const uint8_t r = Rand8();
|
||||
return static_cast<uint8_t>((r < 128) ? r << 4 : r >> 4);
|
||||
}
|
||||
|
||||
uint32_t RandRange(const uint32_t range) {
|
||||
// testing::internal::Random::Generate provides values in the range
|
||||
// testing::internal::Random::kMaxRange.
|
||||
assert(range <= testing::internal::Random::kMaxRange);
|
||||
return random_.Generate(range);
|
||||
}
|
||||
|
||||
int PseudoUniform(int range) { return random_.Generate(range); }
|
||||
|
||||
int operator()(int n) { return PseudoUniform(n); }
|
||||
|
||||
static int DeterministicSeed(void) { return 0xbaba; }
|
||||
|
||||
private:
|
||||
testing::internal::Random random_;
|
||||
};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // VPX_TEST_ACM_RANDOM_H_
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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 <algorithm>
|
||||
#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/y4m_video_source.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Check if any pixel in a 16x16 macroblock varies between frames.
|
||||
int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous, int mb_r,
|
||||
int mb_c) {
|
||||
for (int plane = 0; plane < 3; plane++) {
|
||||
int r = 16 * mb_r;
|
||||
int c0 = 16 * mb_c;
|
||||
int r_top = std::min(r + 16, static_cast<int>(current.d_h));
|
||||
int c_top = std::min(c0 + 16, static_cast<int>(current.d_w));
|
||||
r = std::max(r, 0);
|
||||
c0 = std::max(c0, 0);
|
||||
if (plane > 0 && current.x_chroma_shift) {
|
||||
c_top = (c_top + 1) >> 1;
|
||||
c0 >>= 1;
|
||||
}
|
||||
if (plane > 0 && current.y_chroma_shift) {
|
||||
r_top = (r_top + 1) >> 1;
|
||||
r >>= 1;
|
||||
}
|
||||
for (; r < r_top; ++r) {
|
||||
for (int c = c0; c < c_top; ++c) {
|
||||
if (current.planes[plane][current.stride[plane] * r + c] !=
|
||||
previous.planes[plane][previous.stride[plane] * r + c]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GenerateMap(int mb_rows, int mb_cols, const vpx_image_t ¤t,
|
||||
const vpx_image_t &previous, uint8_t *map) {
|
||||
for (int mb_r = 0; mb_r < mb_rows; ++mb_r) {
|
||||
for (int mb_c = 0; mb_c < mb_cols; ++mb_c) {
|
||||
map[mb_r * mb_cols + mb_c] = CheckMb(current, previous, mb_r, mb_c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int kAqModeCyclicRefresh = 3;
|
||||
|
||||
class ActiveMapRefreshTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
ActiveMapRefreshTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
virtual ~ActiveMapRefreshTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
cpu_used_ = GET_PARAM(2);
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
::libvpx_test::Y4mVideoSource *y4m_video =
|
||||
static_cast<libvpx_test::Y4mVideoSource *>(video);
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh);
|
||||
} else if (video->frame() >= 2 && video->img()) {
|
||||
vpx_image_t *current = video->img();
|
||||
vpx_image_t *previous = y4m_holder_->img();
|
||||
ASSERT_TRUE(previous != NULL);
|
||||
vpx_active_map_t map = vpx_active_map_t();
|
||||
const int width = static_cast<int>(current->d_w);
|
||||
const int height = static_cast<int>(current->d_h);
|
||||
const int mb_width = (width + 15) / 16;
|
||||
const int mb_height = (height + 15) / 16;
|
||||
uint8_t *active_map = new uint8_t[mb_width * mb_height];
|
||||
GenerateMap(mb_height, mb_width, *current, *previous, active_map);
|
||||
map.cols = mb_width;
|
||||
map.rows = mb_height;
|
||||
map.active_map = active_map;
|
||||
encoder->Control(VP8E_SET_ACTIVEMAP, &map);
|
||||
delete[] active_map;
|
||||
}
|
||||
if (video->img()) {
|
||||
y4m_video->SwapBuffers(y4m_holder_);
|
||||
}
|
||||
}
|
||||
|
||||
int cpu_used_;
|
||||
::libvpx_test::Y4mVideoSource *y4m_holder_;
|
||||
};
|
||||
|
||||
TEST_P(ActiveMapRefreshTest, Test) {
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.g_profile = 1;
|
||||
cfg_.rc_target_bitrate = 600;
|
||||
cfg_.rc_resize_allowed = 0;
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 30;
|
||||
cfg_.g_pass = VPX_RC_ONE_PASS;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.kf_max_dist = 90000;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, 30);
|
||||
::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, 30);
|
||||
video_holder.Begin();
|
||||
y4m_holder_ = &video_holder;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(ActiveMapRefreshTest,
|
||||
::testing::Values(::libvpx_test::kRealTime),
|
||||
::testing::Range(5, 6));
|
||||
} // namespace
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 "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 {
|
||||
|
||||
class ActiveMapTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
static const int kWidth = 208;
|
||||
static const int kHeight = 144;
|
||||
|
||||
ActiveMapTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
virtual ~ActiveMapTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
cpu_used_ = GET_PARAM(2);
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||
} else if (video->frame() == 3) {
|
||||
vpx_active_map_t map = vpx_active_map_t();
|
||||
/* clang-format off */
|
||||
uint8_t active_map[9 * 13] = {
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1,
|
||||
0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1,
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
|
||||
};
|
||||
/* clang-format on */
|
||||
map.cols = (kWidth + 15) / 16;
|
||||
map.rows = (kHeight + 15) / 16;
|
||||
ASSERT_EQ(map.cols, 13u);
|
||||
ASSERT_EQ(map.rows, 9u);
|
||||
map.active_map = active_map;
|
||||
encoder->Control(VP8E_SET_ACTIVEMAP, &map);
|
||||
} else if (video->frame() == 15) {
|
||||
vpx_active_map_t map = vpx_active_map_t();
|
||||
map.cols = (kWidth + 15) / 16;
|
||||
map.rows = (kHeight + 15) / 16;
|
||||
map.active_map = NULL;
|
||||
encoder->Control(VP8E_SET_ACTIVEMAP, &map);
|
||||
}
|
||||
}
|
||||
|
||||
int cpu_used_;
|
||||
};
|
||||
|
||||
TEST_P(ActiveMapTest, Test) {
|
||||
// Validate that this non multiple of 64 wide clip encodes
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_target_bitrate = 400;
|
||||
cfg_.rc_resize_allowed = 0;
|
||||
cfg_.g_pass = VPX_RC_ONE_PASS;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.kf_max_dist = 90000;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30, 1,
|
||||
0, 20);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(ActiveMapTest,
|
||||
::testing::Values(::libvpx_test::kRealTime),
|
||||
::testing::Range(0, 9));
|
||||
} // namespace
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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 <math.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_dsp/postproc.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
static const int kNoiseSize = 3072;
|
||||
|
||||
// TODO(jimbankoski): make width and height integers not unsigned.
|
||||
typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise,
|
||||
int blackclamp, int whiteclamp, int width,
|
||||
int height, int pitch);
|
||||
|
||||
typedef std::tuple<double, AddNoiseFunc> AddNoiseTestFPParam;
|
||||
|
||||
class AddNoiseTest : public ::testing::Test,
|
||||
public ::testing::WithParamInterface<AddNoiseTestFPParam> {
|
||||
public:
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
virtual ~AddNoiseTest() {}
|
||||
};
|
||||
|
||||
double stddev6(char a, char b, char c, char d, char e, char f) {
|
||||
const double n = (a + b + c + d + e + f) / 6.0;
|
||||
const double v = ((a - n) * (a - n) + (b - n) * (b - n) + (c - n) * (c - n) +
|
||||
(d - n) * (d - n) + (e - n) * (e - n) + (f - n) * (f - n)) /
|
||||
6.0;
|
||||
return sqrt(v);
|
||||
}
|
||||
|
||||
TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
||||
const int width = 64;
|
||||
const int height = 64;
|
||||
const int image_size = width * height;
|
||||
int8_t noise[kNoiseSize];
|
||||
const int clamp = vpx_setup_noise(GET_PARAM(0), noise, kNoiseSize);
|
||||
uint8_t *const s =
|
||||
reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s)));
|
||||
ASSERT_TRUE(s != NULL);
|
||||
memset(s, 99, image_size * sizeof(*s));
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
|
||||
|
||||
// Check to make sure we don't end up having either the same or no added
|
||||
// noise either vertically or horizontally.
|
||||
for (int i = 0; i < image_size - 6 * width - 6; ++i) {
|
||||
const double hd = stddev6(s[i] - 99, s[i + 1] - 99, s[i + 2] - 99,
|
||||
s[i + 3] - 99, s[i + 4] - 99, s[i + 5] - 99);
|
||||
const double vd = stddev6(s[i] - 99, s[i + width] - 99,
|
||||
s[i + 2 * width] - 99, s[i + 3 * width] - 99,
|
||||
s[i + 4 * width] - 99, s[i + 5 * width] - 99);
|
||||
|
||||
EXPECT_NE(hd, 0);
|
||||
EXPECT_NE(vd, 0);
|
||||
}
|
||||
|
||||
// Initialize pixels in the image to 255 and check for roll over.
|
||||
memset(s, 255, image_size);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
|
||||
|
||||
// Check to make sure don't roll over.
|
||||
for (int i = 0; i < image_size; ++i) {
|
||||
EXPECT_GT(static_cast<int>(s[i]), clamp) << "i = " << i;
|
||||
}
|
||||
|
||||
// Initialize pixels in the image to 0 and check for roll under.
|
||||
memset(s, 0, image_size);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
|
||||
|
||||
// Check to make sure don't roll under.
|
||||
for (int i = 0; i < image_size; ++i) {
|
||||
EXPECT_LT(static_cast<int>(s[i]), 255 - clamp) << "i = " << i;
|
||||
}
|
||||
|
||||
vpx_free(s);
|
||||
}
|
||||
|
||||
TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
||||
const int width = 64;
|
||||
const int height = 64;
|
||||
const int image_size = width * height;
|
||||
int8_t noise[kNoiseSize];
|
||||
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
|
||||
|
||||
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||
uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||
ASSERT_TRUE(s != NULL);
|
||||
ASSERT_TRUE(d != NULL);
|
||||
|
||||
memset(s, 99, image_size);
|
||||
memset(d, 99, image_size);
|
||||
|
||||
srand(0);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
|
||||
srand(0);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width));
|
||||
|
||||
for (int i = 0; i < image_size; ++i) {
|
||||
EXPECT_EQ(static_cast<int>(s[i]), static_cast<int>(d[i])) << "i = " << i;
|
||||
}
|
||||
|
||||
vpx_free(d);
|
||||
vpx_free(s);
|
||||
}
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, AddNoiseTest,
|
||||
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_c),
|
||||
make_tuple(4.4, vpx_plane_add_noise_c)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, AddNoiseTest,
|
||||
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_sse2),
|
||||
make_tuple(4.4, vpx_plane_add_noise_sse2)));
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, AddNoiseTest,
|
||||
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_msa),
|
||||
make_tuple(4.4, vpx_plane_add_noise_msa)));
|
||||
#endif
|
||||
} // namespace
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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 "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 {
|
||||
|
||||
class AltRefAqSegmentTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
AltRefAqSegmentTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
virtual ~AltRefAqSegmentTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
set_cpu_used_ = GET_PARAM(2);
|
||||
aq_mode_ = 0;
|
||||
alt_ref_aq_mode_ = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP9E_SET_ALT_REF_AQ, alt_ref_aq_mode_);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
|
||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100);
|
||||
}
|
||||
}
|
||||
|
||||
int set_cpu_used_;
|
||||
int aq_mode_;
|
||||
int alt_ref_aq_mode_;
|
||||
};
|
||||
|
||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||
// (ALT_REF_AQ=0, AQ=0/no_aq)
|
||||
// encodes and decodes without a mismatch.
|
||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ0) {
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
|
||||
aq_mode_ = 0;
|
||||
alt_ref_aq_mode_ = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 100);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||
// (ALT_REF_AQ=0, AQ=1/variance_aq)
|
||||
// encodes and decodes without a mismatch.
|
||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ1) {
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
|
||||
aq_mode_ = 1;
|
||||
alt_ref_aq_mode_ = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 100);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||
// (ALT_REF_AQ=0, AQ=2/complexity_aq)
|
||||
// encodes and decodes without a mismatch.
|
||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ2) {
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
|
||||
aq_mode_ = 2;
|
||||
alt_ref_aq_mode_ = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 100);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||
// (ALT_REF_AQ=0, AQ=3/cyclicrefresh_aq)
|
||||
// encodes and decodes without a mismatch.
|
||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ3) {
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
|
||||
aq_mode_ = 3;
|
||||
alt_ref_aq_mode_ = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 100);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||
// (ALT_REF_AQ=0, AQ=4/equator360_aq)
|
||||
// encodes and decodes without a mismatch.
|
||||
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ4) {
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
|
||||
aq_mode_ = 4;
|
||||
alt_ref_aq_mode_ = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 100);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(AltRefAqSegmentTest,
|
||||
::testing::Values(::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kTwoPassGood),
|
||||
::testing::Range(2, 5));
|
||||
} // namespace
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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 "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 {
|
||||
|
||||
#if CONFIG_VP8_ENCODER
|
||||
|
||||
// lookahead range: [kLookAheadMin, kLookAheadMax).
|
||||
const int kLookAheadMin = 5;
|
||||
const int kLookAheadMax = 26;
|
||||
|
||||
class AltRefTest : public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<int> {
|
||||
protected:
|
||||
AltRefTest() : EncoderTest(GET_PARAM(0)), altref_count_(0) {}
|
||||
virtual ~AltRefTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(libvpx_test::kTwoPassGood);
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) { altref_count_ = 0; }
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_CPUUSED, 3);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) ++altref_count_;
|
||||
}
|
||||
|
||||
int altref_count() const { return altref_count_; }
|
||||
|
||||
private:
|
||||
int altref_count_;
|
||||
};
|
||||
|
||||
TEST_P(AltRefTest, MonotonicTimestamps) {
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
cfg_.g_lag_in_frames = GET_PARAM(1);
|
||||
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
timebase.den, timebase.num, 0, 30);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
EXPECT_GE(altref_count(), 1);
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(AltRefTest,
|
||||
::testing::Range(kLookAheadMin, kLookAheadMax));
|
||||
|
||||
#endif // CONFIG_VP8_ENCODER
|
||||
|
||||
class AltRefForcedKeyTestLarge
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
AltRefForcedKeyTestLarge()
|
||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
||||
cpu_used_(GET_PARAM(2)), forced_kf_frame_num_(1), frame_num_(0) {}
|
||||
virtual ~AltRefForcedKeyTestLarge() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.g_threads = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
#if CONFIG_VP9_ENCODER
|
||||
// override test default for tile columns if necessary.
|
||||
if (GET_PARAM(0) == &libvpx_test::kVP9) {
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
frame_flags_ =
|
||||
(video->frame() == forced_kf_frame_num_) ? VPX_EFLAG_FORCE_KF : 0;
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
if (frame_num_ == forced_kf_frame_num_) {
|
||||
ASSERT_TRUE(!!(pkt->data.frame.flags & VPX_FRAME_IS_KEY))
|
||||
<< "Frame #" << frame_num_ << " isn't a keyframe!";
|
||||
}
|
||||
++frame_num_;
|
||||
}
|
||||
|
||||
::libvpx_test::TestMode encoding_mode_;
|
||||
int cpu_used_;
|
||||
unsigned int forced_kf_frame_num_;
|
||||
unsigned int frame_num_;
|
||||
};
|
||||
|
||||
TEST_P(AltRefForcedKeyTestLarge, Frame1IsKey) {
|
||||
const vpx_rational timebase = { 1, 30 };
|
||||
const int lag_values[] = { 3, 15, 25, -1 };
|
||||
|
||||
forced_kf_frame_num_ = 1;
|
||||
for (int i = 0; lag_values[i] != -1; ++i) {
|
||||
frame_num_ = 0;
|
||||
cfg_.g_lag_in_frames = lag_values[i];
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
timebase.den, timebase.num, 0, 30);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AltRefForcedKeyTestLarge, ForcedFrameIsKey) {
|
||||
const vpx_rational timebase = { 1, 30 };
|
||||
const int lag_values[] = { 3, 15, 25, -1 };
|
||||
|
||||
for (int i = 0; lag_values[i] != -1; ++i) {
|
||||
frame_num_ = 0;
|
||||
forced_kf_frame_num_ = lag_values[i] - 1;
|
||||
cfg_.g_lag_in_frames = lag_values[i];
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
timebase.den, timebase.num, 0, 30);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(AltRefForcedKeyTestLarge,
|
||||
::testing::Values(::libvpx_test::kOnePassGood),
|
||||
::testing::Range(0, 9));
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(AltRefForcedKeyTestLarge,
|
||||
::testing::Values(::libvpx_test::kOnePassGood),
|
||||
::testing::Range(0, 9));
|
||||
} // namespace
|
||||
@@ -0,0 +1,57 @@
|
||||
# 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.
|
||||
#
|
||||
# This make file builds vpx_test app for android.
|
||||
# The test app itself runs on the command line through adb shell
|
||||
# The paths are really messed up as the libvpx make file
|
||||
# expects to be made from a parent directory.
|
||||
CUR_WD := $(call my-dir)
|
||||
BINDINGS_DIR := $(CUR_WD)/../../..
|
||||
LOCAL_PATH := $(CUR_WD)/../../..
|
||||
|
||||
#libwebm
|
||||
include $(CLEAR_VARS)
|
||||
include $(BINDINGS_DIR)/libvpx/third_party/libwebm/Android.mk
|
||||
LOCAL_PATH := $(CUR_WD)/../../..
|
||||
|
||||
#libvpx
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_STATIC_LIBRARIES := libwebm
|
||||
include $(BINDINGS_DIR)/libvpx/build/make/Android.mk
|
||||
LOCAL_PATH := $(CUR_WD)/../..
|
||||
|
||||
#libgtest
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_ARM_MODE := arm
|
||||
LOCAL_CPP_EXTENSION := .cc
|
||||
LOCAL_MODULE := gtest
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/third_party/googletest/src/include/
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/include/
|
||||
LOCAL_SRC_FILES := ./third_party/googletest/src/src/gtest-all.cc
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
#libvpx_test
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_ARM_MODE := arm
|
||||
LOCAL_MODULE := libvpx_test
|
||||
LOCAL_STATIC_LIBRARIES := gtest libwebm
|
||||
|
||||
ifeq ($(ENABLE_SHARED),1)
|
||||
LOCAL_SHARED_LIBRARIES := vpx
|
||||
else
|
||||
LOCAL_STATIC_LIBRARIES += vpx
|
||||
endif
|
||||
|
||||
include $(LOCAL_PATH)/test/test.mk
|
||||
LOCAL_C_INCLUDES := $(BINDINGS_DIR)
|
||||
FILTERED_SRC := $(sort $(filter %.cc %.c, $(LIBVPX_TEST_SRCS-yes)))
|
||||
LOCAL_SRC_FILES := $(addprefix ./test/, $(FILTERED_SRC))
|
||||
# some test files depend on *_rtcd.h, ensure they're generated first.
|
||||
$(eval $(call rtcd_dep_template))
|
||||
include $(BUILD_EXECUTABLE)
|
||||
@@ -0,0 +1,33 @@
|
||||
Android.mk will build vpx unittests on android.
|
||||
1) Configure libvpx from the parent directory:
|
||||
./libvpx/configure --target=armv7-android-gcc --enable-external-build \
|
||||
--enable-postproc --disable-install-srcs --enable-multi-res-encoding \
|
||||
--enable-temporal-denoising --disable-unit-tests --disable-install-docs \
|
||||
--disable-examples --disable-runtime-cpu-detect
|
||||
|
||||
2) From the parent directory, invoke ndk-build:
|
||||
NDK_PROJECT_PATH=. ndk-build APP_BUILD_SCRIPT=./libvpx/test/android/Android.mk \
|
||||
APP_ABI=armeabi-v7a APP_PLATFORM=android-18 APP_OPTIM=release \
|
||||
APP_STL=c++_static
|
||||
|
||||
Note: Both adb and ndk-build are available at:
|
||||
https://developer.android.com/studio#downloads
|
||||
https://developer.android.com/ndk/downloads
|
||||
|
||||
3) Run get_files.py to download the test files:
|
||||
python get_files.py -i /path/to/test-data.sha1 -o /path/to/put/files \
|
||||
-u http://downloads.webmproject.org/test_data/libvpx
|
||||
|
||||
4) Transfer files to device using adb. Ensure you have proper permissions for
|
||||
the target
|
||||
|
||||
adb push /path/to/test_files /data/local/tmp
|
||||
adb push /path/to/built_libs /data/local/tmp
|
||||
|
||||
NOTE: Built_libs defaults to parent_dir/libs/armeabi-v7a
|
||||
|
||||
5) Run tests:
|
||||
adb shell
|
||||
(on device)
|
||||
cd /data/local/tmp
|
||||
LD_LIBRARY_PATH=. ./vpx_test
|
||||
@@ -0,0 +1,118 @@
|
||||
# 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.
|
||||
#
|
||||
# This simple script pulls test files from the webm homepage
|
||||
# It is intelligent enough to only pull files if
|
||||
# 1) File / test_data folder does not exist
|
||||
# 2) SHA mismatch
|
||||
|
||||
import pycurl
|
||||
import csv
|
||||
import hashlib
|
||||
import re
|
||||
import os.path
|
||||
import time
|
||||
import itertools
|
||||
import sys
|
||||
import getopt
|
||||
|
||||
#globals
|
||||
url = ''
|
||||
file_list_path = ''
|
||||
local_resource_path = ''
|
||||
|
||||
# Helper functions:
|
||||
# A simple function which returns the sha hash of a file in hex
|
||||
def get_file_sha(filename):
|
||||
try:
|
||||
sha_hash = hashlib.sha1()
|
||||
with open(filename, 'rb') as file:
|
||||
buf = file.read(HASH_CHUNK)
|
||||
while len(buf) > 0:
|
||||
sha_hash.update(buf)
|
||||
buf = file.read(HASH_CHUNK)
|
||||
return sha_hash.hexdigest()
|
||||
except IOError:
|
||||
print "Error reading " + filename
|
||||
|
||||
# Downloads a file from a url, and then checks the sha against the passed
|
||||
# in sha
|
||||
def download_and_check_sha(url, filename, sha):
|
||||
path = os.path.join(local_resource_path, filename)
|
||||
fp = open(path, "wb")
|
||||
curl = pycurl.Curl()
|
||||
curl.setopt(pycurl.URL, url + "/" + filename)
|
||||
curl.setopt(pycurl.WRITEDATA, fp)
|
||||
curl.perform()
|
||||
curl.close()
|
||||
fp.close()
|
||||
return get_file_sha(path) == sha
|
||||
|
||||
#constants
|
||||
ftp_retries = 3
|
||||
|
||||
SHA_COL = 0
|
||||
NAME_COL = 1
|
||||
EXPECTED_COL = 2
|
||||
HASH_CHUNK = 65536
|
||||
|
||||
# Main script
|
||||
try:
|
||||
opts, args = \
|
||||
getopt.getopt(sys.argv[1:], \
|
||||
"u:i:o:", ["url=", "input_csv=", "output_dir="])
|
||||
except:
|
||||
print 'get_files.py -u <url> -i <input_csv> -o <output_dir>'
|
||||
sys.exit(2)
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt == '-u':
|
||||
url = arg
|
||||
elif opt in ("-i", "--input_csv"):
|
||||
file_list_path = os.path.join(arg)
|
||||
elif opt in ("-o", "--output_dir"):
|
||||
local_resource_path = os.path.join(arg)
|
||||
|
||||
if len(sys.argv) != 7:
|
||||
print "Expects two paths and a url!"
|
||||
exit(1)
|
||||
|
||||
if not os.path.isdir(local_resource_path):
|
||||
os.makedirs(local_resource_path)
|
||||
|
||||
file_list_csv = open(file_list_path, "rb")
|
||||
|
||||
# Our 'csv' file uses multiple spaces as a delimiter, python's
|
||||
# csv class only uses single character delimiters, so we convert them below
|
||||
file_list_reader = csv.reader((re.sub(' +', ' ', line) \
|
||||
for line in file_list_csv), delimiter = ' ')
|
||||
|
||||
file_shas = []
|
||||
file_names = []
|
||||
|
||||
for row in file_list_reader:
|
||||
if len(row) != EXPECTED_COL:
|
||||
continue
|
||||
file_shas.append(row[SHA_COL])
|
||||
file_names.append(row[NAME_COL])
|
||||
|
||||
file_list_csv.close()
|
||||
|
||||
# Download files, only if they don't already exist and have correct shas
|
||||
for filename, sha in itertools.izip(file_names, file_shas):
|
||||
path = os.path.join(local_resource_path, filename)
|
||||
if os.path.isfile(path) \
|
||||
and get_file_sha(path) == sha:
|
||||
print path + ' exists, skipping'
|
||||
continue
|
||||
for retry in range(0, ftp_retries):
|
||||
print "Downloading " + path
|
||||
if not download_and_check_sha(url, filename, sha):
|
||||
print "Sha does not match, retrying..."
|
||||
else:
|
||||
break
|
||||
@@ -0,0 +1,57 @@
|
||||
# Copyright (c) 2014 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.
|
||||
|
||||
"""Standalone script which parses a gtest log for json.
|
||||
|
||||
Json is returned returns as an array. This script is used by the libvpx
|
||||
waterfall to gather json results mixed in with gtest logs. This is
|
||||
dubious software engineering.
|
||||
"""
|
||||
|
||||
import getopt
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print "Expects a file to write json to!"
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
opts, _ = \
|
||||
getopt.getopt(sys.argv[1:], \
|
||||
'o:', ['output-json='])
|
||||
except getopt.GetOptError:
|
||||
print 'scrape_gtest_log.py -o <output_json>'
|
||||
sys.exit(2)
|
||||
|
||||
output_json = ''
|
||||
for opt, arg in opts:
|
||||
if opt in ('-o', '--output-json'):
|
||||
output_json = os.path.join(arg)
|
||||
|
||||
blob = sys.stdin.read()
|
||||
json_string = '[' + ','.join('{' + x + '}' for x in
|
||||
re.findall(r'{([^}]*.?)}', blob)) + ']'
|
||||
print blob
|
||||
|
||||
output = json.dumps(json.loads(json_string), indent=4, sort_keys=True)
|
||||
print output
|
||||
|
||||
path = os.path.dirname(output_json)
|
||||
if path and not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
outfile = open(output_json, 'w')
|
||||
outfile.write(output)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@@ -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.
|
||||
*/
|
||||
#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 {
|
||||
|
||||
class AqSegmentTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
AqSegmentTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
virtual ~AqSegmentTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
set_cpu_used_ = GET_PARAM(2);
|
||||
aq_mode_ = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
|
||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100);
|
||||
}
|
||||
}
|
||||
|
||||
int set_cpu_used_;
|
||||
int aq_mode_;
|
||||
};
|
||||
|
||||
// Validate that this AQ segmentation mode (AQ=1, variance_ap)
|
||||
// encodes and decodes without a mismatch.
|
||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ1) {
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
|
||||
aq_mode_ = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 100);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
// Validate that this AQ segmentation mode (AQ=2, complexity_aq)
|
||||
// encodes and decodes without a mismatch.
|
||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ2) {
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
|
||||
aq_mode_ = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 100);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
// Validate that this AQ segmentation mode (AQ=3, cyclic_refresh_aq)
|
||||
// encodes and decodes without a mismatch.
|
||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ3) {
|
||||
cfg_.rc_min_quantizer = 8;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
|
||||
aq_mode_ = 3;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 100);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(AqSegmentTest,
|
||||
::testing::Values(::libvpx_test::kRealTime,
|
||||
::libvpx_test::kOnePassGood),
|
||||
::testing::Range(3, 9));
|
||||
} // namespace
|
||||
@@ -0,0 +1,737 @@
|
||||
/*
|
||||
* 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 <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename Pixel>
|
||||
class AverageTestBase : public ::testing::Test {
|
||||
public:
|
||||
AverageTestBase(int width, int height)
|
||||
: width_(width), height_(height), source_data_(NULL), source_stride_(0),
|
||||
bit_depth_(8) {}
|
||||
|
||||
virtual void TearDown() {
|
||||
vpx_free(source_data_);
|
||||
source_data_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
protected:
|
||||
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
||||
static const int kDataAlignment = 16;
|
||||
static const int kDataBlockSize = 64 * 128;
|
||||
|
||||
virtual void SetUp() {
|
||||
source_data_ = reinterpret_cast<Pixel *>(
|
||||
vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0])));
|
||||
ASSERT_TRUE(source_data_ != NULL);
|
||||
source_stride_ = (width_ + 31) & ~31;
|
||||
bit_depth_ = 8;
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
// Sum Pixels
|
||||
static unsigned int ReferenceAverage8x8(const Pixel *source, int pitch) {
|
||||
unsigned int average = 0;
|
||||
for (int h = 0; h < 8; ++h) {
|
||||
for (int w = 0; w < 8; ++w) average += source[h * pitch + w];
|
||||
}
|
||||
return ((average + 32) >> 6);
|
||||
}
|
||||
|
||||
static unsigned int ReferenceAverage4x4(const Pixel *source, int pitch) {
|
||||
unsigned int average = 0;
|
||||
for (int h = 0; h < 4; ++h) {
|
||||
for (int w = 0; w < 4; ++w) average += source[h * pitch + w];
|
||||
}
|
||||
return ((average + 8) >> 4);
|
||||
}
|
||||
|
||||
void FillConstant(Pixel fill_constant) {
|
||||
for (int i = 0; i < width_ * height_; ++i) {
|
||||
source_data_[i] = fill_constant;
|
||||
}
|
||||
}
|
||||
|
||||
void FillRandom() {
|
||||
for (int i = 0; i < width_ * height_; ++i) {
|
||||
source_data_[i] = rnd_.Rand16() & ((1 << bit_depth_) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
int width_, height_;
|
||||
Pixel *source_data_;
|
||||
int source_stride_;
|
||||
int bit_depth_;
|
||||
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch);
|
||||
|
||||
typedef std::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
||||
|
||||
class AverageTest : public AverageTestBase<uint8_t>,
|
||||
public ::testing::WithParamInterface<AvgFunc> {
|
||||
public:
|
||||
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||
|
||||
protected:
|
||||
void CheckAverages() {
|
||||
const int block_size = GET_PARAM(3);
|
||||
unsigned int expected = 0;
|
||||
if (block_size == 8) {
|
||||
expected =
|
||||
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
|
||||
} else if (block_size == 4) {
|
||||
expected =
|
||||
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_));
|
||||
unsigned int actual =
|
||||
GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_);
|
||||
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
};
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
class AverageTestHBD : public AverageTestBase<uint16_t>,
|
||||
public ::testing::WithParamInterface<AvgFunc> {
|
||||
public:
|
||||
AverageTestHBD() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||
|
||||
protected:
|
||||
void CheckAverages() {
|
||||
const int block_size = GET_PARAM(3);
|
||||
unsigned int expected = 0;
|
||||
if (block_size == 8) {
|
||||
expected =
|
||||
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
|
||||
} else if (block_size == 4) {
|
||||
expected =
|
||||
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(GET_PARAM(4)(
|
||||
CONVERT_TO_BYTEPTR(source_data_ + GET_PARAM(2)), source_stride_));
|
||||
unsigned int actual = GET_PARAM(4)(
|
||||
CONVERT_TO_BYTEPTR(source_data_ + GET_PARAM(2)), source_stride_);
|
||||
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
};
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref,
|
||||
const int ref_stride, const int height);
|
||||
|
||||
typedef std::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
||||
|
||||
class IntProRowTest : public AverageTestBase<uint8_t>,
|
||||
public ::testing::WithParamInterface<IntProRowParam> {
|
||||
public:
|
||||
IntProRowTest()
|
||||
: AverageTestBase(16, GET_PARAM(0)), hbuf_asm_(NULL), hbuf_c_(NULL) {
|
||||
asm_func_ = GET_PARAM(1);
|
||||
c_func_ = GET_PARAM(2);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
source_data_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0])));
|
||||
ASSERT_TRUE(source_data_ != NULL);
|
||||
|
||||
hbuf_asm_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(kDataAlignment, sizeof(*hbuf_asm_) * 16));
|
||||
hbuf_c_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(kDataAlignment, sizeof(*hbuf_c_) * 16));
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
vpx_free(source_data_);
|
||||
source_data_ = NULL;
|
||||
vpx_free(hbuf_c_);
|
||||
hbuf_c_ = NULL;
|
||||
vpx_free(hbuf_asm_);
|
||||
hbuf_asm_ = NULL;
|
||||
}
|
||||
|
||||
void RunComparison() {
|
||||
ASM_REGISTER_STATE_CHECK(c_func_(hbuf_c_, source_data_, 0, height_));
|
||||
ASM_REGISTER_STATE_CHECK(asm_func_(hbuf_asm_, source_data_, 0, height_));
|
||||
EXPECT_EQ(0, memcmp(hbuf_c_, hbuf_asm_, sizeof(*hbuf_c_) * 16))
|
||||
<< "Output mismatch";
|
||||
}
|
||||
|
||||
private:
|
||||
IntProRowFunc asm_func_;
|
||||
IntProRowFunc c_func_;
|
||||
int16_t *hbuf_asm_;
|
||||
int16_t *hbuf_c_;
|
||||
};
|
||||
|
||||
typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
|
||||
|
||||
typedef std::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
||||
|
||||
class IntProColTest : public AverageTestBase<uint8_t>,
|
||||
public ::testing::WithParamInterface<IntProColParam> {
|
||||
public:
|
||||
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
|
||||
asm_func_ = GET_PARAM(1);
|
||||
c_func_ = GET_PARAM(2);
|
||||
}
|
||||
|
||||
protected:
|
||||
void RunComparison() {
|
||||
ASM_REGISTER_STATE_CHECK(sum_c_ = c_func_(source_data_, width_));
|
||||
ASM_REGISTER_STATE_CHECK(sum_asm_ = asm_func_(source_data_, width_));
|
||||
EXPECT_EQ(sum_c_, sum_asm_) << "Output mismatch";
|
||||
}
|
||||
|
||||
private:
|
||||
IntProColFunc asm_func_;
|
||||
IntProColFunc c_func_;
|
||||
int16_t sum_asm_;
|
||||
int16_t sum_c_;
|
||||
};
|
||||
|
||||
typedef int (*SatdFunc)(const tran_low_t *coeffs, int length);
|
||||
typedef std::tuple<int, SatdFunc> SatdTestParam;
|
||||
|
||||
class SatdTest : public ::testing::Test,
|
||||
public ::testing::WithParamInterface<SatdTestParam> {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
satd_size_ = GET_PARAM(0);
|
||||
satd_func_ = GET_PARAM(1);
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
src_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*src_) * satd_size_));
|
||||
ASSERT_TRUE(src_ != NULL);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_free(src_);
|
||||
}
|
||||
|
||||
void FillConstant(const tran_low_t val) {
|
||||
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
|
||||
}
|
||||
|
||||
virtual void FillRandom() = 0;
|
||||
|
||||
void Check(const int expected) {
|
||||
int total;
|
||||
ASM_REGISTER_STATE_CHECK(total = satd_func_(src_, satd_size_));
|
||||
EXPECT_EQ(expected, total);
|
||||
}
|
||||
|
||||
tran_low_t *GetCoeff() const { return src_; }
|
||||
|
||||
int satd_size_;
|
||||
ACMRandom rnd_;
|
||||
tran_low_t *src_;
|
||||
|
||||
private:
|
||||
SatdFunc satd_func_;
|
||||
};
|
||||
|
||||
class SatdLowbdTest : public SatdTest {
|
||||
protected:
|
||||
virtual void FillRandom() {
|
||||
for (int i = 0; i < satd_size_; ++i) {
|
||||
const int16_t tmp = rnd_.Rand16Signed();
|
||||
src_[i] = (tran_low_t)tmp;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff, int block_size);
|
||||
typedef std::tuple<int, BlockErrorFunc> BlockErrorTestFPParam;
|
||||
|
||||
class BlockErrorTestFP
|
||||
: public ::testing::Test,
|
||||
public ::testing::WithParamInterface<BlockErrorTestFPParam> {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
txfm_size_ = GET_PARAM(0);
|
||||
block_error_func_ = GET_PARAM(1);
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
coeff_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*coeff_) * txfm_size_));
|
||||
dqcoeff_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*dqcoeff_) * txfm_size_));
|
||||
ASSERT_TRUE(coeff_ != NULL);
|
||||
ASSERT_TRUE(dqcoeff_ != NULL);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_free(coeff_);
|
||||
vpx_free(dqcoeff_);
|
||||
}
|
||||
|
||||
void FillConstant(const tran_low_t coeff_val, const tran_low_t dqcoeff_val) {
|
||||
for (int i = 0; i < txfm_size_; ++i) coeff_[i] = coeff_val;
|
||||
for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = dqcoeff_val;
|
||||
}
|
||||
|
||||
void FillRandom() {
|
||||
// Just two fixed seeds
|
||||
rnd_.Reset(0xb0b9);
|
||||
for (int i = 0; i < txfm_size_; ++i) coeff_[i] = rnd_.Rand16() >> 1;
|
||||
rnd_.Reset(0xb0c8);
|
||||
for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = rnd_.Rand16() >> 1;
|
||||
}
|
||||
|
||||
void Check(const int64_t expected) {
|
||||
int64_t total;
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
total = block_error_func_(coeff_, dqcoeff_, txfm_size_));
|
||||
EXPECT_EQ(expected, total);
|
||||
}
|
||||
|
||||
tran_low_t *GetCoeff() const { return coeff_; }
|
||||
|
||||
tran_low_t *GetDQCoeff() const { return dqcoeff_; }
|
||||
|
||||
int txfm_size_;
|
||||
|
||||
private:
|
||||
tran_low_t *coeff_;
|
||||
tran_low_t *dqcoeff_;
|
||||
BlockErrorFunc block_error_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(AverageTest, MinValue) {
|
||||
FillConstant(0);
|
||||
CheckAverages();
|
||||
}
|
||||
|
||||
TEST_P(AverageTest, MaxValue) {
|
||||
FillConstant(255);
|
||||
CheckAverages();
|
||||
}
|
||||
|
||||
TEST_P(AverageTest, Random) {
|
||||
// The reference frame, but not the source frame, may be unaligned for
|
||||
// certain types of searches.
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
FillRandom();
|
||||
CheckAverages();
|
||||
}
|
||||
}
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
TEST_P(AverageTestHBD, MinValue) {
|
||||
FillConstant(0);
|
||||
CheckAverages();
|
||||
}
|
||||
|
||||
TEST_P(AverageTestHBD, MaxValue) {
|
||||
FillConstant((1 << VPX_BITS_12) - 1);
|
||||
CheckAverages();
|
||||
}
|
||||
|
||||
TEST_P(AverageTestHBD, Random) {
|
||||
bit_depth_ = VPX_BITS_12;
|
||||
// The reference frame, but not the source frame, may be unaligned for
|
||||
// certain types of searches.
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
FillRandom();
|
||||
CheckAverages();
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
TEST_P(IntProRowTest, MinValue) {
|
||||
FillConstant(0);
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(IntProRowTest, MaxValue) {
|
||||
FillConstant(255);
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(IntProRowTest, Random) {
|
||||
FillRandom();
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(IntProColTest, MinValue) {
|
||||
FillConstant(0);
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(IntProColTest, MaxValue) {
|
||||
FillConstant(255);
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(IntProColTest, Random) {
|
||||
FillRandom();
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(SatdLowbdTest, MinValue) {
|
||||
const int kMin = -32640;
|
||||
const int expected = -kMin * satd_size_;
|
||||
FillConstant(kMin);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdLowbdTest, MaxValue) {
|
||||
const int kMax = 32640;
|
||||
const int expected = kMax * satd_size_;
|
||||
FillConstant(kMax);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdLowbdTest, Random) {
|
||||
int expected;
|
||||
switch (satd_size_) {
|
||||
case 16: expected = 261036; break;
|
||||
case 64: expected = 991732; break;
|
||||
case 256: expected = 4136358; break;
|
||||
case 1024: expected = 16677592; break;
|
||||
default:
|
||||
FAIL() << "Invalid satd size (" << satd_size_
|
||||
<< ") valid: 16/64/256/1024";
|
||||
}
|
||||
FillRandom();
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdLowbdTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
const int blocksize = GET_PARAM(0);
|
||||
FillRandom();
|
||||
tran_low_t *coeff = GetCoeff();
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
GET_PARAM(1)(coeff, blocksize);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
class SatdHighbdTest : public SatdTest {
|
||||
protected:
|
||||
virtual void FillRandom() {
|
||||
for (int i = 0; i < satd_size_; ++i) {
|
||||
src_[i] = rnd_.Rand20Signed();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(SatdHighbdTest, MinValue) {
|
||||
const int kMin = -524280;
|
||||
const int expected = -kMin * satd_size_;
|
||||
FillConstant(kMin);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdHighbdTest, MaxValue) {
|
||||
const int kMax = 524280;
|
||||
const int expected = kMax * satd_size_;
|
||||
FillConstant(kMax);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdHighbdTest, Random) {
|
||||
int expected;
|
||||
switch (satd_size_) {
|
||||
case 16: expected = 5249712; break;
|
||||
case 64: expected = 18362120; break;
|
||||
case 256: expected = 66100520; break;
|
||||
case 1024: expected = 266094734; break;
|
||||
default:
|
||||
FAIL() << "Invalid satd size (" << satd_size_
|
||||
<< ") valid: 16/64/256/1024";
|
||||
}
|
||||
FillRandom();
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdHighbdTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
const int blocksize = GET_PARAM(0);
|
||||
FillRandom();
|
||||
tran_low_t *coeff = GetCoeff();
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
GET_PARAM(1)(coeff, blocksize);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
TEST_P(BlockErrorTestFP, MinValue) {
|
||||
const int64_t kMin = -32640;
|
||||
const int64_t expected = kMin * kMin * txfm_size_;
|
||||
FillConstant(kMin, 0);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, MaxValue) {
|
||||
const int64_t kMax = 32640;
|
||||
const int64_t expected = kMax * kMax * txfm_size_;
|
||||
FillConstant(kMax, 0);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, Random) {
|
||||
int64_t expected;
|
||||
switch (txfm_size_) {
|
||||
case 16: expected = 2051681432; break;
|
||||
case 64: expected = 11075114379; break;
|
||||
case 256: expected = 44386271116; break;
|
||||
case 1024: expected = 184774996089; break;
|
||||
default:
|
||||
FAIL() << "Invalid satd size (" << txfm_size_
|
||||
<< ") valid: 16/64/256/1024";
|
||||
}
|
||||
FillRandom();
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
const int blocksize = GET_PARAM(0);
|
||||
FillRandom();
|
||||
tran_low_t *coeff = GetCoeff();
|
||||
tran_low_t *dqcoeff = GetDQCoeff();
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
GET_PARAM(1)(coeff, dqcoeff, blocksize);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
||||
}
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, AverageTest,
|
||||
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
|
||||
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, AverageTestHBD,
|
||||
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_c),
|
||||
make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_c)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, AverageTestHBD,
|
||||
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_sse2),
|
||||
make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_sse2)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, SatdHighbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_c),
|
||||
make_tuple(64, &vpx_satd_c),
|
||||
make_tuple(256, &vpx_satd_c),
|
||||
make_tuple(1024, &vpx_satd_c)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_c),
|
||||
make_tuple(64, &vpx_satd_c),
|
||||
make_tuple(256, &vpx_satd_c),
|
||||
make_tuple(1024, &vpx_satd_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_c),
|
||||
make_tuple(64, &vp9_block_error_fp_c),
|
||||
make_tuple(256, &vp9_block_error_fp_c),
|
||||
make_tuple(1024, &vp9_block_error_fp_c)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, AverageTest,
|
||||
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2),
|
||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2),
|
||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2),
|
||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2),
|
||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_sse2),
|
||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, IntProRowTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
||||
make_tuple(32, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
||||
make_tuple(64, &vpx_int_pro_row_sse2,
|
||||
&vpx_int_pro_row_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, IntProColTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
||||
make_tuple(32, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
||||
make_tuple(64, &vpx_int_pro_col_sse2,
|
||||
&vpx_int_pro_col_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_sse2),
|
||||
make_tuple(64, &vpx_satd_sse2),
|
||||
make_tuple(256, &vpx_satd_sse2),
|
||||
make_tuple(1024, &vpx_satd_sse2)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_sse2),
|
||||
make_tuple(64, &vp9_block_error_fp_sse2),
|
||||
make_tuple(256, &vp9_block_error_fp_sse2),
|
||||
make_tuple(1024, &vp9_block_error_fp_sse2)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_avx2),
|
||||
make_tuple(64, &vpx_satd_avx2),
|
||||
make_tuple(256, &vpx_satd_avx2),
|
||||
make_tuple(1024, &vpx_satd_avx2)));
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, SatdHighbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_highbd_satd_avx2),
|
||||
make_tuple(64, &vpx_highbd_satd_avx2),
|
||||
make_tuple(256, &vpx_highbd_satd_avx2),
|
||||
make_tuple(1024, &vpx_highbd_satd_avx2)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_avx2),
|
||||
make_tuple(64, &vp9_block_error_fp_avx2),
|
||||
make_tuple(256, &vp9_block_error_fp_avx2),
|
||||
make_tuple(1024, &vp9_block_error_fp_avx2)));
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, AverageTest,
|
||||
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon),
|
||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon),
|
||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon),
|
||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon),
|
||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_neon),
|
||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, IntProRowTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
||||
make_tuple(32, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
||||
make_tuple(64, &vpx_int_pro_row_neon,
|
||||
&vpx_int_pro_row_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, IntProColTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
||||
make_tuple(32, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
||||
make_tuple(64, &vpx_int_pro_col_neon,
|
||||
&vpx_int_pro_col_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_neon),
|
||||
make_tuple(64, &vpx_satd_neon),
|
||||
make_tuple(256, &vpx_satd_neon),
|
||||
make_tuple(1024, &vpx_satd_neon)));
|
||||
|
||||
// TODO(jianj): Remove the highbitdepth flag once the SIMD functions are
|
||||
// in place.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_neon),
|
||||
make_tuple(64, &vp9_block_error_fp_neon),
|
||||
make_tuple(256, &vp9_block_error_fp_neon),
|
||||
make_tuple(1024, &vp9_block_error_fp_neon)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, AverageTest,
|
||||
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa),
|
||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa),
|
||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa),
|
||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa),
|
||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, IntProRowTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_row_msa, &vpx_int_pro_row_c),
|
||||
make_tuple(32, &vpx_int_pro_row_msa, &vpx_int_pro_row_c),
|
||||
make_tuple(64, &vpx_int_pro_row_msa,
|
||||
&vpx_int_pro_row_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, IntProColTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_col_msa, &vpx_int_pro_col_c),
|
||||
make_tuple(32, &vpx_int_pro_col_msa, &vpx_int_pro_col_c),
|
||||
make_tuple(64, &vpx_int_pro_col_msa,
|
||||
&vpx_int_pro_col_c)));
|
||||
|
||||
// TODO(jingning): Remove the highbitdepth flag once the SIMD functions are
|
||||
// in place.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_msa),
|
||||
make_tuple(64, &vpx_satd_msa),
|
||||
make_tuple(256, &vpx_satd_msa),
|
||||
make_tuple(1024, &vpx_satd_msa)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_MSA
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <stdio.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "test/bench.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
void AbstractBench::RunNTimes(int n) {
|
||||
for (int r = 0; r < VPX_BENCH_ROBUST_ITER; r++) {
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int j = 0; j < n; ++j) {
|
||||
Run();
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
times_[r] = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractBench::PrintMedian(const char *title) {
|
||||
std::sort(times_, times_ + VPX_BENCH_ROBUST_ITER);
|
||||
const int med = times_[VPX_BENCH_ROBUST_ITER >> 1];
|
||||
int sad = 0;
|
||||
for (int t = 0; t < VPX_BENCH_ROBUST_ITER; t++) {
|
||||
sad += abs(times_[t] - med);
|
||||
}
|
||||
printf("[%10s] %s %.1f ms ( ±%.1f ms )\n", "BENCH ", title, med / 1000.0,
|
||||
sad / (VPX_BENCH_ROBUST_ITER * 1000.0));
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 VPX_TEST_BENCH_H_
|
||||
#define VPX_TEST_BENCH_H_
|
||||
|
||||
// Number of iterations used to compute median run time.
|
||||
#define VPX_BENCH_ROBUST_ITER 15
|
||||
|
||||
class AbstractBench {
|
||||
public:
|
||||
void RunNTimes(int n);
|
||||
void PrintMedian(const char *title);
|
||||
|
||||
protected:
|
||||
// Implement this method and put the code to benchmark in it.
|
||||
virtual void Run() = 0;
|
||||
|
||||
private:
|
||||
int times_[VPX_BENCH_ROBUST_ITER];
|
||||
};
|
||||
|
||||
#endif // VPX_TEST_BENCH_H_
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* 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 <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#if CONFIG_VP9_ENCODER
|
||||
#include "./vp9_rtcd.h"
|
||||
#endif
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vp9/encoder/vp9_blockiness.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
class BlockinessTestBase : public ::testing::Test {
|
||||
public:
|
||||
BlockinessTestBase(int width, int height) : width_(width), height_(height) {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
source_data_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
||||
reference_data_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
||||
}
|
||||
|
||||
static void TearDownTestCase() {
|
||||
vpx_free(source_data_);
|
||||
source_data_ = NULL;
|
||||
vpx_free(reference_data_);
|
||||
reference_data_ = NULL;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
// Handle frames up to 640x480
|
||||
static const int kDataAlignment = 16;
|
||||
static const int kDataBufferSize = 640 * 480;
|
||||
|
||||
virtual void SetUp() {
|
||||
source_stride_ = (width_ + 31) & ~31;
|
||||
reference_stride_ = width_ * 2;
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant, int width,
|
||||
int height) {
|
||||
for (int h = 0; h < height; ++h) {
|
||||
for (int w = 0; w < width; ++w) {
|
||||
data[h * stride + w] = fill_constant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant) {
|
||||
FillConstant(data, stride, fill_constant, width_, height_);
|
||||
}
|
||||
|
||||
void FillRandom(uint8_t *data, int stride, int width, int height) {
|
||||
for (int h = 0; h < height; ++h) {
|
||||
for (int w = 0; w < width; ++w) {
|
||||
data[h * stride + w] = rnd_.Rand8();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FillRandom(uint8_t *data, int stride) {
|
||||
FillRandom(data, stride, width_, height_);
|
||||
}
|
||||
|
||||
void FillRandomBlocky(uint8_t *data, int stride) {
|
||||
for (int h = 0; h < height_; h += 4) {
|
||||
for (int w = 0; w < width_; w += 4) {
|
||||
FillRandom(data + h * stride + w, stride, 4, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FillCheckerboard(uint8_t *data, int stride) {
|
||||
for (int h = 0; h < height_; h += 4) {
|
||||
for (int w = 0; w < width_; w += 4) {
|
||||
if (((h / 4) ^ (w / 4)) & 1) {
|
||||
FillConstant(data + h * stride + w, stride, 255, 4, 4);
|
||||
} else {
|
||||
FillConstant(data + h * stride + w, stride, 0, 4, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Blur(uint8_t *data, int stride, int taps) {
|
||||
int sum = 0;
|
||||
int half_taps = taps / 2;
|
||||
for (int h = 0; h < height_; ++h) {
|
||||
for (int w = 0; w < taps; ++w) {
|
||||
sum += data[w + h * stride];
|
||||
}
|
||||
for (int w = taps; w < width_; ++w) {
|
||||
sum += data[w + h * stride] - data[w - taps + h * stride];
|
||||
data[w - half_taps + h * stride] = (sum + half_taps) / taps;
|
||||
}
|
||||
}
|
||||
for (int w = 0; w < width_; ++w) {
|
||||
for (int h = 0; h < taps; ++h) {
|
||||
sum += data[h + w * stride];
|
||||
}
|
||||
for (int h = taps; h < height_; ++h) {
|
||||
sum += data[w + h * stride] - data[(h - taps) * stride + w];
|
||||
data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
|
||||
}
|
||||
}
|
||||
}
|
||||
int width_, height_;
|
||||
static uint8_t *source_data_;
|
||||
int source_stride_;
|
||||
static uint8_t *reference_data_;
|
||||
int reference_stride_;
|
||||
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
typedef std::tuple<int, int> BlockinessParam;
|
||||
class BlockinessVP9Test
|
||||
: public BlockinessTestBase,
|
||||
public ::testing::WithParamInterface<BlockinessParam> {
|
||||
public:
|
||||
BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||
|
||||
protected:
|
||||
double GetBlockiness() const {
|
||||
return vp9_get_blockiness(source_data_, source_stride_, reference_data_,
|
||||
reference_stride_, width_, height_);
|
||||
}
|
||||
};
|
||||
#endif // CONFIG_VP9_ENCODER
|
||||
|
||||
uint8_t *BlockinessTestBase::source_data_ = NULL;
|
||||
uint8_t *BlockinessTestBase::reference_data_ = NULL;
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
TEST_P(BlockinessVP9Test, SourceBlockierThanReference) {
|
||||
// Source is blockier than reference.
|
||||
FillRandomBlocky(source_data_, source_stride_);
|
||||
FillConstant(reference_data_, reference_stride_, 128);
|
||||
const double super_blocky = GetBlockiness();
|
||||
|
||||
EXPECT_DOUBLE_EQ(0.0, super_blocky)
|
||||
<< "Blocky source should produce 0 blockiness.";
|
||||
}
|
||||
|
||||
TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) {
|
||||
// Source is blockier than reference.
|
||||
FillConstant(source_data_, source_stride_, 128);
|
||||
FillRandomBlocky(reference_data_, reference_stride_);
|
||||
const double super_blocky = GetBlockiness();
|
||||
|
||||
EXPECT_GT(super_blocky, 0.0)
|
||||
<< "Blocky reference should score high for blockiness.";
|
||||
}
|
||||
|
||||
TEST_P(BlockinessVP9Test, BlurringDecreasesBlockiness) {
|
||||
// Source is blockier than reference.
|
||||
FillConstant(source_data_, source_stride_, 128);
|
||||
FillRandomBlocky(reference_data_, reference_stride_);
|
||||
const double super_blocky = GetBlockiness();
|
||||
|
||||
Blur(reference_data_, reference_stride_, 4);
|
||||
const double less_blocky = GetBlockiness();
|
||||
|
||||
EXPECT_GT(super_blocky, less_blocky)
|
||||
<< "A straight blur should decrease blockiness.";
|
||||
}
|
||||
|
||||
TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
|
||||
// Source is blockier than reference.
|
||||
FillConstant(source_data_, source_stride_, 128);
|
||||
FillCheckerboard(reference_data_, reference_stride_);
|
||||
|
||||
const double super_blocky = GetBlockiness();
|
||||
|
||||
Blur(reference_data_, reference_stride_, 4);
|
||||
const double less_blocky = GetBlockiness();
|
||||
|
||||
EXPECT_GT(super_blocky, less_blocky)
|
||||
<< "A straight blur should decrease blockiness.";
|
||||
}
|
||||
#endif // CONFIG_VP9_ENCODER
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// C functions
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
const BlockinessParam c_vp9_tests[] = { make_tuple(320, 240),
|
||||
make_tuple(318, 242),
|
||||
make_tuple(318, 238) };
|
||||
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 "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 {
|
||||
|
||||
class BordersTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
protected:
|
||||
BordersTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
virtual ~BordersTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, 1);
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(BordersTest, TestEncodeHighBitrate) {
|
||||
// Validate that this non multiple of 64 wide clip encodes and decodes
|
||||
// without a mismatch when passing in a very low max q. This pushes
|
||||
// the encoder to producing lots of big partitions which will likely
|
||||
// extend into the border and test the border condition.
|
||||
cfg_.g_lag_in_frames = 25;
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_target_bitrate = 2000;
|
||||
cfg_.rc_max_quantizer = 10;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
40);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
TEST_P(BordersTest, TestLowBitrate) {
|
||||
// Validate that this clip encodes and decodes without a mismatch
|
||||
// when passing in a very high min q. This pushes the encoder to producing
|
||||
// lots of small partitions which might will test the other condition.
|
||||
|
||||
cfg_.g_lag_in_frames = 25;
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
cfg_.rc_min_quantizer = 40;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
40);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(BordersTest,
|
||||
::testing::Values(::libvpx_test::kTwoPassGood));
|
||||
} // namespace
|
||||
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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 VPX_TEST_BUFFER_H_
|
||||
#define VPX_TEST_BUFFER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
template <typename T>
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(int width, int height, int top_padding, int left_padding,
|
||||
int right_padding, int bottom_padding)
|
||||
: width_(width), height_(height), top_padding_(top_padding),
|
||||
left_padding_(left_padding), right_padding_(right_padding),
|
||||
bottom_padding_(bottom_padding), alignment_(0), padding_value_(0),
|
||||
stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int top_padding, int left_padding,
|
||||
int right_padding, int bottom_padding, unsigned int alignment)
|
||||
: width_(width), height_(height), top_padding_(top_padding),
|
||||
left_padding_(left_padding), right_padding_(right_padding),
|
||||
bottom_padding_(bottom_padding), alignment_(alignment),
|
||||
padding_value_(0), stride_(0), raw_size_(0), num_elements_(0),
|
||||
raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int padding)
|
||||
: width_(width), height_(height), top_padding_(padding),
|
||||
left_padding_(padding), right_padding_(padding),
|
||||
bottom_padding_(padding), alignment_(0), padding_value_(0), stride_(0),
|
||||
raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int padding, unsigned int alignment)
|
||||
: width_(width), height_(height), top_padding_(padding),
|
||||
left_padding_(padding), right_padding_(padding),
|
||||
bottom_padding_(padding), alignment_(alignment), padding_value_(0),
|
||||
stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
~Buffer() {
|
||||
if (alignment_) {
|
||||
vpx_free(raw_buffer_);
|
||||
} else {
|
||||
delete[] raw_buffer_;
|
||||
}
|
||||
}
|
||||
|
||||
T *TopLeftPixel() const;
|
||||
|
||||
int stride() const { return stride_; }
|
||||
|
||||
// Set the buffer (excluding padding) to 'value'.
|
||||
void Set(const T value);
|
||||
|
||||
// Set the buffer (excluding padding) to the output of ACMRandom function
|
||||
// 'rand_func'.
|
||||
void Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)());
|
||||
|
||||
// Set the buffer (excluding padding) to the output of ACMRandom function
|
||||
// 'RandRange' with range 'low' to 'high' which typically must be within
|
||||
// testing::internal::Random::kMaxRange (1u << 31). However, because we want
|
||||
// to allow negative low (and high) values, it is restricted to INT32_MAX
|
||||
// here.
|
||||
void Set(ACMRandom *rand_class, const T low, const T high);
|
||||
|
||||
// Copy the contents of Buffer 'a' (excluding padding).
|
||||
void CopyFrom(const Buffer<T> &a);
|
||||
|
||||
void DumpBuffer() const;
|
||||
|
||||
// Highlight the differences between two buffers if they are the same size.
|
||||
void PrintDifference(const Buffer<T> &a) const;
|
||||
|
||||
bool HasPadding() const;
|
||||
|
||||
// Sets all the values in the buffer to 'padding_value'.
|
||||
void SetPadding(const T padding_value);
|
||||
|
||||
// Checks if all the values (excluding padding) are equal to 'value' if the
|
||||
// Buffers are the same size.
|
||||
bool CheckValues(const T value) const;
|
||||
|
||||
// Check that padding matches the expected value or there is no padding.
|
||||
bool CheckPadding() const;
|
||||
|
||||
// Compare the non-padding portion of two buffers if they are the same size.
|
||||
bool CheckValues(const Buffer<T> &a) const;
|
||||
|
||||
bool Init() {
|
||||
if (raw_buffer_ != NULL) return false;
|
||||
EXPECT_GT(width_, 0);
|
||||
EXPECT_GT(height_, 0);
|
||||
EXPECT_GE(top_padding_, 0);
|
||||
EXPECT_GE(left_padding_, 0);
|
||||
EXPECT_GE(right_padding_, 0);
|
||||
EXPECT_GE(bottom_padding_, 0);
|
||||
stride_ = left_padding_ + width_ + right_padding_;
|
||||
num_elements_ = stride_ * (top_padding_ + height_ + bottom_padding_);
|
||||
raw_size_ = num_elements_ * sizeof(T);
|
||||
if (alignment_) {
|
||||
EXPECT_GE(alignment_, sizeof(T));
|
||||
// Ensure alignment of the first value will be preserved.
|
||||
EXPECT_EQ((left_padding_ * sizeof(T)) % alignment_, 0u);
|
||||
// Ensure alignment of the subsequent rows will be preserved when there is
|
||||
// a stride.
|
||||
if (stride_ != width_) {
|
||||
EXPECT_EQ((stride_ * sizeof(T)) % alignment_, 0u);
|
||||
}
|
||||
raw_buffer_ = reinterpret_cast<T *>(vpx_memalign(alignment_, raw_size_));
|
||||
} else {
|
||||
raw_buffer_ = new (std::nothrow) T[num_elements_];
|
||||
}
|
||||
EXPECT_TRUE(raw_buffer_ != NULL);
|
||||
SetPadding(std::numeric_limits<T>::max());
|
||||
return !::testing::Test::HasFailure();
|
||||
}
|
||||
|
||||
private:
|
||||
bool BufferSizesMatch(const Buffer<T> &a) const;
|
||||
|
||||
const int width_;
|
||||
const int height_;
|
||||
const int top_padding_;
|
||||
const int left_padding_;
|
||||
const int right_padding_;
|
||||
const int bottom_padding_;
|
||||
const unsigned int alignment_;
|
||||
T padding_value_;
|
||||
int stride_;
|
||||
int raw_size_;
|
||||
int num_elements_;
|
||||
T *raw_buffer_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T *Buffer<T>::TopLeftPixel() const {
|
||||
if (!raw_buffer_) return NULL;
|
||||
return raw_buffer_ + (top_padding_ * stride_) + left_padding_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(const T value) {
|
||||
if (!raw_buffer_) return;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
src[width] = value;
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()) {
|
||||
if (!raw_buffer_) return;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
src[width] = (*rand_class.*rand_func)();
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(ACMRandom *rand_class, const T low, const T high) {
|
||||
if (!raw_buffer_) return;
|
||||
|
||||
EXPECT_LE(low, high);
|
||||
EXPECT_LE(static_cast<int64_t>(high) - low,
|
||||
std::numeric_limits<int32_t>::max());
|
||||
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
// 'low' will be promoted to unsigned given the return type of RandRange.
|
||||
// Store the value as an int to avoid unsigned overflow warnings when
|
||||
// 'low' is negative.
|
||||
const int32_t value =
|
||||
static_cast<int32_t>((*rand_class).RandRange(high - low));
|
||||
src[width] = static_cast<T>(value + low);
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::CopyFrom(const Buffer<T> &a) {
|
||||
if (!raw_buffer_) return;
|
||||
if (!BufferSizesMatch(a)) return;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = this->TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
b_src[width] = a_src[width];
|
||||
}
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::DumpBuffer() const {
|
||||
if (!raw_buffer_) return;
|
||||
for (int height = 0; height < height_ + top_padding_ + bottom_padding_;
|
||||
++height) {
|
||||
for (int width = 0; width < stride_; ++width) {
|
||||
printf("%4d", raw_buffer_[height + width * stride_]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::HasPadding() const {
|
||||
if (!raw_buffer_) return false;
|
||||
return top_padding_ || left_padding_ || right_padding_ || bottom_padding_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::PrintDifference(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return;
|
||||
if (!BufferSizesMatch(a)) return;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = TopLeftPixel();
|
||||
|
||||
printf("This buffer:\n");
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
printf("*%3d", b_src[width]);
|
||||
} else {
|
||||
printf("%4d", b_src[width]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
|
||||
a_src = a.TopLeftPixel();
|
||||
b_src = TopLeftPixel();
|
||||
|
||||
printf("Reference buffer:\n");
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
printf("*%3d", a_src[width]);
|
||||
} else {
|
||||
printf("%4d", a_src[width]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::SetPadding(const T padding_value) {
|
||||
if (!raw_buffer_) return;
|
||||
padding_value_ = padding_value;
|
||||
|
||||
T *src = raw_buffer_;
|
||||
for (int i = 0; i < num_elements_; ++i) {
|
||||
src[i] = padding_value;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckValues(const T value) const {
|
||||
if (!raw_buffer_) return false;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (value != src[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckPadding() const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (!HasPadding()) return true;
|
||||
|
||||
// Top padding.
|
||||
T const *top = raw_buffer_;
|
||||
for (int i = 0; i < stride_ * top_padding_; ++i) {
|
||||
if (padding_value_ != top[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Left padding.
|
||||
T const *left = TopLeftPixel() - left_padding_;
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < left_padding_; ++width) {
|
||||
if (padding_value_ != left[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
left += stride_;
|
||||
}
|
||||
|
||||
// Right padding.
|
||||
T const *right = TopLeftPixel() + width_;
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < right_padding_; ++width) {
|
||||
if (padding_value_ != right[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
right += stride_;
|
||||
}
|
||||
|
||||
// Bottom padding
|
||||
T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride_;
|
||||
for (int i = 0; i < stride_ * bottom_padding_; ++i) {
|
||||
if (padding_value_ != bottom[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckValues(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (!BufferSizesMatch(a)) return false;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = this->TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (a.width_ != this->width_ || a.height_ != this->height_) {
|
||||
printf(
|
||||
"Reference buffer of size %dx%d does not match this buffer which is "
|
||||
"size %dx%d\n",
|
||||
a.width_, a.height_, this->width_, this->height_);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace libvpx_test
|
||||
#endif // VPX_TEST_BUFFER_H_
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <string>
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/util.h"
|
||||
#if CONFIG_WEBM_IO
|
||||
#include "test/webm_video_source.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
|
||||
const int kLegacyByteAlignment = 0;
|
||||
const int kLegacyYPlaneByteAlignment = 32;
|
||||
const int kNumPlanesToCheck = 3;
|
||||
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
||||
const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5";
|
||||
|
||||
struct ByteAlignmentTestParam {
|
||||
int byte_alignment;
|
||||
vpx_codec_err_t expected_value;
|
||||
bool decode_remaining;
|
||||
};
|
||||
|
||||
const ByteAlignmentTestParam kBaTestParams[] = {
|
||||
{ kLegacyByteAlignment, VPX_CODEC_OK, true },
|
||||
{ 32, VPX_CODEC_OK, true },
|
||||
{ 64, VPX_CODEC_OK, true },
|
||||
{ 128, VPX_CODEC_OK, true },
|
||||
{ 256, VPX_CODEC_OK, true },
|
||||
{ 512, VPX_CODEC_OK, true },
|
||||
{ 1024, VPX_CODEC_OK, true },
|
||||
{ 1, VPX_CODEC_INVALID_PARAM, false },
|
||||
{ -2, VPX_CODEC_INVALID_PARAM, false },
|
||||
{ 4, VPX_CODEC_INVALID_PARAM, false },
|
||||
{ 16, VPX_CODEC_INVALID_PARAM, false },
|
||||
{ 255, VPX_CODEC_INVALID_PARAM, false },
|
||||
{ 2048, VPX_CODEC_INVALID_PARAM, false },
|
||||
};
|
||||
|
||||
// Class for testing byte alignment of reference buffers.
|
||||
class ByteAlignmentTest
|
||||
: public ::testing::TestWithParam<ByteAlignmentTestParam> {
|
||||
protected:
|
||||
ByteAlignmentTest() : video_(NULL), decoder_(NULL), md5_file_(NULL) {}
|
||||
|
||||
virtual void SetUp() {
|
||||
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
|
||||
ASSERT_TRUE(video_ != NULL);
|
||||
video_->Init();
|
||||
video_->Begin();
|
||||
|
||||
const vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
||||
ASSERT_TRUE(decoder_ != NULL);
|
||||
|
||||
OpenMd5File(kVP9Md5File);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
if (md5_file_ != NULL) fclose(md5_file_);
|
||||
|
||||
delete decoder_;
|
||||
delete video_;
|
||||
}
|
||||
|
||||
void SetByteAlignment(int byte_alignment, vpx_codec_err_t expected_value) {
|
||||
decoder_->Control(VP9_SET_BYTE_ALIGNMENT, byte_alignment, expected_value);
|
||||
}
|
||||
|
||||
vpx_codec_err_t DecodeOneFrame(int byte_alignment_to_check) {
|
||||
const vpx_codec_err_t res =
|
||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||
CheckDecodedFrames(byte_alignment_to_check);
|
||||
if (res == VPX_CODEC_OK) video_->Next();
|
||||
return res;
|
||||
}
|
||||
|
||||
vpx_codec_err_t DecodeRemainingFrames(int byte_alignment_to_check) {
|
||||
for (; video_->cxdata() != NULL; video_->Next()) {
|
||||
const vpx_codec_err_t res =
|
||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||
if (res != VPX_CODEC_OK) return res;
|
||||
CheckDecodedFrames(byte_alignment_to_check);
|
||||
}
|
||||
return VPX_CODEC_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
// Check if |data| is aligned to |byte_alignment_to_check|.
|
||||
// |byte_alignment_to_check| must be a power of 2.
|
||||
void CheckByteAlignment(const uint8_t *data, int byte_alignment_to_check) {
|
||||
ASSERT_EQ(0u, reinterpret_cast<size_t>(data) % byte_alignment_to_check);
|
||||
}
|
||||
|
||||
// Iterate through the planes of the decoded frames and check for
|
||||
// alignment based off |byte_alignment_to_check|.
|
||||
void CheckDecodedFrames(int byte_alignment_to_check) {
|
||||
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
||||
const vpx_image_t *img;
|
||||
|
||||
// Get decompressed data
|
||||
while ((img = dec_iter.Next()) != NULL) {
|
||||
if (byte_alignment_to_check == kLegacyByteAlignment) {
|
||||
CheckByteAlignment(img->planes[0], kLegacyYPlaneByteAlignment);
|
||||
} else {
|
||||
for (int i = 0; i < kNumPlanesToCheck; ++i) {
|
||||
CheckByteAlignment(img->planes[i], byte_alignment_to_check);
|
||||
}
|
||||
}
|
||||
CheckMd5(*img);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(fgalligan): Move the MD5 testing code into another class.
|
||||
void OpenMd5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "MD5 file open failed. Filename: " << md5_file_name_;
|
||||
}
|
||||
|
||||
void CheckMd5(const vpx_image_t &img) {
|
||||
ASSERT_TRUE(md5_file_ != NULL);
|
||||
char expected_md5[33];
|
||||
char junk[128];
|
||||
|
||||
// Read correct md5 checksums.
|
||||
const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
|
||||
ASSERT_NE(EOF, res) << "Read md5 data failed";
|
||||
expected_md5[32] = '\0';
|
||||
|
||||
::libvpx_test::MD5 md5_res;
|
||||
md5_res.Add(&img);
|
||||
const char *const actual_md5 = md5_res.Get();
|
||||
|
||||
// Check md5 match.
|
||||
ASSERT_STREQ(expected_md5, actual_md5) << "MD5 checksums don't match";
|
||||
}
|
||||
|
||||
libvpx_test::WebMVideoSource *video_;
|
||||
libvpx_test::VP9Decoder *decoder_;
|
||||
FILE *md5_file_;
|
||||
};
|
||||
|
||||
TEST_F(ByteAlignmentTest, SwitchByteAlignment) {
|
||||
const int num_elements = 14;
|
||||
const int byte_alignments[] = { 0, 32, 64, 128, 256, 512, 1024,
|
||||
0, 1024, 32, 512, 64, 256, 128 };
|
||||
|
||||
for (int i = 0; i < num_elements; ++i) {
|
||||
SetByteAlignment(byte_alignments[i], VPX_CODEC_OK);
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame(byte_alignments[i]));
|
||||
}
|
||||
SetByteAlignment(byte_alignments[0], VPX_CODEC_OK);
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(byte_alignments[0]));
|
||||
}
|
||||
|
||||
TEST_P(ByteAlignmentTest, TestAlignment) {
|
||||
const ByteAlignmentTestParam t = GetParam();
|
||||
SetByteAlignment(t.byte_alignment, t.expected_value);
|
||||
if (t.decode_remaining) {
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(t.byte_alignment));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Alignments, ByteAlignmentTest,
|
||||
::testing::ValuesIn(kBaTestParams));
|
||||
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 VPX_TEST_CLEAR_SYSTEM_STATE_H_
|
||||
#define VPX_TEST_CLEAR_SYSTEM_STATE_H_
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "vpx_ports/system_state.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
// Reset system to a known state. This function should be used for all non-API
|
||||
// test cases.
|
||||
inline void ClearSystemState() { vpx_clear_system_state(); }
|
||||
|
||||
} // namespace libvpx_test
|
||||
#endif // VPX_TEST_CLEAR_SYSTEM_STATE_H_
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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 VPX_TEST_CODEC_FACTORY_H_
|
||||
#define VPX_TEST_CODEC_FACTORY_H_
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#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 {
|
||||
|
||||
const int kCodecFactoryParam = 0;
|
||||
|
||||
class CodecFactory {
|
||||
public:
|
||||
CodecFactory() {}
|
||||
|
||||
virtual ~CodecFactory() {}
|
||||
|
||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const = 0;
|
||||
|
||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||
const vpx_codec_flags_t flags) 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::tuple<const libvpx_test::CodecFactory *, T1> > {};
|
||||
|
||||
template <class T1, class T2>
|
||||
class CodecTestWith2Params
|
||||
: public ::testing::TestWithParam<
|
||||
std::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
class CodecTestWith3Params
|
||||
: public ::testing::TestWithParam<
|
||||
std::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
class CodecTestWith4Params
|
||||
: public ::testing::TestWithParam<
|
||||
std::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {};
|
||||
|
||||
/*
|
||||
* VP8 Codec Definitions
|
||||
*/
|
||||
#if CONFIG_VP8
|
||||
class VP8Decoder : public Decoder {
|
||||
public:
|
||||
explicit VP8Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {}
|
||||
|
||||
VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
||||
: Decoder(cfg, flag) {}
|
||||
|
||||
protected:
|
||||
virtual 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 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) const {
|
||||
return CreateDecoder(cfg, 0);
|
||||
}
|
||||
|
||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||
const vpx_codec_flags_t flags) const {
|
||||
#if CONFIG_VP8_DECODER
|
||||
return new VP8Decoder(cfg, flags);
|
||||
#else
|
||||
(void)cfg;
|
||||
(void)flags;
|
||||
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
|
||||
(void)cfg;
|
||||
(void)deadline;
|
||||
(void)init_flags;
|
||||
(void)stats;
|
||||
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
|
||||
(void)cfg;
|
||||
(void)usage;
|
||||
return VPX_CODEC_INCAPABLE;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
const libvpx_test::VP8CodecFactory kVP8;
|
||||
|
||||
#define VP8_INSTANTIATE_TEST_CASE(test, ...) \
|
||||
INSTANTIATE_TEST_CASE_P( \
|
||||
VP8, test, \
|
||||
::testing::Combine( \
|
||||
::testing::Values(static_cast<const libvpx_test::CodecFactory *>( \
|
||||
&libvpx_test::kVP8)), \
|
||||
__VA_ARGS__))
|
||||
#else
|
||||
#define VP8_INSTANTIATE_TEST_CASE(test, ...)
|
||||
#endif // CONFIG_VP8
|
||||
|
||||
/*
|
||||
* VP9 Codec Definitions
|
||||
*/
|
||||
#if CONFIG_VP9
|
||||
class VP9Decoder : public Decoder {
|
||||
public:
|
||||
explicit VP9Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {}
|
||||
|
||||
VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
||||
: Decoder(cfg, flag) {}
|
||||
|
||||
protected:
|
||||
virtual 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 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) const {
|
||||
return CreateDecoder(cfg, 0);
|
||||
}
|
||||
|
||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||
const vpx_codec_flags_t flags) const {
|
||||
#if CONFIG_VP9_DECODER
|
||||
return new VP9Decoder(cfg, flags);
|
||||
#else
|
||||
(void)cfg;
|
||||
(void)flags;
|
||||
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
|
||||
(void)cfg;
|
||||
(void)deadline;
|
||||
(void)init_flags;
|
||||
(void)stats;
|
||||
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
|
||||
(void)cfg;
|
||||
(void)usage;
|
||||
return VPX_CODEC_INCAPABLE;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
const libvpx_test::VP9CodecFactory kVP9;
|
||||
|
||||
#define VP9_INSTANTIATE_TEST_CASE(test, ...) \
|
||||
INSTANTIATE_TEST_CASE_P( \
|
||||
VP9, test, \
|
||||
::testing::Combine( \
|
||||
::testing::Values(static_cast<const libvpx_test::CodecFactory *>( \
|
||||
&libvpx_test::kVP9)), \
|
||||
__VA_ARGS__))
|
||||
#else
|
||||
#define VP9_INSTANTIATE_TEST_CASE(test, ...)
|
||||
#endif // CONFIG_VP9
|
||||
|
||||
} // namespace libvpx_test
|
||||
#endif // VPX_TEST_CODEC_FACTORY_H_
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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 "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::libvpx_test::ACMRandom;
|
||||
using ::libvpx_test::Buffer;
|
||||
|
||||
typedef void (*AvgPredFunc)(uint8_t *a, const uint8_t *b, int w, int h,
|
||||
const uint8_t *c, int c_stride);
|
||||
|
||||
uint8_t avg_with_rounding(uint8_t a, uint8_t b) { return (a + b + 1) >> 1; }
|
||||
|
||||
void reference_pred(const Buffer<uint8_t> &pred, const Buffer<uint8_t> &ref,
|
||||
int width, int height, Buffer<uint8_t> *avg) {
|
||||
ASSERT_TRUE(avg->TopLeftPixel() != NULL);
|
||||
ASSERT_TRUE(pred.TopLeftPixel() != NULL);
|
||||
ASSERT_TRUE(ref.TopLeftPixel() != NULL);
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
avg->TopLeftPixel()[y * avg->stride() + x] =
|
||||
avg_with_rounding(pred.TopLeftPixel()[y * pred.stride() + x],
|
||||
ref.TopLeftPixel()[y * ref.stride() + x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvgPredTest : public ::testing::TestWithParam<AvgPredFunc> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
avg_pred_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
AvgPredFunc avg_pred_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(AvgPredTest, SizeCombinations) {
|
||||
// This is called as part of the sub pixel variance. As such it must be one of
|
||||
// the variance block sizes.
|
||||
|
||||
for (int width_pow = 2; width_pow <= 6; ++width_pow) {
|
||||
for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
|
||||
++height_pow) {
|
||||
// Don't test 4x2 or 64x128
|
||||
if (height_pow == 1 || height_pow == 7) continue;
|
||||
|
||||
// The sse2 special-cases when ref width == stride, so make sure to test
|
||||
// it.
|
||||
for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
|
||||
const int width = 1 << width_pow;
|
||||
const int height = 1 << height_pow;
|
||||
// Only the reference buffer may have a stride not equal to width.
|
||||
Buffer<uint8_t> ref =
|
||||
Buffer<uint8_t>(width, height, ref_padding ? 8 : 0);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg_ref = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_ref.Init());
|
||||
Buffer<uint8_t> avg_chk = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_chk.Init());
|
||||
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
reference_pred(pred, ref, width, height, &avg_ref);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
avg_pred_func_(avg_chk.TopLeftPixel(), pred.TopLeftPixel(), width,
|
||||
height, ref.TopLeftPixel(), ref.stride()));
|
||||
|
||||
EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
|
||||
if (HasFailure()) {
|
||||
printf("Width: %d Height: %d\n", width, height);
|
||||
avg_chk.PrintDifference(avg_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AvgPredTest, CompareReferenceRandom) {
|
||||
const int width = 64;
|
||||
const int height = 32;
|
||||
Buffer<uint8_t> ref = Buffer<uint8_t>(width, height, 8);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg_ref = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_ref.Init());
|
||||
Buffer<uint8_t> avg_chk = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_chk.Init());
|
||||
|
||||
for (int i = 0; i < 500; ++i) {
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
reference_pred(pred, ref, width, height, &avg_ref);
|
||||
ASM_REGISTER_STATE_CHECK(avg_pred_func_(avg_chk.TopLeftPixel(),
|
||||
pred.TopLeftPixel(), width, height,
|
||||
ref.TopLeftPixel(), ref.stride()));
|
||||
EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
|
||||
if (HasFailure()) {
|
||||
printf("Width: %d Height: %d\n", width, height);
|
||||
avg_chk.PrintDifference(avg_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AvgPredTest, DISABLED_Speed) {
|
||||
for (int width_pow = 2; width_pow <= 6; ++width_pow) {
|
||||
for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
|
||||
++height_pow) {
|
||||
// Don't test 4x2 or 64x128
|
||||
if (height_pow == 1 || height_pow == 7) continue;
|
||||
|
||||
for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
|
||||
const int width = 1 << width_pow;
|
||||
const int height = 1 << height_pow;
|
||||
Buffer<uint8_t> ref =
|
||||
Buffer<uint8_t>(width, height, ref_padding ? 8 : 0);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg.Init());
|
||||
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < 10000000 / (width * height); ++i) {
|
||||
avg_pred_func_(avg.TopLeftPixel(), pred.TopLeftPixel(), width, height,
|
||||
ref.TopLeftPixel(), ref.stride());
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("Average Test (ref_padding: %d) %dx%d time: %5d us\n",
|
||||
ref_padding, width, height, elapsed_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(VSX, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_vsx));
|
||||
#endif // HAVE_VSX
|
||||
} // namespace
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 "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 ::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 ~ConfigTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
frame_count_in_ = 0;
|
||||
frame_count_out_ = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource * /*video*/) {
|
||||
++frame_count_in_;
|
||||
abort_ |= (frame_count_in_ >= frame_count_max_);
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {
|
||||
++frame_count_out_;
|
||||
}
|
||||
|
||||
unsigned int frame_count_in_;
|
||||
unsigned int frame_count_out_;
|
||||
unsigned int frame_count_max_;
|
||||
};
|
||||
|
||||
TEST_P(ConfigTest, LagIsDisabled) {
|
||||
frame_count_max_ = 2;
|
||||
cfg_.g_lag_in_frames = 15;
|
||||
|
||||
libvpx_test::DummyVideoSource video;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
EXPECT_EQ(frame_count_in_, frame_count_out_);
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(ConfigTest, ONE_PASS_TEST_MODES);
|
||||
} // namespace
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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 <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#if CONFIG_VP9_ENCODER
|
||||
#include "./vp9_rtcd.h"
|
||||
#endif
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx_dsp/ssim.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
extern "C" double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
|
||||
uint8_t *img2, int img2_pitch, int width,
|
||||
int height, Ssimv *sv2, Metrics *m,
|
||||
int do_inconsistency);
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
class ConsistencyTestBase : public ::testing::Test {
|
||||
public:
|
||||
ConsistencyTestBase(int width, int height) : width_(width), height_(height) {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
source_data_[0] = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
||||
reference_data_[0] = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
||||
source_data_[1] = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
||||
reference_data_[1] = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBufferSize));
|
||||
ssim_array_ = new Ssimv[kDataBufferSize / 16];
|
||||
}
|
||||
|
||||
static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); }
|
||||
static void TearDownTestCase() {
|
||||
vpx_free(source_data_[0]);
|
||||
source_data_[0] = NULL;
|
||||
vpx_free(reference_data_[0]);
|
||||
reference_data_[0] = NULL;
|
||||
vpx_free(source_data_[1]);
|
||||
source_data_[1] = NULL;
|
||||
vpx_free(reference_data_[1]);
|
||||
reference_data_[1] = NULL;
|
||||
|
||||
delete[] ssim_array_;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
// Handle frames up to 640x480
|
||||
static const int kDataAlignment = 16;
|
||||
static const int kDataBufferSize = 640 * 480;
|
||||
|
||||
virtual void SetUp() {
|
||||
source_stride_ = (width_ + 31) & ~31;
|
||||
reference_stride_ = width_ * 2;
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
void FillRandom(uint8_t *data, int stride, int width, int height) {
|
||||
for (int h = 0; h < height; ++h) {
|
||||
for (int w = 0; w < width; ++w) {
|
||||
data[h * stride + w] = rnd_.Rand8();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FillRandom(uint8_t *data, int stride) {
|
||||
FillRandom(data, stride, width_, height_);
|
||||
}
|
||||
|
||||
void Copy(uint8_t *reference, uint8_t *source) {
|
||||
memcpy(reference, source, kDataBufferSize);
|
||||
}
|
||||
|
||||
void Blur(uint8_t *data, int stride, int taps) {
|
||||
int sum = 0;
|
||||
int half_taps = taps / 2;
|
||||
for (int h = 0; h < height_; ++h) {
|
||||
for (int w = 0; w < taps; ++w) {
|
||||
sum += data[w + h * stride];
|
||||
}
|
||||
for (int w = taps; w < width_; ++w) {
|
||||
sum += data[w + h * stride] - data[w - taps + h * stride];
|
||||
data[w - half_taps + h * stride] = (sum + half_taps) / taps;
|
||||
}
|
||||
}
|
||||
for (int w = 0; w < width_; ++w) {
|
||||
for (int h = 0; h < taps; ++h) {
|
||||
sum += data[h + w * stride];
|
||||
}
|
||||
for (int h = taps; h < height_; ++h) {
|
||||
sum += data[w + h * stride] - data[(h - taps) * stride + w];
|
||||
data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
|
||||
}
|
||||
}
|
||||
}
|
||||
int width_, height_;
|
||||
static uint8_t *source_data_[2];
|
||||
int source_stride_;
|
||||
static uint8_t *reference_data_[2];
|
||||
int reference_stride_;
|
||||
static Ssimv *ssim_array_;
|
||||
Metrics metrics_;
|
||||
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
typedef std::tuple<int, int> ConsistencyParam;
|
||||
class ConsistencyVP9Test
|
||||
: public ConsistencyTestBase,
|
||||
public ::testing::WithParamInterface<ConsistencyParam> {
|
||||
public:
|
||||
ConsistencyVP9Test() : ConsistencyTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||
|
||||
protected:
|
||||
double CheckConsistency(int frame) {
|
||||
EXPECT_LT(frame, 2) << "Frame to check has to be less than 2.";
|
||||
return vpx_get_ssim_metrics(source_data_[frame], source_stride_,
|
||||
reference_data_[frame], reference_stride_,
|
||||
width_, height_, ssim_array_, &metrics_, 1);
|
||||
}
|
||||
};
|
||||
#endif // CONFIG_VP9_ENCODER
|
||||
|
||||
uint8_t *ConsistencyTestBase::source_data_[2] = { NULL, NULL };
|
||||
uint8_t *ConsistencyTestBase::reference_data_[2] = { NULL, NULL };
|
||||
Ssimv *ConsistencyTestBase::ssim_array_ = NULL;
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
|
||||
FillRandom(source_data_[0], source_stride_);
|
||||
Copy(source_data_[1], source_data_[0]);
|
||||
Copy(reference_data_[0], source_data_[0]);
|
||||
Blur(reference_data_[0], reference_stride_, 3);
|
||||
Copy(reference_data_[1], source_data_[0]);
|
||||
Blur(reference_data_[1], reference_stride_, 3);
|
||||
|
||||
double inconsistency = CheckConsistency(1);
|
||||
inconsistency = CheckConsistency(0);
|
||||
EXPECT_EQ(inconsistency, 0.0)
|
||||
<< "Should have 0 inconsistency if they are exactly the same.";
|
||||
|
||||
// If sources are not consistent reference frames inconsistency should
|
||||
// be less than if the source is consistent.
|
||||
FillRandom(source_data_[0], source_stride_);
|
||||
FillRandom(source_data_[1], source_stride_);
|
||||
FillRandom(reference_data_[0], reference_stride_);
|
||||
FillRandom(reference_data_[1], reference_stride_);
|
||||
CheckConsistency(0);
|
||||
inconsistency = CheckConsistency(1);
|
||||
|
||||
Copy(source_data_[1], source_data_[0]);
|
||||
CheckConsistency(0);
|
||||
double inconsistency2 = CheckConsistency(1);
|
||||
EXPECT_LT(inconsistency, inconsistency2)
|
||||
<< "Should have less inconsistency if source itself is inconsistent.";
|
||||
|
||||
// Less of a blur should be less inconsistent than more blur coming off a
|
||||
// a frame with no blur.
|
||||
ClearSsim();
|
||||
FillRandom(source_data_[0], source_stride_);
|
||||
Copy(source_data_[1], source_data_[0]);
|
||||
Copy(reference_data_[0], source_data_[0]);
|
||||
Copy(reference_data_[1], source_data_[0]);
|
||||
Blur(reference_data_[1], reference_stride_, 4);
|
||||
CheckConsistency(0);
|
||||
inconsistency = CheckConsistency(1);
|
||||
ClearSsim();
|
||||
Copy(reference_data_[1], source_data_[0]);
|
||||
Blur(reference_data_[1], reference_stride_, 8);
|
||||
CheckConsistency(0);
|
||||
inconsistency2 = CheckConsistency(1);
|
||||
|
||||
EXPECT_LT(inconsistency, inconsistency2)
|
||||
<< "Stronger Blur should produce more inconsistency.";
|
||||
}
|
||||
#endif // CONFIG_VP9_ENCODER
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// C functions
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
const ConsistencyParam c_vp9_tests[] = { make_tuple(320, 240),
|
||||
make_tuple(318, 242),
|
||||
make_tuple(318, 238) };
|
||||
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
|
||||
::testing::ValuesIn(c_vp9_tests));
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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 "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"
|
||||
#include "test/y4m_video_source.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const int kMaxPSNR = 100;
|
||||
|
||||
class CpuSpeedTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
CpuSpeedTest()
|
||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
||||
set_cpu_used_(GET_PARAM(2)), min_psnr_(kMaxPSNR),
|
||||
tune_content_(VP9E_CONTENT_DEFAULT) {}
|
||||
virtual ~CpuSpeedTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
cfg_.g_lag_in_frames = 25;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
} else {
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) { min_psnr_ = kMaxPSNR; }
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
if (pkt->data.psnr.psnr[0] < min_psnr_) min_psnr_ = pkt->data.psnr.psnr[0];
|
||||
}
|
||||
|
||||
::libvpx_test::TestMode encoding_mode_;
|
||||
int set_cpu_used_;
|
||||
double min_psnr_;
|
||||
int tune_content_;
|
||||
};
|
||||
|
||||
TEST_P(CpuSpeedTest, TestQ0) {
|
||||
// Validate that this non multiple of 64 wide clip encodes and decodes
|
||||
// without a mismatch when passing in a very low max q. This pushes
|
||||
// the encoder to producing lots of big partitions which will likely
|
||||
// extend into the border and test the border condition.
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_target_bitrate = 400;
|
||||
cfg_.rc_max_quantizer = 0;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
20);
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
EXPECT_GE(min_psnr_, kMaxPSNR);
|
||||
}
|
||||
|
||||
TEST_P(CpuSpeedTest, TestScreencastQ0) {
|
||||
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25);
|
||||
cfg_.g_timebase = video.timebase();
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_target_bitrate = 400;
|
||||
cfg_.rc_max_quantizer = 0;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
EXPECT_GE(min_psnr_, kMaxPSNR);
|
||||
}
|
||||
|
||||
TEST_P(CpuSpeedTest, TestTuneScreen) {
|
||||
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25);
|
||||
cfg_.g_timebase = video.timebase();
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
||||
cfg_.rc_target_bitrate = 2000;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
tune_content_ = VP9E_CONTENT_SCREEN;
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
TEST_P(CpuSpeedTest, TestEncodeHighBitrate) {
|
||||
// Validate that this non multiple of 64 wide clip encodes and decodes
|
||||
// without a mismatch when passing in a very low max q. This pushes
|
||||
// the encoder to producing lots of big partitions which will likely
|
||||
// extend into the border and test the border condition.
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_target_bitrate = 12000;
|
||||
cfg_.rc_max_quantizer = 10;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
20);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
TEST_P(CpuSpeedTest, TestLowBitrate) {
|
||||
// Validate that this clip encodes and decodes without a mismatch
|
||||
// when passing in a very high min q. This pushes the encoder to producing
|
||||
// lots of small partitions which might will test the other condition.
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
cfg_.rc_min_quantizer = 40;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
20);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(CpuSpeedTest,
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(0, 10));
|
||||
} // namespace
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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 <cmath>
|
||||
#include <map>
|
||||
#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 {
|
||||
|
||||
// CQ level range: [kCQLevelMin, kCQLevelMax).
|
||||
const int kCQLevelMin = 4;
|
||||
const int kCQLevelMax = 63;
|
||||
const int kCQLevelStep = 8;
|
||||
const unsigned int kCQTargetBitrate = 2000;
|
||||
|
||||
class CQTest : public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<int> {
|
||||
public:
|
||||
// maps the cqlevel to the bitrate produced.
|
||||
typedef std::map<int, uint32_t> BitrateMap;
|
||||
|
||||
static void SetUpTestCase() { bitrates_.clear(); }
|
||||
|
||||
static void TearDownTestCase() {
|
||||
ASSERT_TRUE(!HasFailure())
|
||||
<< "skipping bitrate validation due to earlier failure.";
|
||||
uint32_t prev_actual_bitrate = kCQTargetBitrate;
|
||||
for (BitrateMap::const_iterator iter = bitrates_.begin();
|
||||
iter != bitrates_.end(); ++iter) {
|
||||
const uint32_t cq_actual_bitrate = iter->second;
|
||||
EXPECT_LE(cq_actual_bitrate, prev_actual_bitrate)
|
||||
<< "cq_level: " << iter->first
|
||||
<< ", bitrate should decrease with increase in CQ level.";
|
||||
prev_actual_bitrate = cq_actual_bitrate;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
CQTest() : EncoderTest(GET_PARAM(0)), cq_level_(GET_PARAM(1)) {
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
}
|
||||
|
||||
virtual ~CQTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(libvpx_test::kTwoPassGood);
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
file_size_ = 0;
|
||||
psnr_ = 0.0;
|
||||
n_frames_ = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
if (cfg_.rc_end_usage == VPX_CQ) {
|
||||
encoder->Control(VP8E_SET_CQ_LEVEL, cq_level_);
|
||||
}
|
||||
encoder->Control(VP8E_SET_CPUUSED, 3);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
psnr_ += pow(10.0, pkt->data.psnr.psnr[0] / 10.0);
|
||||
n_frames_++;
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
file_size_ += pkt->data.frame.sz;
|
||||
}
|
||||
|
||||
double GetLinearPSNROverBitrate() const {
|
||||
double avg_psnr = log10(psnr_ / n_frames_) * 10.0;
|
||||
return pow(10.0, avg_psnr / 10.0) / file_size_;
|
||||
}
|
||||
|
||||
int cq_level() const { return cq_level_; }
|
||||
size_t file_size() const { return file_size_; }
|
||||
int n_frames() const { return n_frames_; }
|
||||
|
||||
static BitrateMap bitrates_;
|
||||
|
||||
private:
|
||||
int cq_level_;
|
||||
size_t file_size_;
|
||||
double psnr_;
|
||||
int n_frames_;
|
||||
};
|
||||
|
||||
CQTest::BitrateMap CQTest::bitrates_;
|
||||
|
||||
TEST_P(CQTest, LinearPSNRIsHigherForCQLevel) {
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = kCQTargetBitrate;
|
||||
cfg_.g_lag_in_frames = 25;
|
||||
|
||||
cfg_.rc_end_usage = VPX_CQ;
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
timebase.den, timebase.num, 0, 30);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const double cq_psnr_lin = GetLinearPSNROverBitrate();
|
||||
const unsigned int cq_actual_bitrate =
|
||||
static_cast<unsigned int>(file_size()) * 8 * 30 / (n_frames() * 1000);
|
||||
EXPECT_LE(cq_actual_bitrate, kCQTargetBitrate);
|
||||
bitrates_[cq_level()] = cq_actual_bitrate;
|
||||
|
||||
// try targeting the approximate same bitrate with VBR mode
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_target_bitrate = cq_actual_bitrate;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const double vbr_psnr_lin = GetLinearPSNROverBitrate();
|
||||
EXPECT_GE(cq_psnr_lin, vbr_psnr_lin);
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(CQTest, ::testing::Range(kCQLevelMin, kCQLevelMax,
|
||||
kCQLevelStep));
|
||||
} // namespace
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2016 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.
|
||||
##
|
||||
## This file tests the libvpx cx_set_ref example. To add new tests to this
|
||||
## file, do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to cx_set_ref_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: $YUV_RAW_INPUT is required.
|
||||
cx_set_ref_verify_environment() {
|
||||
if [ ! -e "${YUV_RAW_INPUT}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs cx_set_ref and updates the reference frame before encoding frame 90.
|
||||
# $1 is the codec name.
|
||||
vpx_set_ref() {
|
||||
local codec="$1"
|
||||
local encoder="${LIBVPX_BIN_PATH}/${codec}cx_set_ref${VPX_TEST_EXE_SUFFIX}"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/${codec}cx_set_ref_${codec}.ivf"
|
||||
local ref_frame_num=90
|
||||
|
||||
if [ ! -x "${encoder}" ]; then
|
||||
elog "${encoder} does not exist or is not executable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
|
||||
"${ref_frame_num}" ${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
}
|
||||
|
||||
cx_set_ref_vp8() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_set_ref vp8 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
cx_set_ref_vp9() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_set_ref vp9 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
cx_set_ref_tests="cx_set_ref_vp8 cx_set_ref_vp9"
|
||||
|
||||
run_tests cx_set_ref_verify_environment "${cx_set_ref_tests}"
|
||||
@@ -0,0 +1,868 @@
|
||||
/*
|
||||
* 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 <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vp9/common/vp9_scan.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/msvc.h" // for round()
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
|
||||
const int kNumCoeffs = 256;
|
||||
const double C1 = 0.995184726672197;
|
||||
const double C2 = 0.98078528040323;
|
||||
const double C3 = 0.956940335732209;
|
||||
const double C4 = 0.923879532511287;
|
||||
const double C5 = 0.881921264348355;
|
||||
const double C6 = 0.831469612302545;
|
||||
const double C7 = 0.773010453362737;
|
||||
const double C8 = 0.707106781186548;
|
||||
const double C9 = 0.634393284163646;
|
||||
const double C10 = 0.555570233019602;
|
||||
const double C11 = 0.471396736825998;
|
||||
const double C12 = 0.38268343236509;
|
||||
const double C13 = 0.290284677254462;
|
||||
const double C14 = 0.195090322016128;
|
||||
const double C15 = 0.098017140329561;
|
||||
|
||||
void butterfly_16x16_dct_1d(double input[16], double output[16]) {
|
||||
double step[16];
|
||||
double intermediate[16];
|
||||
double temp1, temp2;
|
||||
|
||||
// step 1
|
||||
step[0] = input[0] + input[15];
|
||||
step[1] = input[1] + input[14];
|
||||
step[2] = input[2] + input[13];
|
||||
step[3] = input[3] + input[12];
|
||||
step[4] = input[4] + input[11];
|
||||
step[5] = input[5] + input[10];
|
||||
step[6] = input[6] + input[9];
|
||||
step[7] = input[7] + input[8];
|
||||
step[8] = input[7] - input[8];
|
||||
step[9] = input[6] - input[9];
|
||||
step[10] = input[5] - input[10];
|
||||
step[11] = input[4] - input[11];
|
||||
step[12] = input[3] - input[12];
|
||||
step[13] = input[2] - input[13];
|
||||
step[14] = input[1] - input[14];
|
||||
step[15] = input[0] - input[15];
|
||||
|
||||
// step 2
|
||||
output[0] = step[0] + step[7];
|
||||
output[1] = step[1] + step[6];
|
||||
output[2] = step[2] + step[5];
|
||||
output[3] = step[3] + step[4];
|
||||
output[4] = step[3] - step[4];
|
||||
output[5] = step[2] - step[5];
|
||||
output[6] = step[1] - step[6];
|
||||
output[7] = step[0] - step[7];
|
||||
|
||||
temp1 = step[8] * C7;
|
||||
temp2 = step[15] * C9;
|
||||
output[8] = temp1 + temp2;
|
||||
|
||||
temp1 = step[9] * C11;
|
||||
temp2 = step[14] * C5;
|
||||
output[9] = temp1 - temp2;
|
||||
|
||||
temp1 = step[10] * C3;
|
||||
temp2 = step[13] * C13;
|
||||
output[10] = temp1 + temp2;
|
||||
|
||||
temp1 = step[11] * C15;
|
||||
temp2 = step[12] * C1;
|
||||
output[11] = temp1 - temp2;
|
||||
|
||||
temp1 = step[11] * C1;
|
||||
temp2 = step[12] * C15;
|
||||
output[12] = temp2 + temp1;
|
||||
|
||||
temp1 = step[10] * C13;
|
||||
temp2 = step[13] * C3;
|
||||
output[13] = temp2 - temp1;
|
||||
|
||||
temp1 = step[9] * C5;
|
||||
temp2 = step[14] * C11;
|
||||
output[14] = temp2 + temp1;
|
||||
|
||||
temp1 = step[8] * C9;
|
||||
temp2 = step[15] * C7;
|
||||
output[15] = temp2 - temp1;
|
||||
|
||||
// step 3
|
||||
step[0] = output[0] + output[3];
|
||||
step[1] = output[1] + output[2];
|
||||
step[2] = output[1] - output[2];
|
||||
step[3] = output[0] - output[3];
|
||||
|
||||
temp1 = output[4] * C14;
|
||||
temp2 = output[7] * C2;
|
||||
step[4] = temp1 + temp2;
|
||||
|
||||
temp1 = output[5] * C10;
|
||||
temp2 = output[6] * C6;
|
||||
step[5] = temp1 + temp2;
|
||||
|
||||
temp1 = output[5] * C6;
|
||||
temp2 = output[6] * C10;
|
||||
step[6] = temp2 - temp1;
|
||||
|
||||
temp1 = output[4] * C2;
|
||||
temp2 = output[7] * C14;
|
||||
step[7] = temp2 - temp1;
|
||||
|
||||
step[8] = output[8] + output[11];
|
||||
step[9] = output[9] + output[10];
|
||||
step[10] = output[9] - output[10];
|
||||
step[11] = output[8] - output[11];
|
||||
|
||||
step[12] = output[12] + output[15];
|
||||
step[13] = output[13] + output[14];
|
||||
step[14] = output[13] - output[14];
|
||||
step[15] = output[12] - output[15];
|
||||
|
||||
// step 4
|
||||
output[0] = (step[0] + step[1]);
|
||||
output[8] = (step[0] - step[1]);
|
||||
|
||||
temp1 = step[2] * C12;
|
||||
temp2 = step[3] * C4;
|
||||
temp1 = temp1 + temp2;
|
||||
output[4] = 2 * (temp1 * C8);
|
||||
|
||||
temp1 = step[2] * C4;
|
||||
temp2 = step[3] * C12;
|
||||
temp1 = temp2 - temp1;
|
||||
output[12] = 2 * (temp1 * C8);
|
||||
|
||||
output[2] = 2 * ((step[4] + step[5]) * C8);
|
||||
output[14] = 2 * ((step[7] - step[6]) * C8);
|
||||
|
||||
temp1 = step[4] - step[5];
|
||||
temp2 = step[6] + step[7];
|
||||
output[6] = (temp1 + temp2);
|
||||
output[10] = (temp1 - temp2);
|
||||
|
||||
intermediate[8] = step[8] + step[14];
|
||||
intermediate[9] = step[9] + step[15];
|
||||
|
||||
temp1 = intermediate[8] * C12;
|
||||
temp2 = intermediate[9] * C4;
|
||||
temp1 = temp1 - temp2;
|
||||
output[3] = 2 * (temp1 * C8);
|
||||
|
||||
temp1 = intermediate[8] * C4;
|
||||
temp2 = intermediate[9] * C12;
|
||||
temp1 = temp2 + temp1;
|
||||
output[13] = 2 * (temp1 * C8);
|
||||
|
||||
output[9] = 2 * ((step[10] + step[11]) * C8);
|
||||
|
||||
intermediate[11] = step[10] - step[11];
|
||||
intermediate[12] = step[12] + step[13];
|
||||
intermediate[13] = step[12] - step[13];
|
||||
intermediate[14] = step[8] - step[14];
|
||||
intermediate[15] = step[9] - step[15];
|
||||
|
||||
output[15] = (intermediate[11] + intermediate[12]);
|
||||
output[1] = -(intermediate[11] - intermediate[12]);
|
||||
|
||||
output[7] = 2 * (intermediate[13] * C8);
|
||||
|
||||
temp1 = intermediate[14] * C12;
|
||||
temp2 = intermediate[15] * C4;
|
||||
temp1 = temp1 - temp2;
|
||||
output[11] = -2 * (temp1 * C8);
|
||||
|
||||
temp1 = intermediate[14] * C4;
|
||||
temp2 = intermediate[15] * C12;
|
||||
temp1 = temp2 + temp1;
|
||||
output[5] = 2 * (temp1 * C8);
|
||||
}
|
||||
|
||||
void reference_16x16_dct_2d(int16_t input[256], double output[256]) {
|
||||
// First transform columns
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
double temp_in[16], temp_out[16];
|
||||
for (int j = 0; j < 16; ++j) temp_in[j] = input[j * 16 + i];
|
||||
butterfly_16x16_dct_1d(temp_in, temp_out);
|
||||
for (int j = 0; j < 16; ++j) output[j * 16 + i] = temp_out[j];
|
||||
}
|
||||
// Then transform rows
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
double temp_in[16], temp_out[16];
|
||||
for (int j = 0; j < 16; ++j) temp_in[j] = output[j + i * 16];
|
||||
butterfly_16x16_dct_1d(temp_in, temp_out);
|
||||
// Scale by some magic number
|
||||
for (int j = 0; j < 16; ++j) output[j + i * 16] = temp_out[j] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
||||
int tx_type);
|
||||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type);
|
||||
|
||||
typedef std::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct16x16Param;
|
||||
typedef std::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param;
|
||||
typedef std::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct16x16Param;
|
||||
|
||||
void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
vpx_fdct16x16_c(in, out, stride);
|
||||
}
|
||||
|
||||
void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
||||
int /*tx_type*/) {
|
||||
vpx_idct16x16_256_add_c(in, dest, stride);
|
||||
}
|
||||
|
||||
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||
vp9_fht16x16_c(in, out, stride, tx_type);
|
||||
}
|
||||
|
||||
void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
||||
int tx_type) {
|
||||
vp9_iht16x16_256_add_c(in, dest, stride, tx_type);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
idct16x16_10(in, out, stride);
|
||||
}
|
||||
|
||||
void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
idct16x16_12(in, out, stride);
|
||||
}
|
||||
|
||||
void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
||||
}
|
||||
|
||||
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
#endif // HAVE_SSE2
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
class Trans16x16TestBase {
|
||||
public:
|
||||
virtual ~Trans16x16TestBase() {}
|
||||
|
||||
protected:
|
||||
virtual void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) = 0;
|
||||
|
||||
virtual void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) = 0;
|
||||
|
||||
void RunAccuracyCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
uint32_t max_error = 0;
|
||||
int64_t total_error = 0;
|
||||
const int count_test_block = 10000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
test_input_block[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
test_input_block[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int32_t diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const int32_t diff = dst[j] - src[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_GE(1u << 2 * (bit_depth_ - 8), max_error)
|
||||
<< "Error: 16x16 FHT/IHT has an individual round trip error > 1";
|
||||
|
||||
EXPECT_GE(count_test_block << 2 * (bit_depth_ - 8), total_error)
|
||||
<< "Error: 16x16 FHT/IHT has average round trip error > 1 per block";
|
||||
}
|
||||
|
||||
void RunCoeffCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
for (int j = 0; j < kNumCoeffs; ++j)
|
||||
EXPECT_EQ(output_block[j], output_ref_block[j]);
|
||||
}
|
||||
}
|
||||
|
||||
void RunMemCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||
}
|
||||
if (i == 0) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||
} else if (i == 1) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(input_extreme_block, output_block, pitch_));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
EXPECT_EQ(output_block[j], output_ref_block[j]);
|
||||
EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j]))
|
||||
<< "Error: 16x16 FDCT has coefficient larger than 4*DCT_MAX_VALUE";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunQuantCheck(int dc_thred, int ac_thred) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 100000;
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||
}
|
||||
if (i == 0) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||
}
|
||||
if (i == 1) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||
|
||||
// clear reconstructed pixel buffers
|
||||
memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
|
||||
memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
|
||||
memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
|
||||
#endif
|
||||
|
||||
// quantization with maximum allowed step sizes
|
||||
output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred;
|
||||
for (int j = 1; j < kNumCoeffs; ++j) {
|
||||
output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred;
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
inv_txfm_ref(output_ref_block, CAST_TO_BYTEPTR(ref16), pitch_,
|
||||
tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(output_ref_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref[j], dst[j]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref16[j], dst16[j]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunInvAccuracyCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
double out_r[kNumCoeffs];
|
||||
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
in[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
in[j] = src16[j] - dst16[j];
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
}
|
||||
|
||||
reference_16x16_dct_2d(in, out_r);
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||
}
|
||||
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), 16));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const uint32_t diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const uint32_t diff = dst[j] - src[j];
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(1u, error)
|
||||
<< "Error: 16x16 IDCT has error " << error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CompareInvReference(IdctFunc ref_txfm, int thresh) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 10000;
|
||||
const int eob = 10;
|
||||
const int16_t *scan = vp9_default_scan_orders[TX_16X16].scan;
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (j < eob) {
|
||||
// Random values less than the threshold, either positive or negative
|
||||
coeff[scan[j]] = rnd(thresh) * (1 - 2 * (i % 2));
|
||||
} else {
|
||||
coeff[scan[j]] = 0;
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
dst[j] = 0;
|
||||
ref[j] = 0;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
dst16[j] = 0;
|
||||
ref16[j] = 0;
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ref_txfm(coeff, ref, pitch_);
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
} else {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const uint32_t diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
||||
#else
|
||||
const uint32_t diff = dst[j] - ref[j];
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_EQ(0u, error) << "Error: 16x16 IDCT Comparison has error "
|
||||
<< error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int pitch_;
|
||||
int tx_type_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
FhtFunc fwd_txfm_ref;
|
||||
IhtFunc inv_txfm_ref;
|
||||
};
|
||||
|
||||
class Trans16x16DCT : public Trans16x16TestBase,
|
||||
public ::testing::TestWithParam<Dct16x16Param> {
|
||||
public:
|
||||
virtual ~Trans16x16DCT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
pitch_ = 16;
|
||||
fwd_txfm_ref = fdct16x16_ref;
|
||||
inv_txfm_ref = idct16x16_ref;
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
switch (bit_depth_) {
|
||||
case VPX_BITS_10: inv_txfm_ref = idct16x16_10_ref; break;
|
||||
case VPX_BITS_12: inv_txfm_ref = idct16x16_12_ref; break;
|
||||
default: inv_txfm_ref = idct16x16_ref; break;
|
||||
}
|
||||
#else
|
||||
inv_txfm_ref = idct16x16_ref;
|
||||
#endif
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride);
|
||||
}
|
||||
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride);
|
||||
}
|
||||
|
||||
FdctFunc fwd_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(Trans16x16DCT, AccuracyCheck) { RunAccuracyCheck(); }
|
||||
|
||||
TEST_P(Trans16x16DCT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(Trans16x16DCT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(Trans16x16DCT, QuantCheck) {
|
||||
// Use maximally allowed quantization step sizes for DC and AC
|
||||
// coefficients respectively.
|
||||
RunQuantCheck(1336, 1828);
|
||||
}
|
||||
|
||||
TEST_P(Trans16x16DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
|
||||
|
||||
class Trans16x16HT : public Trans16x16TestBase,
|
||||
public ::testing::TestWithParam<Ht16x16Param> {
|
||||
public:
|
||||
virtual ~Trans16x16HT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
pitch_ = 16;
|
||||
fwd_txfm_ref = fht16x16_ref;
|
||||
inv_txfm_ref = iht16x16_ref;
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
switch (bit_depth_) {
|
||||
case VPX_BITS_10: inv_txfm_ref = iht16x16_10; break;
|
||||
case VPX_BITS_12: inv_txfm_ref = iht16x16_12; break;
|
||||
default: inv_txfm_ref = iht16x16_ref; break;
|
||||
}
|
||||
#else
|
||||
inv_txfm_ref = iht16x16_ref;
|
||||
#endif
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride, tx_type_);
|
||||
}
|
||||
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride, tx_type_);
|
||||
}
|
||||
|
||||
FhtFunc fwd_txfm_;
|
||||
IhtFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(Trans16x16HT, AccuracyCheck) { RunAccuracyCheck(); }
|
||||
|
||||
TEST_P(Trans16x16HT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(Trans16x16HT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(Trans16x16HT, QuantCheck) {
|
||||
// The encoder skips any non-DC intra prediction modes,
|
||||
// when the quantization step size goes beyond 988.
|
||||
RunQuantCheck(429, 729);
|
||||
}
|
||||
|
||||
class InvTrans16x16DCT : public Trans16x16TestBase,
|
||||
public ::testing::TestWithParam<Idct16x16Param> {
|
||||
public:
|
||||
virtual ~InvTrans16x16DCT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
ref_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
thresh_ = GET_PARAM(2);
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
pitch_ = 16;
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(int16_t * /*in*/, tran_low_t * /*out*/, int /*stride*/) {}
|
||||
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride);
|
||||
}
|
||||
|
||||
IdctFunc ref_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
int thresh_;
|
||||
};
|
||||
|
||||
TEST_P(InvTrans16x16DCT, CompareReference) {
|
||||
CompareInvReference(ref_txfm_, thresh_);
|
||||
}
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans16x16DCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(C, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_c,
|
||||
&vpx_idct16x16_256_add_c,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans16x16HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 1, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 2, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 3, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 1, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 2, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 3, VPX_BITS_12),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans16x16HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_neon,
|
||||
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_sse2,
|
||||
&vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans16x16HT,
|
||||
::testing::Values(make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||
0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||
1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||
2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||
3, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans16x16DCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_10_sse2, 0,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_12_sse2, 0,
|
||||
VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_c, 0,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans16x16HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 3,
|
||||
VPX_BITS_8)));
|
||||
// Optimizations take effect at a threshold of 3155, so we use a value close to
|
||||
// that to test both branches.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, InvTrans16x16DCT,
|
||||
::testing::Values(make_tuple(&idct16x16_10_add_10_c,
|
||||
&idct16x16_10_add_10_sse2, 3167, VPX_BITS_10),
|
||||
make_tuple(&idct16x16_10, &idct16x16_256_add_10_sse2,
|
||||
3167, VPX_BITS_10),
|
||||
make_tuple(&idct16x16_10_add_12_c,
|
||||
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
||||
make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
|
||||
3167, VPX_BITS_12)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(MSA, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_msa,
|
||||
&vpx_idct16x16_256_add_msa,
|
||||
0, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, Trans16x16HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(VSX, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_c,
|
||||
&vpx_idct16x16_256_add_vsx,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
* 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 <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/msvc.h" // for round()
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
|
||||
const int kNumCoeffs = 1024;
|
||||
const double kPi = 3.141592653589793238462643383279502884;
|
||||
void reference_32x32_dct_1d(const double in[32], double out[32]) {
|
||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||
for (int k = 0; k < 32; k++) {
|
||||
out[k] = 0.0;
|
||||
for (int n = 0; n < 32; n++) {
|
||||
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0);
|
||||
}
|
||||
if (k == 0) out[k] = out[k] * kInvSqrt2;
|
||||
}
|
||||
}
|
||||
|
||||
void reference_32x32_dct_2d(const int16_t input[kNumCoeffs],
|
||||
double output[kNumCoeffs]) {
|
||||
// First transform columns
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
double temp_in[32], temp_out[32];
|
||||
for (int j = 0; j < 32; ++j) temp_in[j] = input[j * 32 + i];
|
||||
reference_32x32_dct_1d(temp_in, temp_out);
|
||||
for (int j = 0; j < 32; ++j) output[j * 32 + i] = temp_out[j];
|
||||
}
|
||||
// Then transform rows
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
double temp_in[32], temp_out[32];
|
||||
for (int j = 0; j < 32; ++j) temp_in[j] = output[j + i * 32];
|
||||
reference_32x32_dct_1d(temp_in, temp_out);
|
||||
// Scale by some magic number
|
||||
for (int j = 0; j < 32; ++j) output[j + i * 32] = temp_out[j] / 4;
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
|
||||
typedef std::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||
Trans32x32Param;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
class Trans32x32Test : public AbstractBench,
|
||||
public ::testing::TestWithParam<Trans32x32Param> {
|
||||
public:
|
||||
virtual ~Trans32x32Test() {}
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
version_ = GET_PARAM(2); // 0: high precision forward transform
|
||||
// 1: low precision version for rd loop
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
int version_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
FwdTxfmFunc fwd_txfm_;
|
||||
InvTxfmFunc inv_txfm_;
|
||||
|
||||
int16_t *bench_in_;
|
||||
tran_low_t *bench_out_;
|
||||
virtual void Run();
|
||||
};
|
||||
|
||||
void Trans32x32Test::Run() { fwd_txfm_(bench_in_, bench_out_, 32); }
|
||||
|
||||
TEST_P(Trans32x32Test, AccuracyCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
uint32_t max_error = 0;
|
||||
int64_t total_error = 0;
|
||||
const int count_test_block = 10000;
|
||||
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
test_input_block[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
test_input_block[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32));
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
inv_txfm_(test_temp_block, CAST_TO_BYTEPTR(dst16), 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int32_t diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const int32_t diff = dst[j] - src[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
}
|
||||
}
|
||||
|
||||
if (version_ == 1) {
|
||||
max_error /= 2;
|
||||
total_error /= 45;
|
||||
}
|
||||
|
||||
EXPECT_GE(1u << 2 * (bit_depth_ - 8), max_error)
|
||||
<< "Error: 32x32 FDCT/IDCT has an individual round-trip error > 1";
|
||||
|
||||
EXPECT_GE(count_test_block << 2 * (bit_depth_ - 8), total_error)
|
||||
<< "Error: 32x32 FDCT/IDCT has average round-trip error > 1 per block";
|
||||
}
|
||||
|
||||
TEST_P(Trans32x32Test, CoeffCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
|
||||
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||
}
|
||||
|
||||
const int stride = 32;
|
||||
vpx_fdct32x32_c(input_block, output_ref_block, stride);
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride));
|
||||
|
||||
if (version_ == 0) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j)
|
||||
EXPECT_EQ(output_block[j], output_ref_block[j])
|
||||
<< "Error: 32x32 FDCT versions have mismatched coefficients";
|
||||
} else {
|
||||
for (int j = 0; j < kNumCoeffs; ++j)
|
||||
EXPECT_GE(6, abs(output_block[j] - output_ref_block[j]))
|
||||
<< "Error: 32x32 FDCT rd has mismatched coefficients";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Trans32x32Test, MemCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 2000;
|
||||
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
|
||||
}
|
||||
if (i == 0) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||
} else if (i == 1) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||
}
|
||||
|
||||
const int stride = 32;
|
||||
vpx_fdct32x32_c(input_extreme_block, output_ref_block, stride);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
fwd_txfm_(input_extreme_block, output_block, stride));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (version_ == 0) {
|
||||
EXPECT_EQ(output_block[j], output_ref_block[j])
|
||||
<< "Error: 32x32 FDCT versions have mismatched coefficients";
|
||||
} else {
|
||||
EXPECT_GE(6, abs(output_block[j] - output_ref_block[j]))
|
||||
<< "Error: 32x32 FDCT rd has mismatched coefficients";
|
||||
}
|
||||
EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_ref_block[j]))
|
||||
<< "Error: 32x32 FDCT C has coefficient larger than 4*DCT_MAX_VALUE";
|
||||
EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j]))
|
||||
<< "Error: 32x32 FDCT has coefficient larger than "
|
||||
<< "4*DCT_MAX_VALUE";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Trans32x32Test, DISABLED_Speed) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
bench_in_ = input_extreme_block;
|
||||
bench_out_ = output_block;
|
||||
|
||||
RunNTimes(INT16_MAX);
|
||||
PrintMedian("32x32");
|
||||
}
|
||||
|
||||
TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
double out_r[kNumCoeffs];
|
||||
|
||||
// Initialize a test block with input range [-255, 255]
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
in[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
in[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
reference_32x32_dct_2d(in, out_r);
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CAST_TO_BYTEPTR(dst16), 32));
|
||||
#endif
|
||||
}
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const int diff = dst[j] - src[j];
|
||||
#endif
|
||||
const int error = diff * diff;
|
||||
EXPECT_GE(1, error) << "Error: 32x32 IDCT has error " << error
|
||||
<< " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans32x32Test,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_10, 1, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_12, 1, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, 1,
|
||||
VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c,
|
||||
1, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_neon,
|
||||
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_neon,
|
||||
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_sse2,
|
||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_sse2,
|
||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans32x32Test,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct32x32_rd_sse2, &idct32x32_10, 1,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct32x32_rd_sse2, &idct32x32_12, 1,
|
||||
VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct32x32_sse2, &vpx_idct32x32_1024_add_c, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_avx2,
|
||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_avx2,
|
||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_msa,
|
||||
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_msa,
|
||||
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VSX, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_vsx,
|
||||
0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_vsx,
|
||||
&vpx_idct32x32_1024_add_vsx, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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 <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_dsp/vpx_dsp_common.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
using std::make_tuple;
|
||||
using std::tuple;
|
||||
|
||||
namespace {
|
||||
typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
|
||||
typedef tuple<PartialFdctFunc, int /* size */, vpx_bit_depth_t>
|
||||
PartialFdctParam;
|
||||
|
||||
tran_low_t partial_fdct_ref(const Buffer<int16_t> &in, int size) {
|
||||
int64_t sum = 0;
|
||||
if (in.TopLeftPixel() != NULL) {
|
||||
for (int y = 0; y < size; ++y) {
|
||||
for (int x = 0; x < size; ++x) {
|
||||
sum += in.TopLeftPixel()[y * in.stride() + x];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 4: sum *= 2; break;
|
||||
case 8: /*sum = sum;*/ break;
|
||||
case 16: sum >>= 1; break;
|
||||
case 32: sum >>= 3; break;
|
||||
}
|
||||
|
||||
return static_cast<tran_low_t>(sum);
|
||||
}
|
||||
|
||||
class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> {
|
||||
public:
|
||||
PartialFdctTest() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
size_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunTest() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int16_t maxvalue =
|
||||
clip_pixel_highbd(std::numeric_limits<int16_t>::max(), bit_depth_);
|
||||
const int16_t minvalue = -maxvalue;
|
||||
Buffer<int16_t> input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_block.Init());
|
||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
if (output_block.TopLeftPixel() != NULL) {
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
if (i == 0) {
|
||||
input_block.Set(maxvalue);
|
||||
} else if (i == 1) {
|
||||
input_block.Set(minvalue);
|
||||
} else {
|
||||
input_block.Set(&rnd, minvalue, maxvalue);
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block.TopLeftPixel(),
|
||||
output_block.TopLeftPixel(),
|
||||
input_block.stride()));
|
||||
|
||||
EXPECT_EQ(partial_fdct_ref(input_block, size_),
|
||||
output_block.TopLeftPixel()[0]);
|
||||
}
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
PartialFdctFunc fwd_txfm_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int size_;
|
||||
};
|
||||
|
||||
TEST_P(PartialFdctTest, PartialFdctTest) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_sse2, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_sse2, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_sse2, 4, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_1_msa, 8,
|
||||
VPX_BITS_8)));
|
||||
#else // !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_msa, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_msa, 8, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_MSA
|
||||
} // namespace
|
||||
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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 <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
using std::make_tuple;
|
||||
using std::tuple;
|
||||
|
||||
namespace {
|
||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
||||
int tx_type);
|
||||
typedef void (*FhtFuncRef)(const Buffer<int16_t> &in, Buffer<tran_low_t> *out,
|
||||
int size, int tx_type);
|
||||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type);
|
||||
typedef void (*IhtWithBdFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type, int bd);
|
||||
|
||||
template <FdctFunc fn>
|
||||
void fdct_wrapper(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||
(void)tx_type;
|
||||
fn(in, out, stride);
|
||||
}
|
||||
|
||||
template <IdctFunc fn>
|
||||
void idct_wrapper(const tran_low_t *in, uint8_t *out, int stride, int tx_type,
|
||||
int bd) {
|
||||
(void)tx_type;
|
||||
(void)bd;
|
||||
fn(in, out, stride);
|
||||
}
|
||||
|
||||
template <IhtFunc fn>
|
||||
void iht_wrapper(const tran_low_t *in, uint8_t *out, int stride, int tx_type,
|
||||
int bd) {
|
||||
(void)bd;
|
||||
fn(in, out, stride, tx_type);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
typedef void (*HighbdIdctFunc)(const tran_low_t *in, uint16_t *out, int stride,
|
||||
int bd);
|
||||
|
||||
typedef void (*HighbdIhtFunc)(const tran_low_t *in, uint16_t *out, int stride,
|
||||
int tx_type, int bd);
|
||||
|
||||
template <HighbdIdctFunc fn>
|
||||
void highbd_idct_wrapper(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type, int bd) {
|
||||
(void)tx_type;
|
||||
fn(in, CAST_TO_SHORTPTR(out), stride, bd);
|
||||
}
|
||||
|
||||
template <HighbdIhtFunc fn>
|
||||
void highbd_iht_wrapper(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type, int bd) {
|
||||
fn(in, CAST_TO_SHORTPTR(out), stride, tx_type, bd);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
struct FuncInfo {
|
||||
FhtFunc ft_func;
|
||||
IhtWithBdFunc it_func;
|
||||
int size;
|
||||
int pixel_size;
|
||||
};
|
||||
|
||||
/* forward transform, inverse transform, size, transform type, bit depth */
|
||||
typedef tuple<int, const FuncInfo *, int, vpx_bit_depth_t> DctParam;
|
||||
|
||||
void fdct_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int /*tx_type*/) {
|
||||
const int16_t *i = in.TopLeftPixel();
|
||||
const int i_stride = in.stride();
|
||||
tran_low_t *o = out->TopLeftPixel();
|
||||
if (size == 4) {
|
||||
vpx_fdct4x4_c(i, o, i_stride);
|
||||
} else if (size == 8) {
|
||||
vpx_fdct8x8_c(i, o, i_stride);
|
||||
} else if (size == 16) {
|
||||
vpx_fdct16x16_c(i, o, i_stride);
|
||||
} else if (size == 32) {
|
||||
vpx_fdct32x32_c(i, o, i_stride);
|
||||
}
|
||||
}
|
||||
|
||||
void fht_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int tx_type) {
|
||||
const int16_t *i = in.TopLeftPixel();
|
||||
const int i_stride = in.stride();
|
||||
tran_low_t *o = out->TopLeftPixel();
|
||||
if (size == 4) {
|
||||
vp9_fht4x4_c(i, o, i_stride, tx_type);
|
||||
} else if (size == 8) {
|
||||
vp9_fht8x8_c(i, o, i_stride, tx_type);
|
||||
} else if (size == 16) {
|
||||
vp9_fht16x16_c(i, o, i_stride, tx_type);
|
||||
}
|
||||
}
|
||||
|
||||
void fwht_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int /*tx_type*/) {
|
||||
ASSERT_EQ(size, 4);
|
||||
vp9_fwht4x4_c(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
||||
}
|
||||
|
||||
class TransTestBase : public ::testing::TestWithParam<DctParam> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
const int idx = GET_PARAM(0);
|
||||
const FuncInfo *func_info = &(GET_PARAM(1)[idx]);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
fwd_txfm_ = func_info->ft_func;
|
||||
inv_txfm_ = func_info->it_func;
|
||||
size_ = func_info->size;
|
||||
pixel_size_ = func_info->pixel_size;
|
||||
max_pixel_value_ = (1 << bit_depth_) - 1;
|
||||
|
||||
// Randomize stride_ to a value less than or equal to 1024
|
||||
stride_ = rnd_(1024) + 1;
|
||||
if (stride_ < size_) {
|
||||
stride_ = size_;
|
||||
}
|
||||
// Align stride_ to 16 if it's bigger than 16.
|
||||
if (stride_ > 16) {
|
||||
stride_ &= ~15;
|
||||
}
|
||||
|
||||
block_size_ = size_ * stride_;
|
||||
|
||||
src_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(16, pixel_size_ * block_size_));
|
||||
ASSERT_TRUE(src_ != NULL);
|
||||
dst_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(16, pixel_size_ * block_size_));
|
||||
ASSERT_TRUE(dst_ != NULL);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
vpx_free(src_);
|
||||
src_ = NULL;
|
||||
vpx_free(dst_);
|
||||
dst_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
void InitMem() {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
if (pixel_size_ == 1) {
|
||||
for (int j = 0; j < block_size_; ++j) {
|
||||
src_[j] = rnd_.Rand16() & max_pixel_value_;
|
||||
}
|
||||
for (int j = 0; j < block_size_; ++j) {
|
||||
dst_[j] = rnd_.Rand16() & max_pixel_value_;
|
||||
}
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
for (int j = 0; j < block_size_; ++j) {
|
||||
src[j] = rnd_.Rand16() & max_pixel_value_;
|
||||
}
|
||||
for (int j = 0; j < block_size_; ++j) {
|
||||
dst[j] = rnd_.Rand16() & max_pixel_value_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
||||
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride(), tx_type_);
|
||||
}
|
||||
|
||||
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
||||
inv_txfm_(in.TopLeftPixel(), out, stride_, tx_type_, bit_depth_);
|
||||
}
|
||||
|
||||
protected:
|
||||
void RunAccuracyCheck(int limit) {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
Buffer<int16_t> test_input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(test_input_block.Init());
|
||||
ASSERT_TRUE(test_input_block.TopLeftPixel() != NULL);
|
||||
Buffer<tran_low_t> test_temp_block =
|
||||
Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(test_temp_block.Init());
|
||||
uint32_t max_error = 0;
|
||||
int64_t total_error = 0;
|
||||
const int count_test_block = 10000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
InitMem();
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
if (pixel_size_ == 1) {
|
||||
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
||||
src_[h * stride_ + w] - dst_[h * stride_ + w];
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
const uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
const uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
||||
src[h * stride_ + w] - dst[h * stride_ + w];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block, &test_temp_block));
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst_));
|
||||
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
int diff;
|
||||
if (pixel_size_ == 1) {
|
||||
diff = dst_[h * stride_ + w] - src_[h * stride_ + w];
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
const uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
const uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
diff = dst[h * stride_ + w] - src[h * stride_ + w];
|
||||
}
|
||||
const uint32_t error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
||||
<< "Error: " << size_ << "x" << size_
|
||||
<< " transform/inverse transform has an individual round trip error > "
|
||||
<< limit;
|
||||
|
||||
EXPECT_GE(count_test_block * limit, total_error)
|
||||
<< "Error: " << size_ << "x" << size_
|
||||
<< " transform/inverse transform has average round trip error > "
|
||||
<< limit << " per block";
|
||||
}
|
||||
|
||||
void RunCoeffCheck() {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
Buffer<int16_t> input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_block.Init());
|
||||
Buffer<tran_low_t> output_ref_block = Buffer<tran_low_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(output_ref_block.Init());
|
||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-max_pixel_value_,
|
||||
// max_pixel_value_].
|
||||
input_block.Set(&rnd, -max_pixel_value_, max_pixel_value_);
|
||||
|
||||
fwd_txfm_ref(input_block, &output_ref_block, size_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, &output_block));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
EXPECT_TRUE(output_block.CheckValues(output_ref_block));
|
||||
if (::testing::Test::HasFailure()) {
|
||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
||||
output_block.PrintDifference(output_ref_block);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunMemCheck() {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
Buffer<int16_t> input_extreme_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_extreme_block.Init());
|
||||
Buffer<tran_low_t> output_ref_block = Buffer<tran_low_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(output_ref_block.Init());
|
||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with -max_pixel_value_ or max_pixel_value_.
|
||||
if (i == 0) {
|
||||
input_extreme_block.Set(max_pixel_value_);
|
||||
} else if (i == 1) {
|
||||
input_extreme_block.Set(-max_pixel_value_);
|
||||
} else {
|
||||
ASSERT_TRUE(input_extreme_block.TopLeftPixel() != NULL);
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
input_extreme_block
|
||||
.TopLeftPixel()[h * input_extreme_block.stride() + w] =
|
||||
rnd.Rand8() % 2 ? max_pixel_value_ : -max_pixel_value_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_extreme_block, &output_ref_block, size_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, &output_block));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
EXPECT_TRUE(output_block.CheckValues(output_ref_block));
|
||||
ASSERT_TRUE(output_block.TopLeftPixel() != NULL);
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
EXPECT_GE(
|
||||
4 * DCT_MAX_VALUE << (bit_depth_ - 8),
|
||||
abs(output_block.TopLeftPixel()[h * output_block.stride() + w]))
|
||||
<< "Error: " << size_ << "x" << size_
|
||||
<< " transform has coefficient larger than 4*DCT_MAX_VALUE"
|
||||
<< " at " << w << "," << h;
|
||||
if (::testing::Test::HasFailure()) {
|
||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
||||
output_block.DumpBuffer();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunInvAccuracyCheck(int limit) {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
Buffer<int16_t> in = Buffer<int16_t>(size_, size_, 4);
|
||||
ASSERT_TRUE(in.Init());
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<uint8_t> dst = Buffer<uint8_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(dst.Init());
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(src.Init());
|
||||
Buffer<uint16_t> dst16 = Buffer<uint16_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(dst16.Init());
|
||||
Buffer<uint16_t> src16 = Buffer<uint16_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(src16.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
InitMem();
|
||||
ASSERT_TRUE(in.TopLeftPixel() != NULL);
|
||||
// Initialize a test block with input range [-max_pixel_value_,
|
||||
// max_pixel_value_].
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
if (pixel_size_ == 1) {
|
||||
in.TopLeftPixel()[h * in.stride() + w] =
|
||||
src_[h * stride_ + w] - dst_[h * stride_ + w];
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
const uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
const uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
in.TopLeftPixel()[h * in.stride() + w] =
|
||||
src[h * stride_ + w] - dst[h * stride_ + w];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fwd_txfm_ref(in, &coeff, size_, tx_type_);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst_));
|
||||
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
int diff;
|
||||
if (pixel_size_ == 1) {
|
||||
diff = dst_[h * stride_ + w] - src_[h * stride_ + w];
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
const uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
const uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
diff = dst[h * stride_ + w] - src[h * stride_ + w];
|
||||
}
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
||||
<< "Error: " << size_ << "x" << size_
|
||||
<< " inverse transform has error " << error << " at " << w << ","
|
||||
<< h;
|
||||
if (::testing::Test::HasFailure()) {
|
||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FhtFunc fwd_txfm_;
|
||||
FhtFuncRef fwd_txfm_ref;
|
||||
IhtWithBdFunc inv_txfm_;
|
||||
ACMRandom rnd_;
|
||||
uint8_t *src_;
|
||||
uint8_t *dst_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int tx_type_;
|
||||
int max_pixel_value_;
|
||||
int size_;
|
||||
int stride_;
|
||||
int pixel_size_;
|
||||
int block_size_;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class TransDCT : public TransTestBase {
|
||||
public:
|
||||
TransDCT() { fwd_txfm_ref = fdct_ref; }
|
||||
};
|
||||
|
||||
TEST_P(TransDCT, AccuracyCheck) {
|
||||
int t = 1;
|
||||
if (size_ == 16 && bit_depth_ > 10 && pixel_size_ == 2) {
|
||||
t = 2;
|
||||
} else if (size_ == 32 && bit_depth_ > 10 && pixel_size_ == 2) {
|
||||
t = 7;
|
||||
}
|
||||
RunAccuracyCheck(t);
|
||||
}
|
||||
|
||||
TEST_P(TransDCT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransDCT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransDCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
static const FuncInfo dct_c_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &fdct_wrapper<vpx_highbd_fdct4x4_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct4x4_16_add_c>, 4, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct8x8_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct8x8_64_add_c>, 8, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct16x16_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct16x16_256_add_c>, 16, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct32x32_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct32x32_1024_add_c>, 32, 2 },
|
||||
#endif
|
||||
{ &fdct_wrapper<vpx_fdct4x4_c>, &idct_wrapper<vpx_idct4x4_16_add_c>, 4, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct8x8_c>, &idct_wrapper<vpx_idct8x8_64_add_c>, 8, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct16x16_c>, &idct_wrapper<vpx_idct16x16_256_add_c>, 16,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct32x32_c>, &idct_wrapper<vpx_idct32x32_1024_add_c>, 32,
|
||||
1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransDCT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(dct_c_func_info) /
|
||||
sizeof(dct_c_func_info[0]))),
|
||||
::testing::Values(dct_c_func_info), ::testing::Values(0),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2
|
||||
static const FuncInfo dct_sse2_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &fdct_wrapper<vpx_highbd_fdct4x4_sse2>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct4x4_16_add_sse2>, 4, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct8x8_sse2>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct8x8_64_add_sse2>, 8, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct16x16_sse2>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct16x16_256_add_sse2>, 16, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct32x32_sse2>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct32x32_1024_add_sse2>, 32, 2 },
|
||||
#endif
|
||||
{ &fdct_wrapper<vpx_fdct4x4_sse2>, &idct_wrapper<vpx_idct4x4_16_add_sse2>, 4,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct8x8_sse2>, &idct_wrapper<vpx_idct8x8_64_add_sse2>, 8,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct16x16_sse2>,
|
||||
&idct_wrapper<vpx_idct16x16_256_add_sse2>, 16, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct32x32_sse2>,
|
||||
&idct_wrapper<vpx_idct32x32_1024_add_sse2>, 32, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, TransDCT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(dct_sse2_func_info) /
|
||||
sizeof(dct_sse2_func_info[0]))),
|
||||
::testing::Values(dct_sse2_func_info), ::testing::Values(0),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && VPX_ARCH_X86_64
|
||||
// vpx_fdct8x8_ssse3 is only available in 64 bit builds.
|
||||
static const FuncInfo dct_ssse3_func_info = {
|
||||
&fdct_wrapper<vpx_fdct8x8_ssse3>, &idct_wrapper<vpx_idct8x8_64_add_sse2>, 8, 1
|
||||
};
|
||||
|
||||
// TODO(johannkoenig): high bit depth fdct8x8.
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, TransDCT,
|
||||
::testing::Values(make_tuple(0, &dct_ssse3_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && VPX_ARCH_X86_64
|
||||
|
||||
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo dct_avx2_func_info = {
|
||||
&fdct_wrapper<vpx_fdct32x32_avx2>, &idct_wrapper<vpx_idct32x32_1024_add_sse2>,
|
||||
32, 1
|
||||
};
|
||||
|
||||
// TODO(johannkoenig): high bit depth fdct32x32.
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, TransDCT,
|
||||
::testing::Values(make_tuple(0, &dct_avx2_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON
|
||||
static const FuncInfo dct_neon_func_info[4] = {
|
||||
{ &fdct_wrapper<vpx_fdct4x4_neon>, &idct_wrapper<vpx_idct4x4_16_add_neon>, 4,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct8x8_neon>, &idct_wrapper<vpx_idct8x8_64_add_neon>, 8,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct16x16_neon>,
|
||||
&idct_wrapper<vpx_idct16x16_256_add_neon>, 16, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct32x32_neon>,
|
||||
&idct_wrapper<vpx_idct32x32_1024_add_neon>, 32, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, TransDCT,
|
||||
::testing::Combine(::testing::Range(0, 4),
|
||||
::testing::Values(dct_neon_func_info),
|
||||
::testing::Values(0), ::testing::Values(VPX_BITS_8)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo dct_msa_func_info[4] = {
|
||||
{ &fdct_wrapper<vpx_fdct4x4_msa>, &idct_wrapper<vpx_idct4x4_16_add_msa>, 4,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct8x8_msa>, &idct_wrapper<vpx_idct8x8_64_add_msa>, 8,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct16x16_msa>, &idct_wrapper<vpx_idct16x16_256_add_msa>,
|
||||
16, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct32x32_msa>, &idct_wrapper<vpx_idct32x32_1024_add_msa>,
|
||||
32, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, TransDCT,
|
||||
::testing::Combine(::testing::Range(0, 4),
|
||||
::testing::Values(dct_msa_func_info),
|
||||
::testing::Values(0),
|
||||
::testing::Values(VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo dct_vsx_func_info = {
|
||||
&fdct_wrapper<vpx_fdct4x4_c>, &idct_wrapper<vpx_idct4x4_16_add_vsx>, 4, 1
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VSX, TransDCT,
|
||||
::testing::Values(make_tuple(0, &dct_vsx_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH &&
|
||||
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class TransHT : public TransTestBase {
|
||||
public:
|
||||
TransHT() { fwd_txfm_ref = fht_ref; }
|
||||
};
|
||||
|
||||
TEST_P(TransHT, AccuracyCheck) {
|
||||
RunAccuracyCheck(size_ == 16 && bit_depth_ > 10 && pixel_size_ == 2 ? 2 : 1);
|
||||
}
|
||||
|
||||
TEST_P(TransHT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransHT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransHT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
static const FuncInfo ht_c_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &vp9_highbd_fht4x4_c, &highbd_iht_wrapper<vp9_highbd_iht4x4_16_add_c>, 4,
|
||||
2 },
|
||||
{ &vp9_highbd_fht8x8_c, &highbd_iht_wrapper<vp9_highbd_iht8x8_64_add_c>, 8,
|
||||
2 },
|
||||
{ &vp9_highbd_fht16x16_c, &highbd_iht_wrapper<vp9_highbd_iht16x16_256_add_c>,
|
||||
16, 2 },
|
||||
#endif
|
||||
{ &vp9_fht4x4_c, &iht_wrapper<vp9_iht4x4_16_add_c>, 4, 1 },
|
||||
{ &vp9_fht8x8_c, &iht_wrapper<vp9_iht8x8_64_add_c>, 8, 1 },
|
||||
{ &vp9_fht16x16_c, &iht_wrapper<vp9_iht16x16_256_add_c>, 16, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransHT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(ht_c_func_info) /
|
||||
sizeof(ht_c_func_info[0]))),
|
||||
::testing::Values(ht_c_func_info), ::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_NEON
|
||||
|
||||
static const FuncInfo ht_neon_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &vp9_highbd_fht4x4_c, &highbd_iht_wrapper<vp9_highbd_iht4x4_16_add_neon>, 4,
|
||||
2 },
|
||||
{ &vp9_highbd_fht8x8_c, &highbd_iht_wrapper<vp9_highbd_iht8x8_64_add_neon>, 8,
|
||||
2 },
|
||||
{ &vp9_highbd_fht16x16_c,
|
||||
&highbd_iht_wrapper<vp9_highbd_iht16x16_256_add_neon>, 16, 2 },
|
||||
#endif
|
||||
{ &vp9_fht4x4_c, &iht_wrapper<vp9_iht4x4_16_add_neon>, 4, 1 },
|
||||
{ &vp9_fht8x8_c, &iht_wrapper<vp9_iht8x8_64_add_neon>, 8, 1 },
|
||||
{ &vp9_fht16x16_c, &iht_wrapper<vp9_iht16x16_256_add_neon>, 16, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, TransHT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(ht_neon_func_info) /
|
||||
sizeof(ht_neon_func_info[0]))),
|
||||
::testing::Values(ht_neon_func_info), ::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_SSE2
|
||||
|
||||
static const FuncInfo ht_sse2_func_info[3] = {
|
||||
{ &vp9_fht4x4_sse2, &iht_wrapper<vp9_iht4x4_16_add_sse2>, 4, 1 },
|
||||
{ &vp9_fht8x8_sse2, &iht_wrapper<vp9_iht8x8_64_add_sse2>, 8, 1 },
|
||||
{ &vp9_fht16x16_sse2, &iht_wrapper<vp9_iht16x16_256_add_sse2>, 16, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, TransHT,
|
||||
::testing::Combine(::testing::Range(0, 3),
|
||||
::testing::Values(ht_sse2_func_info),
|
||||
::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo ht_sse4_1_func_info[3] = {
|
||||
{ &vp9_highbd_fht4x4_c, &highbd_iht_wrapper<vp9_highbd_iht4x4_16_add_sse4_1>,
|
||||
4, 2 },
|
||||
{ vp9_highbd_fht8x8_c, &highbd_iht_wrapper<vp9_highbd_iht8x8_64_add_sse4_1>,
|
||||
8, 2 },
|
||||
{ &vp9_highbd_fht16x16_c,
|
||||
&highbd_iht_wrapper<vp9_highbd_iht16x16_256_add_sse4_1>, 16, 2 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE4_1, TransHT,
|
||||
::testing::Combine(::testing::Range(0, 3),
|
||||
::testing::Values(ht_sse4_1_func_info),
|
||||
::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10,
|
||||
VPX_BITS_12)));
|
||||
#endif // HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_VSX && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo ht_vsx_func_info[3] = {
|
||||
{ &vp9_fht4x4_c, &iht_wrapper<vp9_iht4x4_16_add_vsx>, 4, 1 },
|
||||
{ &vp9_fht8x8_c, &iht_wrapper<vp9_iht8x8_64_add_vsx>, 8, 1 },
|
||||
{ &vp9_fht16x16_c, &iht_wrapper<vp9_iht16x16_256_add_vsx>, 16, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VSX, TransHT,
|
||||
::testing::Combine(::testing::Range(0, 3),
|
||||
::testing::Values(ht_vsx_func_info),
|
||||
::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8)));
|
||||
#endif // HAVE_VSX
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class TransWHT : public TransTestBase {
|
||||
public:
|
||||
TransWHT() { fwd_txfm_ref = fwht_ref; }
|
||||
};
|
||||
|
||||
TEST_P(TransWHT, AccuracyCheck) { RunAccuracyCheck(0); }
|
||||
|
||||
TEST_P(TransWHT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransWHT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransWHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
|
||||
|
||||
static const FuncInfo wht_c_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &fdct_wrapper<vp9_highbd_fwht4x4_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_iwht4x4_16_add_c>, 4, 2 },
|
||||
#endif
|
||||
{ &fdct_wrapper<vp9_fwht4x4_c>, &idct_wrapper<vpx_iwht4x4_16_add_c>, 4, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransWHT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(wht_c_func_info) /
|
||||
sizeof(wht_c_func_info[0]))),
|
||||
::testing::Values(wht_c_func_info), ::testing::Values(0),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||
static const FuncInfo wht_sse2_func_info = {
|
||||
&fdct_wrapper<vp9_fwht4x4_sse2>, &idct_wrapper<vpx_iwht4x4_16_add_sse2>, 4, 1
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, TransWHT,
|
||||
::testing::Values(make_tuple(0, &wht_sse2_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo wht_vsx_func_info = {
|
||||
&fdct_wrapper<vp9_fwht4x4_c>, &idct_wrapper<vpx_iwht4x4_16_add_vsx>, 4, 1
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VSX, TransWHT,
|
||||
::testing::Values(make_tuple(0, &wht_vsx_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "vpx/vp8dx.h"
|
||||
#include "vpx/vpx_decoder.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
|
||||
|
||||
TEST(DecodeAPI, InvalidParams) {
|
||||
static const vpx_codec_iface_t *kCodecs[] = {
|
||||
#if CONFIG_VP8_DECODER
|
||||
&vpx_codec_vp8_dx_algo,
|
||||
#endif
|
||||
#if CONFIG_VP9_DECODER
|
||||
&vpx_codec_vp9_dx_algo,
|
||||
#endif
|
||||
};
|
||||
uint8_t buf[1] = { 0 };
|
||||
vpx_codec_ctx_t dec;
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_dec_init(NULL, NULL, NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_dec_init(&dec, NULL, NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(NULL, NULL, 0, NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(NULL, buf, 0, NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_decode(NULL, buf, NELEMENTS(buf), NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_decode(NULL, NULL, NELEMENTS(buf), NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
|
||||
EXPECT_TRUE(vpx_codec_error(NULL) != NULL);
|
||||
|
||||
for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_dec_init(NULL, kCodecs[i], NULL, 0));
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, kCodecs[i], NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
|
||||
vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(&dec, buf, 0, NULL, 0));
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
TEST(DecodeAPI, OptionalParams) {
|
||||
vpx_codec_ctx_t dec;
|
||||
|
||||
#if CONFIG_ERROR_CONCEALMENT
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
|
||||
VPX_CODEC_USE_ERROR_CONCEALMENT));
|
||||
#else
|
||||
EXPECT_EQ(VPX_CODEC_INCAPABLE,
|
||||
vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
|
||||
VPX_CODEC_USE_ERROR_CONCEALMENT));
|
||||
#endif // CONFIG_ERROR_CONCEALMENT
|
||||
}
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Test VP9 codec controls after a decode error to ensure the code doesn't
|
||||
// misbehave.
|
||||
void TestVp9Controls(vpx_codec_ctx_t *dec) {
|
||||
static const int kControls[] = { VP8D_GET_LAST_REF_UPDATES,
|
||||
VP8D_GET_FRAME_CORRUPTED,
|
||||
VP9D_GET_DISPLAY_SIZE, VP9D_GET_FRAME_SIZE };
|
||||
int val[2];
|
||||
|
||||
for (int i = 0; i < NELEMENTS(kControls); ++i) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val);
|
||||
switch (kControls[i]) {
|
||||
case VP8D_GET_FRAME_CORRUPTED:
|
||||
EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
|
||||
break;
|
||||
default: EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i]; break;
|
||||
}
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_control_(dec, kControls[i], NULL));
|
||||
}
|
||||
|
||||
vp9_ref_frame_t ref;
|
||||
ref.idx = 0;
|
||||
EXPECT_EQ(VPX_CODEC_ERROR, vpx_codec_control(dec, VP9_GET_REFERENCE, &ref));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_control(dec, VP9_GET_REFERENCE, NULL));
|
||||
|
||||
vpx_ref_frame_t ref_copy;
|
||||
const int width = 352;
|
||||
const int height = 288;
|
||||
ASSERT_TRUE(
|
||||
vpx_img_alloc(&ref_copy.img, VPX_IMG_FMT_I420, width, height, 1) != NULL);
|
||||
ref_copy.frame_type = VP8_LAST_FRAME;
|
||||
EXPECT_EQ(VPX_CODEC_ERROR,
|
||||
vpx_codec_control(dec, VP8_COPY_REFERENCE, &ref_copy));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_control(dec, VP8_COPY_REFERENCE, NULL));
|
||||
vpx_img_free(&ref_copy.img);
|
||||
}
|
||||
|
||||
TEST(DecodeAPI, Vp9InvalidDecode) {
|
||||
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
|
||||
const char filename[] =
|
||||
"invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf";
|
||||
libvpx_test::IVFVideoSource video(filename);
|
||||
video.Init();
|
||||
video.Begin();
|
||||
ASSERT_TRUE(!HasFailure());
|
||||
|
||||
vpx_codec_ctx_t dec;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
|
||||
const uint32_t frame_size = static_cast<uint32_t>(video.frame_size());
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
EXPECT_EQ(VPX_CODEC_MEM_ERROR,
|
||||
vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
|
||||
#else
|
||||
EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
|
||||
vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
|
||||
#endif
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
|
||||
|
||||
TestVp9Controls(&dec);
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||
}
|
||||
|
||||
void TestPeekInfo(const uint8_t *const data, uint32_t data_sz,
|
||||
uint32_t peek_size) {
|
||||
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
|
||||
// Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
|
||||
// to decoder_peek_si_internal on frames of size < 8.
|
||||
if (data_sz >= 8) {
|
||||
vpx_codec_ctx_t dec;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
|
||||
EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM
|
||||
: VPX_CODEC_CORRUPT_FRAME,
|
||||
vpx_codec_decode(&dec, data, data_sz, NULL, 0));
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||
}
|
||||
|
||||
// Verify behavior of vpx_codec_peek_stream_info.
|
||||
vpx_codec_stream_info_t si;
|
||||
si.sz = sizeof(si);
|
||||
EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
|
||||
vpx_codec_peek_stream_info(codec, data, data_sz, &si));
|
||||
}
|
||||
|
||||
TEST(DecodeAPI, Vp9PeekStreamInfo) {
|
||||
// The first 9 bytes are valid and the rest of the bytes are made up. Until
|
||||
// size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
|
||||
// should return VPX_CODEC_CORRUPT_FRAME.
|
||||
const uint8_t data[32] = {
|
||||
0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49, 0x83, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
};
|
||||
|
||||
for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
|
||||
TestPeekInfo(data, data_sz, 10);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DecodeAPI, Vp9PeekStreamInfoTruncated) {
|
||||
// This profile 1 header requires 10.25 bytes, ensure
|
||||
// vpx_codec_peek_stream_info doesn't over read.
|
||||
const uint8_t profile1_data[10] = { 0xa4, 0xe9, 0x30, 0x68, 0x53,
|
||||
0xe9, 0x30, 0x68, 0x53, 0x04 };
|
||||
|
||||
for (uint32_t data_sz = 1; data_sz <= 10; ++data_sz) {
|
||||
TestPeekInfo(profile1_data, data_sz, 11);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_VP9_DECODER
|
||||
|
||||
TEST(DecodeAPI, HighBitDepthCapability) {
|
||||
// VP8 should not claim VP9 HBD as a capability.
|
||||
#if CONFIG_VP8_DECODER
|
||||
const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_dx_algo);
|
||||
EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_dx_algo);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
|
||||
#else
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 <tuple>
|
||||
|
||||
#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/i420_video_source.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class DecodeCorruptedFrameTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::testing::TestWithParam<
|
||||
std::tuple<const libvpx_test::CodecFactory *> > {
|
||||
public:
|
||||
DecodeCorruptedFrameTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
|
||||
protected:
|
||||
virtual ~DecodeCorruptedFrameTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(::libvpx_test::kRealTime);
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 600;
|
||||
|
||||
// Set small key frame distance such that we insert more key frames.
|
||||
cfg_.kf_max_dist = 3;
|
||||
dec_cfg_.threads = 1;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, 7);
|
||||
}
|
||||
|
||||
virtual void MismatchHook(const vpx_image_t * /*img1*/,
|
||||
const vpx_image_t * /*img2*/) {}
|
||||
|
||||
virtual const vpx_codec_cx_pkt_t *MutateEncoderOutputHook(
|
||||
const vpx_codec_cx_pkt_t *pkt) {
|
||||
// Don't edit frame packet on key frame.
|
||||
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) return pkt;
|
||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return pkt;
|
||||
|
||||
memcpy(&modified_pkt_, pkt, sizeof(*pkt));
|
||||
|
||||
// Halve the size so it's corrupted to decoder.
|
||||
modified_pkt_.data.frame.sz = modified_pkt_.data.frame.sz / 2;
|
||||
|
||||
return &modified_pkt_;
|
||||
}
|
||||
|
||||
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
|
||||
const libvpx_test::VideoSource & /*video*/,
|
||||
libvpx_test::Decoder *decoder) {
|
||||
EXPECT_NE(res_dec, VPX_CODEC_MEM_ERROR) << decoder->DecodeError();
|
||||
return VPX_CODEC_MEM_ERROR != res_dec;
|
||||
}
|
||||
|
||||
vpx_codec_cx_pkt_t modified_pkt_;
|
||||
};
|
||||
|
||||
TEST_P(DecodeCorruptedFrameTest, DecodeCorruptedFrame) {
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
cfg_.g_error_resilient = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
#if CONFIG_VP9
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9, DecodeCorruptedFrameTest,
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)));
|
||||
#endif // CONFIG_VP9
|
||||
|
||||
#if CONFIG_VP8
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP8, DecodeCorruptedFrameTest,
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)));
|
||||
#endif // CONFIG_VP8
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/encode_test_driver.h"
|
||||
#include "test/i420_video_source.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/util.h"
|
||||
#include "test/webm_video_source.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
#include "./ivfenc.h"
|
||||
#include "./vpx_version.h"
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
namespace {
|
||||
|
||||
#define VIDEO_NAME 0
|
||||
#define THREADS 1
|
||||
|
||||
const double kUsecsInSec = 1000000.0;
|
||||
const char kNewEncodeOutputFile[] = "new_encode.ivf";
|
||||
|
||||
/*
|
||||
DecodePerfTest takes a tuple of filename + number of threads to decode with
|
||||
*/
|
||||
typedef std::tuple<const char *, unsigned> DecodePerfParam;
|
||||
|
||||
const DecodePerfParam kVP9DecodePerfVectors[] = {
|
||||
make_tuple("vp90-2-bbb_426x240_tile_1x1_180kbps.webm", 1),
|
||||
make_tuple("vp90-2-bbb_640x360_tile_1x2_337kbps.webm", 2),
|
||||
make_tuple("vp90-2-bbb_854x480_tile_1x2_651kbps.webm", 2),
|
||||
make_tuple("vp90-2-bbb_1280x720_tile_1x4_1310kbps.webm", 4),
|
||||
make_tuple("vp90-2-bbb_1920x1080_tile_1x1_2581kbps.webm", 1),
|
||||
make_tuple("vp90-2-bbb_1920x1080_tile_1x4_2586kbps.webm", 4),
|
||||
make_tuple("vp90-2-bbb_1920x1080_tile_1x4_fpm_2304kbps.webm", 4),
|
||||
make_tuple("vp90-2-sintel_426x182_tile_1x1_171kbps.webm", 1),
|
||||
make_tuple("vp90-2-sintel_640x272_tile_1x2_318kbps.webm", 2),
|
||||
make_tuple("vp90-2-sintel_854x364_tile_1x2_621kbps.webm", 2),
|
||||
make_tuple("vp90-2-sintel_1280x546_tile_1x4_1257kbps.webm", 4),
|
||||
make_tuple("vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm", 4),
|
||||
make_tuple("vp90-2-tos_426x178_tile_1x1_181kbps.webm", 1),
|
||||
make_tuple("vp90-2-tos_640x266_tile_1x2_336kbps.webm", 2),
|
||||
make_tuple("vp90-2-tos_854x356_tile_1x2_656kbps.webm", 2),
|
||||
make_tuple("vp90-2-tos_854x356_tile_1x2_fpm_546kbps.webm", 2),
|
||||
make_tuple("vp90-2-tos_1280x534_tile_1x4_1306kbps.webm", 4),
|
||||
make_tuple("vp90-2-tos_1280x534_tile_1x4_fpm_952kbps.webm", 4),
|
||||
make_tuple("vp90-2-tos_1920x800_tile_1x4_fpm_2335kbps.webm", 4),
|
||||
};
|
||||
|
||||
/*
|
||||
In order to reflect real world performance as much as possible, Perf tests
|
||||
*DO NOT* do any correctness checks. Please run them alongside correctness
|
||||
tests to ensure proper codec integrity. Furthermore, in this test we
|
||||
deliberately limit the amount of system calls we make to avoid OS
|
||||
preemption.
|
||||
|
||||
TODO(joshualitt) create a more detailed perf measurement test to collect
|
||||
power/temp/min max frame decode times/etc
|
||||
*/
|
||||
|
||||
class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {};
|
||||
|
||||
TEST_P(DecodePerfTest, PerfTest) {
|
||||
const char *const video_name = GET_PARAM(VIDEO_NAME);
|
||||
const unsigned threads = GET_PARAM(THREADS);
|
||||
|
||||
libvpx_test::WebMVideoSource video(video_name);
|
||||
video.Init();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
cfg.threads = threads;
|
||||
libvpx_test::VP9Decoder decoder(cfg, 0);
|
||||
|
||||
vpx_usec_timer t;
|
||||
vpx_usec_timer_start(&t);
|
||||
|
||||
for (video.Begin(); video.cxdata() != NULL; video.Next()) {
|
||||
decoder.DecodeFrame(video.cxdata(), video.frame_size());
|
||||
}
|
||||
|
||||
vpx_usec_timer_mark(&t);
|
||||
const double elapsed_secs = double(vpx_usec_timer_elapsed(&t)) / kUsecsInSec;
|
||||
const unsigned frames = video.frame_number();
|
||||
const double fps = double(frames) / elapsed_secs;
|
||||
|
||||
printf("{\n");
|
||||
printf("\t\"type\" : \"decode_perf_test\",\n");
|
||||
printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
|
||||
printf("\t\"videoName\" : \"%s\",\n", video_name);
|
||||
printf("\t\"threadCount\" : %u,\n", threads);
|
||||
printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs);
|
||||
printf("\t\"totalFrames\" : %u,\n", frames);
|
||||
printf("\t\"framesPerSecond\" : %f\n", fps);
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
|
||||
::testing::ValuesIn(kVP9DecodePerfVectors));
|
||||
|
||||
class VP9NewEncodeDecodePerfTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
protected:
|
||||
VP9NewEncodeDecodePerfTest()
|
||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), speed_(0),
|
||||
outfile_(0), out_frames_(0) {}
|
||||
|
||||
virtual ~VP9NewEncodeDecodePerfTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
|
||||
cfg_.g_lag_in_frames = 25;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_undershoot_pct = 50;
|
||||
cfg_.rc_overshoot_pct = 50;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 600;
|
||||
cfg_.rc_resize_allowed = 0;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, speed_);
|
||||
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 2);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
const std::string data_path = getenv("LIBVPX_TEST_DATA_PATH");
|
||||
const std::string path_to_source = data_path + "/" + kNewEncodeOutputFile;
|
||||
outfile_ = fopen(path_to_source.c_str(), "wb");
|
||||
ASSERT_TRUE(outfile_ != NULL);
|
||||
}
|
||||
|
||||
virtual void EndPassHook() {
|
||||
if (outfile_ != NULL) {
|
||||
if (!fseek(outfile_, 0, SEEK_SET)) {
|
||||
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
||||
}
|
||||
fclose(outfile_);
|
||||
outfile_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
++out_frames_;
|
||||
|
||||
// Write initial file header if first frame.
|
||||
if (pkt->data.frame.pts == 0) {
|
||||
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
||||
}
|
||||
|
||||
// Write frame header and data.
|
||||
ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
|
||||
ASSERT_EQ(fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_),
|
||||
pkt->data.frame.sz);
|
||||
}
|
||||
|
||||
virtual bool DoDecode() const { return false; }
|
||||
|
||||
void set_speed(unsigned int speed) { speed_ = speed; }
|
||||
|
||||
private:
|
||||
libvpx_test::TestMode encoding_mode_;
|
||||
uint32_t speed_;
|
||||
FILE *outfile_;
|
||||
uint32_t out_frames_;
|
||||
};
|
||||
|
||||
struct EncodePerfTestVideo {
|
||||
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
||||
uint32_t bitrate_, int frames_)
|
||||
: name(name_), width(width_), height(height_), bitrate(bitrate_),
|
||||
frames(frames_) {}
|
||||
const char *name;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t bitrate;
|
||||
int frames;
|
||||
};
|
||||
|
||||
const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
|
||||
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
|
||||
};
|
||||
|
||||
TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
|
||||
SetUp();
|
||||
|
||||
// TODO(JBB): Make this work by going through the set of given files.
|
||||
const int i = 0;
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
||||
libvpx_test::I420VideoSource video(
|
||||
video_name, kVP9EncodePerfTestVectors[i].width,
|
||||
kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
|
||||
kVP9EncodePerfTestVectors[i].frames);
|
||||
set_speed(2);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
const uint32_t threads = 4;
|
||||
|
||||
libvpx_test::IVFVideoSource decode_video(kNewEncodeOutputFile);
|
||||
decode_video.Init();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
cfg.threads = threads;
|
||||
libvpx_test::VP9Decoder decoder(cfg, 0);
|
||||
|
||||
vpx_usec_timer t;
|
||||
vpx_usec_timer_start(&t);
|
||||
|
||||
for (decode_video.Begin(); decode_video.cxdata() != NULL;
|
||||
decode_video.Next()) {
|
||||
decoder.DecodeFrame(decode_video.cxdata(), decode_video.frame_size());
|
||||
}
|
||||
|
||||
vpx_usec_timer_mark(&t);
|
||||
const double elapsed_secs =
|
||||
static_cast<double>(vpx_usec_timer_elapsed(&t)) / kUsecsInSec;
|
||||
const unsigned decode_frames = decode_video.frame_number();
|
||||
const double fps = static_cast<double>(decode_frames) / elapsed_secs;
|
||||
|
||||
printf("{\n");
|
||||
printf("\t\"type\" : \"decode_perf_test\",\n");
|
||||
printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
|
||||
printf("\t\"videoName\" : \"%s\",\n", kNewEncodeOutputFile);
|
||||
printf("\t\"threadCount\" : %u,\n", threads);
|
||||
printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs);
|
||||
printf("\t\"totalFrames\" : %u,\n", decode_frames);
|
||||
printf("\t\"framesPerSecond\" : %f\n", fps);
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(VP9NewEncodeDecodePerfTest,
|
||||
::testing::Values(::libvpx_test::kTwoPassGood));
|
||||
} // namespace
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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 <memory>
|
||||
#include <string>
|
||||
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "test/test_vectors.h"
|
||||
#include "test/util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const unsigned int kNumFrames = 19;
|
||||
|
||||
class DecodeSvcTest : public ::libvpx_test::DecoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<const char *> {
|
||||
protected:
|
||||
DecodeSvcTest() : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)) {}
|
||||
virtual ~DecodeSvcTest() {}
|
||||
|
||||
virtual void PreDecodeFrameHook(
|
||||
const libvpx_test::CompressedVideoSource &video,
|
||||
libvpx_test::Decoder *decoder) {
|
||||
if (video.frame_number() == 0)
|
||||
decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER, spatial_layer_);
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
const unsigned int frame_number) {
|
||||
ASSERT_EQ(img.d_w, width_);
|
||||
ASSERT_EQ(img.d_h, height_);
|
||||
total_frames_ = frame_number;
|
||||
}
|
||||
|
||||
int spatial_layer_;
|
||||
unsigned int width_;
|
||||
unsigned int height_;
|
||||
unsigned int total_frames_;
|
||||
};
|
||||
|
||||
// SVC test vector is 1280x720, with 3 spatial layers, and 20 frames.
|
||||
|
||||
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||
// spatial layer 0. Verify the resolution of each decoded frame and the total
|
||||
// number of frames decoded. This results in 1/4x1/4 resolution (320x180).
|
||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) {
|
||||
const std::string filename = GET_PARAM(1);
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
total_frames_ = 0;
|
||||
spatial_layer_ = 0;
|
||||
width_ = 320;
|
||||
height_ = 180;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||
ASSERT_EQ(total_frames_, kNumFrames);
|
||||
}
|
||||
|
||||
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||
// spatial layer 1. Verify the resolution of each decoded frame and the total
|
||||
// number of frames decoded. This results in 1/2x1/2 resolution (640x360).
|
||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) {
|
||||
const std::string filename = GET_PARAM(1);
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
total_frames_ = 0;
|
||||
spatial_layer_ = 1;
|
||||
width_ = 640;
|
||||
height_ = 360;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||
ASSERT_EQ(total_frames_, kNumFrames);
|
||||
}
|
||||
|
||||
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||
// spatial layer 2. Verify the resolution of each decoded frame and the total
|
||||
// number of frames decoded. This results in the full resolution (1280x720).
|
||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) {
|
||||
const std::string filename = GET_PARAM(1);
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
total_frames_ = 0;
|
||||
spatial_layer_ = 2;
|
||||
width_ = 1280;
|
||||
height_ = 720;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||
ASSERT_EQ(total_frames_, kNumFrames);
|
||||
}
|
||||
|
||||
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||
// spatial layer 10. Verify the resolution of each decoded frame and the total
|
||||
// number of frames decoded. This is beyond the number of spatial layers, so
|
||||
// the decoding should result in the full resolution (1280x720).
|
||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer10) {
|
||||
const std::string filename = GET_PARAM(1);
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
total_frames_ = 0;
|
||||
spatial_layer_ = 10;
|
||||
width_ = 1280;
|
||||
height_ = 720;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||
ASSERT_EQ(total_frames_, kNumFrames);
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
DecodeSvcTest, ::testing::ValuesIn(libvpx_test::kVP9TestVectorsSvc,
|
||||
libvpx_test::kVP9TestVectorsSvc +
|
||||
libvpx_test::kNumVP9TestVectorsSvc));
|
||||
} // namespace
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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 "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/video_source.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
const char kVP8Name[] = "WebM Project VP8";
|
||||
|
||||
vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size,
|
||||
vpx_codec_stream_info_t *stream_info) {
|
||||
return vpx_codec_peek_stream_info(
|
||||
CodecInterface(), cxdata, static_cast<unsigned int>(size), stream_info);
|
||||
}
|
||||
|
||||
vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) {
|
||||
return DecodeFrame(cxdata, size, NULL);
|
||||
}
|
||||
|
||||
vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size,
|
||||
void *user_priv) {
|
||||
vpx_codec_err_t res_dec;
|
||||
InitOnce();
|
||||
API_REGISTER_STATE_CHECK(
|
||||
res_dec = vpx_codec_decode(
|
||||
&decoder_, cxdata, static_cast<unsigned int>(size), user_priv, 0));
|
||||
return res_dec;
|
||||
}
|
||||
|
||||
bool Decoder::IsVP8() const {
|
||||
const char *codec_name = GetDecoderName();
|
||||
return strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
|
||||
}
|
||||
|
||||
void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
||||
CompressedVideoSource *video,
|
||||
const vpx_codec_err_t res_peek) {
|
||||
const bool is_vp8 = decoder->IsVP8();
|
||||
if (is_vp8) {
|
||||
/* Vp8's implementation of PeekStream returns an error if the frame you
|
||||
* pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
|
||||
* frame, which must be a keyframe. */
|
||||
if (video->frame_number() == 0) {
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||
}
|
||||
} else {
|
||||
/* The Vp9 implementation of PeekStream returns an error only if the
|
||||
* data passed to it isn't a valid Vp9 chunk. */
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||
}
|
||||
}
|
||||
|
||||
void DecoderTest::RunLoop(CompressedVideoSource *video,
|
||||
const vpx_codec_dec_cfg_t &dec_cfg) {
|
||||
Decoder *const decoder = codec_->CreateDecoder(dec_cfg, flags_);
|
||||
ASSERT_TRUE(decoder != NULL);
|
||||
bool end_of_file = false;
|
||||
|
||||
// Decode frames.
|
||||
for (video->Begin(); !::testing::Test::HasFailure() && !end_of_file;
|
||||
video->Next()) {
|
||||
PreDecodeFrameHook(*video, decoder);
|
||||
|
||||
vpx_codec_stream_info_t stream_info;
|
||||
stream_info.sz = sizeof(stream_info);
|
||||
|
||||
if (video->cxdata() != NULL) {
|
||||
const vpx_codec_err_t res_peek = decoder->PeekStream(
|
||||
video->cxdata(), video->frame_size(), &stream_info);
|
||||
HandlePeekResult(decoder, video, res_peek);
|
||||
ASSERT_FALSE(::testing::Test::HasFailure());
|
||||
|
||||
vpx_codec_err_t res_dec =
|
||||
decoder->DecodeFrame(video->cxdata(), video->frame_size());
|
||||
if (!HandleDecodeResult(res_dec, *video, decoder)) break;
|
||||
} else {
|
||||
// Signal end of the file to the decoder.
|
||||
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
|
||||
end_of_file = true;
|
||||
}
|
||||
|
||||
DxDataIterator dec_iter = decoder->GetDxData();
|
||||
const vpx_image_t *img = NULL;
|
||||
|
||||
// Get decompressed data
|
||||
while (!::testing::Test::HasFailure() && (img = dec_iter.Next())) {
|
||||
DecompressedFrameHook(*img, video->frame_number());
|
||||
}
|
||||
}
|
||||
delete decoder;
|
||||
}
|
||||
|
||||
void DecoderTest::RunLoop(CompressedVideoSource *video) {
|
||||
vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
|
||||
RunLoop(video, dec_cfg);
|
||||
}
|
||||
|
||||
void DecoderTest::set_cfg(const vpx_codec_dec_cfg_t &dec_cfg) {
|
||||
memcpy(&cfg_, &dec_cfg, sizeof(cfg_));
|
||||
}
|
||||
|
||||
void DecoderTest::set_flags(const vpx_codec_flags_t flags) { flags_ = flags; }
|
||||
|
||||
} // namespace libvpx_test
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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 VPX_TEST_DECODE_TEST_DRIVER_H_
|
||||
#define VPX_TEST_DECODE_TEST_DRIVER_H_
|
||||
#include <cstring>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "vpx/vpx_decoder.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
class CodecFactory;
|
||||
class CompressedVideoSource;
|
||||
|
||||
// Provides an object to handle decoding output
|
||||
class DxDataIterator {
|
||||
public:
|
||||
explicit DxDataIterator(vpx_codec_ctx_t *decoder)
|
||||
: decoder_(decoder), iter_(NULL) {}
|
||||
|
||||
const vpx_image_t *Next() { return vpx_codec_get_frame(decoder_, &iter_); }
|
||||
|
||||
private:
|
||||
vpx_codec_ctx_t *decoder_;
|
||||
vpx_codec_iter_t iter_;
|
||||
};
|
||||
|
||||
// Provides a simplified interface to manage one video decoding.
|
||||
// Similar to Encoder class, the exact services should be added
|
||||
// as more tests are added.
|
||||
class Decoder {
|
||||
public:
|
||||
explicit Decoder(vpx_codec_dec_cfg_t cfg)
|
||||
: cfg_(cfg), flags_(0), init_done_(false) {
|
||||
memset(&decoder_, 0, sizeof(decoder_));
|
||||
}
|
||||
|
||||
Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
||||
: cfg_(cfg), flags_(flag), init_done_(false) {
|
||||
memset(&decoder_, 0, sizeof(decoder_));
|
||||
}
|
||||
|
||||
virtual ~Decoder() { vpx_codec_destroy(&decoder_); }
|
||||
|
||||
vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size,
|
||||
vpx_codec_stream_info_t *stream_info);
|
||||
|
||||
vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size);
|
||||
|
||||
vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size,
|
||||
void *user_priv);
|
||||
|
||||
DxDataIterator GetDxData() { return DxDataIterator(&decoder_); }
|
||||
|
||||
void Control(int ctrl_id, int arg) { Control(ctrl_id, arg, VPX_CODEC_OK); }
|
||||
|
||||
void Control(int ctrl_id, const void *arg) {
|
||||
InitOnce();
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, int arg, vpx_codec_err_t expected_value) {
|
||||
InitOnce();
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(expected_value, res) << DecodeError();
|
||||
}
|
||||
|
||||
const char *DecodeError() {
|
||||
const char *detail = vpx_codec_error_detail(&decoder_);
|
||||
return detail ? detail : vpx_codec_error(&decoder_);
|
||||
}
|
||||
|
||||
// Passes the external frame buffer information to libvpx.
|
||||
vpx_codec_err_t SetFrameBufferFunctions(
|
||||
vpx_get_frame_buffer_cb_fn_t cb_get,
|
||||
vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
|
||||
InitOnce();
|
||||
return vpx_codec_set_frame_buffer_functions(&decoder_, cb_get, cb_release,
|
||||
user_priv);
|
||||
}
|
||||
|
||||
const char *GetDecoderName() const {
|
||||
return vpx_codec_iface_name(CodecInterface());
|
||||
}
|
||||
|
||||
bool IsVP8() const;
|
||||
|
||||
vpx_codec_ctx_t *GetDecoder() { return &decoder_; }
|
||||
|
||||
protected:
|
||||
virtual vpx_codec_iface_t *CodecInterface() const = 0;
|
||||
|
||||
void InitOnce() {
|
||||
if (!init_done_) {
|
||||
const vpx_codec_err_t res =
|
||||
vpx_codec_dec_init(&decoder_, CodecInterface(), &cfg_, flags_);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
|
||||
init_done_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
vpx_codec_ctx_t decoder_;
|
||||
vpx_codec_dec_cfg_t cfg_;
|
||||
vpx_codec_flags_t flags_;
|
||||
bool init_done_;
|
||||
};
|
||||
|
||||
// Common test functionality for all Decoder tests.
|
||||
class DecoderTest {
|
||||
public:
|
||||
// Main decoding loop
|
||||
virtual void RunLoop(CompressedVideoSource *video);
|
||||
virtual void RunLoop(CompressedVideoSource *video,
|
||||
const vpx_codec_dec_cfg_t &dec_cfg);
|
||||
|
||||
virtual void set_cfg(const vpx_codec_dec_cfg_t &dec_cfg);
|
||||
virtual void set_flags(const vpx_codec_flags_t flags);
|
||||
|
||||
// Hook to be called before decompressing every frame.
|
||||
virtual void PreDecodeFrameHook(const CompressedVideoSource & /*video*/,
|
||||
Decoder * /*decoder*/) {}
|
||||
|
||||
// Hook to be called to handle decode result. Return true to continue.
|
||||
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
|
||||
const CompressedVideoSource & /*video*/,
|
||||
Decoder *decoder) {
|
||||
EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
|
||||
return VPX_CODEC_OK == res_dec;
|
||||
}
|
||||
|
||||
// Hook to be called on every decompressed frame.
|
||||
virtual void DecompressedFrameHook(const vpx_image_t & /*img*/,
|
||||
const unsigned int /*frame_number*/) {}
|
||||
|
||||
// Hook to be called on peek result
|
||||
virtual void HandlePeekResult(Decoder *const decoder,
|
||||
CompressedVideoSource *video,
|
||||
const vpx_codec_err_t res_peek);
|
||||
|
||||
protected:
|
||||
explicit DecoderTest(const CodecFactory *codec)
|
||||
: codec_(codec), cfg_(), flags_(0) {}
|
||||
|
||||
virtual ~DecoderTest() {}
|
||||
|
||||
const CodecFactory *codec_;
|
||||
vpx_codec_dec_cfg_t cfg_;
|
||||
vpx_codec_flags_t flags_;
|
||||
};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // VPX_TEST_DECODE_TEST_DRIVER_H_
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file tests the libvpx decode_to_md5 example. To add new tests to this
|
||||
## file, do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to decode_to_md5_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: Make sure input is available:
|
||||
# $VP8_IVF_FILE and $VP9_IVF_FILE are required.
|
||||
decode_to_md5_verify_environment() {
|
||||
if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs decode_to_md5 on $1 and captures the md5 sum for the final frame. $2 is
|
||||
# interpreted as codec name and used solely to name the output file. $3 is the
|
||||
# expected md5 sum: It must match that of the final frame.
|
||||
decode_to_md5() {
|
||||
local decoder="${LIBVPX_BIN_PATH}/decode_to_md5${VPX_TEST_EXE_SUFFIX}"
|
||||
local input_file="$1"
|
||||
local codec="$2"
|
||||
local expected_md5="$3"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/decode_to_md5_${codec}"
|
||||
|
||||
if [ ! -x "${decoder}" ]; then
|
||||
elog "${decoder} does not exist or is not executable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
|
||||
${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
|
||||
local md5_last_frame="$(tail -n1 "${output_file}" | awk '{print $1}')"
|
||||
local actual_md5="$(echo "${md5_last_frame}" | awk '{print $1}')"
|
||||
[ "${actual_md5}" = "${expected_md5}" ] || return 1
|
||||
}
|
||||
|
||||
decode_to_md5_vp8() {
|
||||
# expected MD5 sum for the last frame.
|
||||
local expected_md5="56794d911b02190212bca92f88ad60c6"
|
||||
|
||||
if [ "$(vp8_decode_available)" = "yes" ]; then
|
||||
decode_to_md5 "${VP8_IVF_FILE}" "vp8" "${expected_md5}"
|
||||
fi
|
||||
}
|
||||
|
||||
decode_to_md5_vp9() {
|
||||
# expected MD5 sum for the last frame.
|
||||
local expected_md5="2952c0eae93f3dadd1aa84c50d3fd6d2"
|
||||
|
||||
if [ "$(vp9_decode_available)" = "yes" ]; then
|
||||
decode_to_md5 "${VP9_IVF_FILE}" "vp9" "${expected_md5}"
|
||||
fi
|
||||
}
|
||||
|
||||
decode_to_md5_tests="decode_to_md5_vp8
|
||||
decode_to_md5_vp9"
|
||||
|
||||
run_tests decode_to_md5_verify_environment "${decode_to_md5_tests}"
|
||||
@@ -0,0 +1,79 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file tests the libvpx decode_with_drops example. To add new tests to
|
||||
## this file, do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to decode_with_drops_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: Make sure input is available:
|
||||
# $VP8_IVF_FILE and $VP9_IVF_FILE are required.
|
||||
decode_with_drops_verify_environment() {
|
||||
if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs decode_with_drops on $1, $2 is interpreted as codec name and used solely
|
||||
# to name the output file. $3 is the drop mode, and is passed directly to
|
||||
# decode_with_drops.
|
||||
decode_with_drops() {
|
||||
local decoder="${LIBVPX_BIN_PATH}/decode_with_drops${VPX_TEST_EXE_SUFFIX}"
|
||||
local input_file="$1"
|
||||
local codec="$2"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/decode_with_drops_${codec}"
|
||||
local drop_mode="$3"
|
||||
|
||||
if [ ! -x "${decoder}" ]; then
|
||||
elog "${decoder} does not exist or is not executable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
|
||||
"${drop_mode}" ${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
}
|
||||
|
||||
# Decodes $VP8_IVF_FILE while dropping frames, twice: once in sequence mode,
|
||||
# and once in pattern mode.
|
||||
# Note: This test assumes that $VP8_IVF_FILE has exactly 29 frames, and could
|
||||
# break if the file is modified.
|
||||
decode_with_drops_vp8() {
|
||||
if [ "$(vp8_decode_available)" = "yes" ]; then
|
||||
# Test sequence mode: Drop frames 2-28.
|
||||
decode_with_drops "${VP8_IVF_FILE}" "vp8" "2-28"
|
||||
|
||||
# Test pattern mode: Drop 3 of every 4 frames.
|
||||
decode_with_drops "${VP8_IVF_FILE}" "vp8" "3/4"
|
||||
fi
|
||||
}
|
||||
|
||||
# Decodes $VP9_IVF_FILE while dropping frames, twice: once in sequence mode,
|
||||
# and once in pattern mode.
|
||||
# Note: This test assumes that $VP9_IVF_FILE has exactly 20 frames, and could
|
||||
# break if the file is modified.
|
||||
decode_with_drops_vp9() {
|
||||
if [ "$(vp9_decode_available)" = "yes" ]; then
|
||||
# Test sequence mode: Drop frames 2-28.
|
||||
decode_with_drops "${VP9_IVF_FILE}" "vp9" "2-19"
|
||||
|
||||
# Test pattern mode: Drop 3 of every 4 frames.
|
||||
decode_with_drops "${VP9_IVF_FILE}" "vp9" "3/4"
|
||||
fi
|
||||
}
|
||||
|
||||
decode_with_drops_tests="decode_with_drops_vp8
|
||||
decode_with_drops_vp9"
|
||||
|
||||
run_tests decode_with_drops_verify_environment "${decode_with_drops_tests}"
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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 "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
|
||||
|
||||
TEST(EncodeAPI, InvalidParams) {
|
||||
static const vpx_codec_iface_t *kCodecs[] = {
|
||||
#if CONFIG_VP8_ENCODER
|
||||
&vpx_codec_vp8_cx_algo,
|
||||
#endif
|
||||
#if CONFIG_VP9_ENCODER
|
||||
&vpx_codec_vp9_cx_algo,
|
||||
#endif
|
||||
};
|
||||
uint8_t buf[1] = { 0 };
|
||||
vpx_image_t img;
|
||||
vpx_codec_ctx_t enc;
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
|
||||
EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf));
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(NULL, NULL, NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(&enc, NULL, NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, NULL, 0, 0, 0, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, &img, 0, 0, 0, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_enc_config_default(NULL, NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_enc_config_default(NULL, &cfg, 0));
|
||||
EXPECT_TRUE(vpx_codec_error(NULL) != NULL);
|
||||
|
||||
for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
|
||||
SCOPED_TRACE(vpx_codec_iface_name(kCodecs[i]));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_enc_init(NULL, kCodecs[i], NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_enc_init(&enc, kCodecs[i], NULL, 0));
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_enc_config_default(kCodecs[i], &cfg, 1));
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(kCodecs[i], &cfg, 0));
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, kCodecs[i], &cfg, 0));
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, NULL, 0, 0, 0, 0));
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodeAPI, HighBitDepthCapability) {
|
||||
// VP8 should not claim VP9 HBD as a capability.
|
||||
#if CONFIG_VP8_ENCODER
|
||||
const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo);
|
||||
EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
|
||||
#else
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_VP8_ENCODER
|
||||
TEST(EncodeAPI, ImageSizeSetting) {
|
||||
const int width = 711;
|
||||
const int height = 360;
|
||||
const int bps = 12;
|
||||
vpx_image_t img;
|
||||
vpx_codec_ctx_t enc;
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
uint8_t *img_buf = reinterpret_cast<uint8_t *>(
|
||||
calloc(width * height * bps / 8, sizeof(*img_buf)));
|
||||
vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0);
|
||||
|
||||
cfg.g_w = width;
|
||||
cfg.g_h = height;
|
||||
|
||||
vpx_img_wrap(&img, VPX_IMG_FMT_I420, width, height, 1, img_buf);
|
||||
|
||||
vpx_codec_enc_init(&enc, vpx_codec_vp8_cx(), &cfg, 0);
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, &img, 0, 1, 0, 0));
|
||||
|
||||
free(img_buf);
|
||||
|
||||
vpx_codec_destroy(&enc);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set up 2 spatial streams with 2 temporal layers per stream, and generate
|
||||
// invalid configuration by setting the temporal layer rate allocation
|
||||
// (ts_target_bitrate[]) to 0 for both layers. This should fail independent of
|
||||
// CONFIG_MULTI_RES_ENCODING.
|
||||
TEST(EncodeAPI, MultiResEncode) {
|
||||
static const vpx_codec_iface_t *kCodecs[] = {
|
||||
#if CONFIG_VP8_ENCODER
|
||||
&vpx_codec_vp8_cx_algo,
|
||||
#endif
|
||||
#if CONFIG_VP9_ENCODER
|
||||
&vpx_codec_vp9_cx_algo,
|
||||
#endif
|
||||
};
|
||||
const int width = 1280;
|
||||
const int height = 720;
|
||||
const int width_down = width / 2;
|
||||
const int height_down = height / 2;
|
||||
const int target_bitrate = 1000;
|
||||
const int framerate = 30;
|
||||
|
||||
for (int c = 0; c < NELEMENTS(kCodecs); ++c) {
|
||||
const vpx_codec_iface_t *const iface = kCodecs[c];
|
||||
vpx_codec_ctx_t enc[2];
|
||||
vpx_codec_enc_cfg_t cfg[2];
|
||||
vpx_rational_t dsf[2] = { { 2, 1 }, { 2, 1 } };
|
||||
|
||||
memset(enc, 0, sizeof(enc));
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
vpx_codec_enc_config_default(iface, &cfg[i], 0);
|
||||
}
|
||||
|
||||
/* Highest-resolution encoder settings */
|
||||
cfg[0].g_w = width;
|
||||
cfg[0].g_h = height;
|
||||
cfg[0].rc_dropframe_thresh = 0;
|
||||
cfg[0].rc_end_usage = VPX_CBR;
|
||||
cfg[0].rc_resize_allowed = 0;
|
||||
cfg[0].rc_min_quantizer = 2;
|
||||
cfg[0].rc_max_quantizer = 56;
|
||||
cfg[0].rc_undershoot_pct = 100;
|
||||
cfg[0].rc_overshoot_pct = 15;
|
||||
cfg[0].rc_buf_initial_sz = 500;
|
||||
cfg[0].rc_buf_optimal_sz = 600;
|
||||
cfg[0].rc_buf_sz = 1000;
|
||||
cfg[0].g_error_resilient = 1; /* Enable error resilient mode */
|
||||
cfg[0].g_lag_in_frames = 0;
|
||||
|
||||
cfg[0].kf_mode = VPX_KF_AUTO;
|
||||
cfg[0].kf_min_dist = 3000;
|
||||
cfg[0].kf_max_dist = 3000;
|
||||
|
||||
cfg[0].rc_target_bitrate = target_bitrate; /* Set target bitrate */
|
||||
cfg[0].g_timebase.num = 1; /* Set fps */
|
||||
cfg[0].g_timebase.den = framerate;
|
||||
|
||||
memcpy(&cfg[1], &cfg[0], sizeof(cfg[0]));
|
||||
cfg[1].rc_target_bitrate = 500;
|
||||
cfg[1].g_w = width_down;
|
||||
cfg[1].g_h = height_down;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
cfg[i].ts_number_layers = 2;
|
||||
cfg[i].ts_periodicity = 2;
|
||||
cfg[i].ts_rate_decimator[0] = 2;
|
||||
cfg[i].ts_rate_decimator[1] = 1;
|
||||
cfg[i].ts_layer_id[0] = 0;
|
||||
cfg[i].ts_layer_id[1] = 1;
|
||||
// Invalid parameters.
|
||||
cfg[i].ts_target_bitrate[0] = 0;
|
||||
cfg[i].ts_target_bitrate[1] = 0;
|
||||
}
|
||||
|
||||
// VP9 should report incapable, VP8 invalid for all configurations.
|
||||
const char kVP9Name[] = "WebM Project VP9";
|
||||
const bool is_vp9 = strncmp(kVP9Name, vpx_codec_iface_name(iface),
|
||||
sizeof(kVP9Name) - 1) == 0;
|
||||
EXPECT_EQ(is_vp9 ? VPX_CODEC_INCAPABLE : VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_enc_init_multi(&enc[0], iface, &cfg[0], 2, 0, &dsf[0]));
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
vpx_codec_destroy(&enc[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <string>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_version.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/encode_test_driver.h"
|
||||
#include "test/i420_video_source.h"
|
||||
#include "test/util.h"
|
||||
#include "test/y4m_video_source.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const int kMaxPsnr = 100;
|
||||
const double kUsecsInSec = 1000000.0;
|
||||
|
||||
struct EncodePerfTestVideo {
|
||||
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
||||
uint32_t bitrate_, int frames_)
|
||||
: name(name_), width(width_), height(height_), bitrate(bitrate_),
|
||||
frames(frames_) {}
|
||||
const char *name;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t bitrate;
|
||||
int frames;
|
||||
};
|
||||
|
||||
const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
|
||||
EncodePerfTestVideo("desktop_640_360_30.yuv", 640, 360, 200, 2484),
|
||||
EncodePerfTestVideo("kirland_640_480_30.yuv", 640, 480, 200, 300),
|
||||
EncodePerfTestVideo("macmarcomoving_640_480_30.yuv", 640, 480, 200, 987),
|
||||
EncodePerfTestVideo("macmarcostationary_640_480_30.yuv", 640, 480, 200, 718),
|
||||
EncodePerfTestVideo("niklas_640_480_30.yuv", 640, 480, 200, 471),
|
||||
EncodePerfTestVideo("tacomanarrows_640_480_30.yuv", 640, 480, 200, 300),
|
||||
EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv", 640, 480, 200,
|
||||
300),
|
||||
EncodePerfTestVideo("thaloundeskmtg_640_480_30.yuv", 640, 480, 200, 300),
|
||||
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
|
||||
};
|
||||
|
||||
const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8, 9 };
|
||||
const int kEncodePerfTestThreads[] = { 1, 2, 4 };
|
||||
|
||||
#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
|
||||
class VP9EncodePerfTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
protected:
|
||||
VP9EncodePerfTest()
|
||||
: EncoderTest(GET_PARAM(0)), min_psnr_(kMaxPsnr), nframes_(0),
|
||||
encoding_mode_(GET_PARAM(1)), speed_(0), threads_(1) {}
|
||||
|
||||
virtual ~VP9EncodePerfTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_undershoot_pct = 50;
|
||||
cfg_.rc_overshoot_pct = 50;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 600;
|
||||
cfg_.rc_resize_allowed = 0;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.g_threads = threads_;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
const int log2_tile_columns = 3;
|
||||
encoder->Control(VP8E_SET_CPUUSED, speed_);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, log2_tile_columns);
|
||||
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
min_psnr_ = kMaxPsnr;
|
||||
nframes_ = 0;
|
||||
}
|
||||
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
if (pkt->data.psnr.psnr[0] < min_psnr_) {
|
||||
min_psnr_ = pkt->data.psnr.psnr[0];
|
||||
}
|
||||
}
|
||||
|
||||
// for performance reasons don't decode
|
||||
virtual bool DoDecode() const { return false; }
|
||||
|
||||
double min_psnr() const { return min_psnr_; }
|
||||
|
||||
void set_speed(unsigned int speed) { speed_ = speed; }
|
||||
|
||||
void set_threads(unsigned int threads) { threads_ = threads; }
|
||||
|
||||
private:
|
||||
double min_psnr_;
|
||||
unsigned int nframes_;
|
||||
libvpx_test::TestMode encoding_mode_;
|
||||
unsigned speed_;
|
||||
unsigned int threads_;
|
||||
};
|
||||
|
||||
TEST_P(VP9EncodePerfTest, PerfTest) {
|
||||
for (size_t i = 0; i < NELEMENTS(kVP9EncodePerfTestVectors); ++i) {
|
||||
for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
|
||||
for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) {
|
||||
if (kVP9EncodePerfTestVectors[i].width < 512 &&
|
||||
kEncodePerfTestThreads[k] > 1) {
|
||||
continue;
|
||||
} else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
|
||||
kEncodePerfTestThreads[k] > 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
set_threads(kEncodePerfTestThreads[k]);
|
||||
SetUp();
|
||||
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
const unsigned frames = kVP9EncodePerfTestVectors[i].frames;
|
||||
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
||||
libvpx_test::I420VideoSource video(
|
||||
video_name, kVP9EncodePerfTestVectors[i].width,
|
||||
kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
|
||||
kVP9EncodePerfTestVectors[i].frames);
|
||||
set_speed(kEncodePerfTestSpeeds[j]);
|
||||
|
||||
vpx_usec_timer t;
|
||||
vpx_usec_timer_start(&t);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
vpx_usec_timer_mark(&t);
|
||||
const double elapsed_secs = vpx_usec_timer_elapsed(&t) / kUsecsInSec;
|
||||
const double fps = frames / elapsed_secs;
|
||||
const double minimum_psnr = min_psnr();
|
||||
std::string display_name(video_name);
|
||||
if (kEncodePerfTestThreads[k] > 1) {
|
||||
char thread_count[32];
|
||||
snprintf(thread_count, sizeof(thread_count), "_t-%d",
|
||||
kEncodePerfTestThreads[k]);
|
||||
display_name += thread_count;
|
||||
}
|
||||
|
||||
printf("{\n");
|
||||
printf("\t\"type\" : \"encode_perf_test\",\n");
|
||||
printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
|
||||
printf("\t\"videoName\" : \"%s\",\n", display_name.c_str());
|
||||
printf("\t\"encodeTimeSecs\" : %f,\n", elapsed_secs);
|
||||
printf("\t\"totalFrames\" : %u,\n", frames);
|
||||
printf("\t\"framesPerSecond\" : %f,\n", fps);
|
||||
printf("\t\"minPsnr\" : %f,\n", minimum_psnr);
|
||||
printf("\t\"speed\" : %d,\n", kEncodePerfTestSpeeds[j]);
|
||||
printf("\t\"threads\" : %d\n", kEncodePerfTestThreads[k]);
|
||||
printf("}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(VP9EncodePerfTest,
|
||||
::testing::Values(::libvpx_test::kRealTime));
|
||||
} // namespace
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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 <memory>
|
||||
#include <string>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/encode_test_driver.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/video_source.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
void Encoder::InitEncoder(VideoSource *video) {
|
||||
vpx_codec_err_t res;
|
||||
const vpx_image_t *img = video->img();
|
||||
|
||||
if (video->img() && !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_, CodecInterface(), &cfg_, init_flags_);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
if (CodecInterface() == &vpx_codec_vp9_cx_algo) {
|
||||
// Default to 1 tile column for VP9.
|
||||
const int log2_tile_columns = 0;
|
||||
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
|
||||
log2_tile_columns);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if CONFIG_VP8_ENCODER
|
||||
ASSERT_EQ(&vpx_codec_vp8_cx_algo, CodecInterface())
|
||||
<< "Unknown Codec Interface";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) {
|
||||
if (video->img()) {
|
||||
EncodeFrameInternal(*video, frame_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,
|
||||
const unsigned long frame_flags) {
|
||||
vpx_codec_err_t res;
|
||||
const vpx_image_t *img = video.img();
|
||||
|
||||
// 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
|
||||
API_REGISTER_STATE_CHECK(res = vpx_codec_encode(&encoder_, img, video.pts(),
|
||||
video.duration(), frame_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_);
|
||||
if (!encoder_.priv)
|
||||
ASSERT_EQ(VPX_CODEC_ERROR, res) << EncoderError();
|
||||
else
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void EncoderTest::InitializeConfig() {
|
||||
const vpx_codec_err_t res = codec_->DefaultEncoderConfig(&cfg_, 0);
|
||||
dec_cfg_ = vpx_codec_dec_cfg_t();
|
||||
ASSERT_EQ(VPX_CODEC_OK, res);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// The function should return "true" most of the time, therefore no early
|
||||
// break-out is implemented within the match checking process.
|
||||
static bool compare_img(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||
bool match = (img1->fmt == img2->fmt) && (img1->cs == img2->cs) &&
|
||||
(img1->d_w == img2->d_w) && (img1->d_h == img2->d_h);
|
||||
|
||||
if (!match) return false;
|
||||
|
||||
const unsigned int width_y = img1->d_w;
|
||||
const unsigned int height_y = img1->d_h;
|
||||
unsigned int i;
|
||||
for (i = 0; i < height_y; ++i) {
|
||||
match = (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
|
||||
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
|
||||
width_y) == 0) &&
|
||||
match;
|
||||
}
|
||||
const unsigned int width_uv = (img1->d_w + 1) >> 1;
|
||||
const unsigned int height_uv = (img1->d_h + 1) >> 1;
|
||||
for (i = 0; i < height_uv; ++i) {
|
||||
match = (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
|
||||
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
|
||||
width_uv) == 0) &&
|
||||
match;
|
||||
}
|
||||
for (i = 0; i < height_uv; ++i) {
|
||||
match = (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
|
||||
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
|
||||
width_uv) == 0) &&
|
||||
match;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
void EncoderTest::MismatchHook(const vpx_image_t * /*img1*/,
|
||||
const vpx_image_t * /*img2*/) {
|
||||
ASSERT_TRUE(0) << "Encode/Decode mismatch found";
|
||||
}
|
||||
|
||||
void EncoderTest::RunLoop(VideoSource *video) {
|
||||
vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
|
||||
|
||||
stats_.Reset();
|
||||
|
||||
ASSERT_TRUE(passes_ == 1 || passes_ == 2);
|
||||
for (unsigned int pass = 0; pass < passes_; pass++) {
|
||||
last_pts_ = 0;
|
||||
|
||||
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);
|
||||
std::unique_ptr<Encoder> encoder(
|
||||
codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_));
|
||||
ASSERT_TRUE(encoder.get() != NULL);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(video->Begin());
|
||||
encoder->InitEncoder(video);
|
||||
ASSERT_FALSE(::testing::Test::HasFatalFailure());
|
||||
|
||||
unsigned long dec_init_flags = 0; // NOLINT
|
||||
// Use fragment decoder if encoder outputs partitions.
|
||||
// NOTE: fragment decoder and partition encoder are only supported by VP8.
|
||||
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) {
|
||||
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
|
||||
}
|
||||
std::unique_ptr<Decoder> decoder(
|
||||
codec_->CreateDecoder(dec_cfg, dec_init_flags));
|
||||
bool again;
|
||||
for (again = true; again; video->Next()) {
|
||||
again = (video->img() != NULL);
|
||||
|
||||
PreEncodeFrameHook(video);
|
||||
PreEncodeFrameHook(video, encoder.get());
|
||||
encoder->EncodeFrame(video, frame_flags_);
|
||||
|
||||
PostEncodeFrameHook(encoder.get());
|
||||
|
||||
CxDataIterator iter = encoder->GetCxData();
|
||||
|
||||
bool has_cxdata = false;
|
||||
bool has_dxdata = false;
|
||||
while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
|
||||
pkt = MutateEncoderOutputHook(pkt);
|
||||
again = true;
|
||||
switch (pkt->kind) {
|
||||
case VPX_CODEC_CX_FRAME_PKT:
|
||||
has_cxdata = true;
|
||||
if (decoder.get() != NULL && DoDecode()) {
|
||||
PreDecodeFrameHook(video, decoder.get());
|
||||
vpx_codec_err_t res_dec = decoder->DecodeFrame(
|
||||
(const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz);
|
||||
|
||||
if (!HandleDecodeResult(res_dec, *video, decoder.get())) break;
|
||||
|
||||
has_dxdata = true;
|
||||
}
|
||||
ASSERT_GE(pkt->data.frame.pts, last_pts_);
|
||||
last_pts_ = pkt->data.frame.pts;
|
||||
FramePktHook(pkt);
|
||||
break;
|
||||
|
||||
case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;
|
||||
|
||||
case VPX_CODEC_STATS_PKT: StatsPktHook(pkt); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush the decoder when there are no more fragments.
|
||||
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
|
||||
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
||||
if (!HandleDecodeResult(res_dec, *video, decoder.get())) break;
|
||||
}
|
||||
|
||||
if (has_dxdata && has_cxdata) {
|
||||
const vpx_image_t *img_enc = encoder->GetPreviewFrame();
|
||||
DxDataIterator dec_iter = decoder->GetDxData();
|
||||
const vpx_image_t *img_dec = dec_iter.Next();
|
||||
if (img_enc && img_dec) {
|
||||
const bool res = compare_img(img_enc, img_dec);
|
||||
if (!res) { // Mismatch
|
||||
MismatchHook(img_enc, img_dec);
|
||||
}
|
||||
}
|
||||
if (img_dec) DecompressedFrameHook(*img_dec, video->pts());
|
||||
}
|
||||
if (!Continue()) break;
|
||||
}
|
||||
|
||||
EndPassHook();
|
||||
|
||||
if (!Continue()) break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace libvpx_test
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* 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 VPX_TEST_ENCODE_TEST_DRIVER_H_
|
||||
#define VPX_TEST_ENCODE_TEST_DRIVER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||
#include "vpx/vp8cx.h"
|
||||
#endif
|
||||
#include "vpx/vpx_encoder.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
class CodecFactory;
|
||||
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)
|
||||
|
||||
#define ONE_PASS_TEST_MODES \
|
||||
::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \
|
||||
::libvpx_test::kOnePassBest)
|
||||
|
||||
#define TWO_PASS_TEST_MODES \
|
||||
::testing::Values(::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;
|
||||
}
|
||||
|
||||
void Reset() { buffer_.clear(); }
|
||||
|
||||
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,
|
||||
const unsigned long init_flags, TwopassStatsStore *stats)
|
||||
: cfg_(cfg), deadline_(deadline), init_flags_(init_flags), stats_(stats) {
|
||||
memset(&encoder_, 0, sizeof(encoder_));
|
||||
}
|
||||
|
||||
virtual ~Encoder() { vpx_codec_destroy(&encoder_); }
|
||||
|
||||
CxDataIterator GetCxData() { return CxDataIterator(&encoder_); }
|
||||
|
||||
void InitEncoder(VideoSource *video);
|
||||
|
||||
const vpx_image_t *GetPreviewFrame() {
|
||||
return vpx_codec_get_preview_frame(&encoder_);
|
||||
}
|
||||
// This is a thin wrapper around vpx_codec_encode(), so refer to
|
||||
// vpx_encoder.h for its semantics.
|
||||
void EncodeFrame(VideoSource *video, const unsigned long frame_flags);
|
||||
|
||||
// Convenience wrapper for EncodeFrame()
|
||||
void EncodeFrame(VideoSource *video) { EncodeFrame(video, 0); }
|
||||
|
||||
void Control(int ctrl_id, int arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, int *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_scaling_mode *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_layer_id *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_ref_frame_config *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_parameters *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_frame_drop *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_spatial_layer_sync *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||
void Control(int ctrl_id, vpx_active_map_t *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, vpx_roi_map_t *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
#endif
|
||||
void Config(const vpx_codec_enc_cfg_t *cfg) {
|
||||
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
cfg_ = *cfg;
|
||||
}
|
||||
|
||||
void set_deadline(unsigned long deadline) { deadline_ = deadline; }
|
||||
|
||||
protected:
|
||||
virtual vpx_codec_iface_t *CodecInterface() const = 0;
|
||||
|
||||
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,
|
||||
const unsigned long frame_flags);
|
||||
|
||||
// Flush the encoder on EOS
|
||||
void Flush();
|
||||
|
||||
vpx_codec_ctx_t encoder_;
|
||||
vpx_codec_enc_cfg_t cfg_;
|
||||
unsigned long deadline_;
|
||||
unsigned long init_flags_;
|
||||
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:
|
||||
explicit EncoderTest(const CodecFactory *codec)
|
||||
: codec_(codec), abort_(false), init_flags_(0), frame_flags_(0),
|
||||
last_pts_(0) {
|
||||
// Default to 1 thread.
|
||||
cfg_.g_threads = 1;
|
||||
}
|
||||
|
||||
virtual ~EncoderTest() {}
|
||||
|
||||
// Initialize the cfg_ member with the default configuration.
|
||||
void InitializeConfig();
|
||||
|
||||
// Map the TestMode enum to the deadline_ and passes_ variables.
|
||||
void SetMode(TestMode mode);
|
||||
|
||||
// Set encoder flag.
|
||||
void set_init_flags(unsigned long flag) { // NOLINT(runtime/int)
|
||||
init_flags_ = flag;
|
||||
}
|
||||
|
||||
// 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*/) {}
|
||||
virtual void PreEncodeFrameHook(VideoSource * /*video*/,
|
||||
Encoder * /*encoder*/) {}
|
||||
|
||||
virtual void PreDecodeFrameHook(VideoSource * /*video*/,
|
||||
Decoder * /*decoder*/) {}
|
||||
|
||||
virtual void PostEncodeFrameHook(Encoder * /*encoder*/) {}
|
||||
|
||||
// Hook to be called on every compressed data packet.
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||
|
||||
// Hook to be called on every PSNR packet.
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||
|
||||
// Hook to be called on every first pass stats packet.
|
||||
virtual void StatsPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||
|
||||
// Hook to determine whether the encode loop should continue.
|
||||
virtual bool Continue() const {
|
||||
return !(::testing::Test::HasFatalFailure() || abort_);
|
||||
}
|
||||
|
||||
const CodecFactory *codec_;
|
||||
// Hook to determine whether to decode frame after encoding
|
||||
virtual bool DoDecode() const { return 1; }
|
||||
|
||||
// Hook to handle encode/decode mismatch
|
||||
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2);
|
||||
|
||||
// Hook to be called on every decompressed frame.
|
||||
virtual void DecompressedFrameHook(const vpx_image_t & /*img*/,
|
||||
vpx_codec_pts_t /*pts*/) {}
|
||||
|
||||
// Hook to be called to handle decode result. Return true to continue.
|
||||
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
|
||||
const VideoSource & /*video*/,
|
||||
Decoder *decoder) {
|
||||
EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
|
||||
return VPX_CODEC_OK == res_dec;
|
||||
}
|
||||
|
||||
// Hook that can modify the encoder's output data
|
||||
virtual const vpx_codec_cx_pkt_t *MutateEncoderOutputHook(
|
||||
const vpx_codec_cx_pkt_t *pkt) {
|
||||
return pkt;
|
||||
}
|
||||
|
||||
bool abort_;
|
||||
vpx_codec_enc_cfg_t cfg_;
|
||||
vpx_codec_dec_cfg_t dec_cfg_;
|
||||
unsigned int passes_;
|
||||
unsigned long deadline_;
|
||||
TwopassStatsStore stats_;
|
||||
unsigned long init_flags_;
|
||||
unsigned long frame_flags_;
|
||||
vpx_codec_pts_t last_pts_;
|
||||
};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // VPX_TEST_ENCODE_TEST_DRIVER_H_
|
||||
@@ -0,0 +1,582 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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 {
|
||||
|
||||
const int kMaxErrorFrames = 12;
|
||||
const int kMaxDroppableFrames = 12;
|
||||
|
||||
class ErrorResilienceTestLarge
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> {
|
||||
protected:
|
||||
ErrorResilienceTestLarge()
|
||||
: EncoderTest(GET_PARAM(0)), svc_support_(GET_PARAM(2)), psnr_(0.0),
|
||||
nframes_(0), mismatch_psnr_(0.0), mismatch_nframes_(0),
|
||||
encoding_mode_(GET_PARAM(1)) {
|
||||
Reset();
|
||||
}
|
||||
|
||||
virtual ~ErrorResilienceTestLarge() {}
|
||||
|
||||
void Reset() {
|
||||
error_nframes_ = 0;
|
||||
droppable_nframes_ = 0;
|
||||
pattern_switch_ = 0;
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
psnr_ = 0.0;
|
||||
nframes_ = 0;
|
||||
mismatch_psnr_ = 0.0;
|
||||
mismatch_nframes_ = 0;
|
||||
}
|
||||
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
psnr_ += pkt->data.psnr.psnr[0];
|
||||
nframes_++;
|
||||
}
|
||||
|
||||
//
|
||||
// Frame flags and layer id for temporal layers.
|
||||
// For two layers, test pattern is:
|
||||
// 1 3
|
||||
// 0 2 .....
|
||||
// LAST is updated on base/layer 0, GOLDEN updated on layer 1.
|
||||
// Non-zero pattern_switch parameter means pattern will switch to
|
||||
// not using LAST for frame_num >= pattern_switch.
|
||||
int SetFrameFlags(int frame_num, int num_temp_layers, int pattern_switch) {
|
||||
int frame_flags = 0;
|
||||
if (num_temp_layers == 2) {
|
||||
if (frame_num % 2 == 0) {
|
||||
if (frame_num < pattern_switch || pattern_switch == 0) {
|
||||
// Layer 0: predict from LAST and ARF, update LAST.
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||
} else {
|
||||
// Layer 0: predict from GF and ARF, update GF.
|
||||
frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
|
||||
VP8_EFLAG_NO_UPD_ARF;
|
||||
}
|
||||
} else {
|
||||
if (frame_num < pattern_switch || pattern_switch == 0) {
|
||||
// Layer 1: predict from L, GF, and ARF, update GF.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||
} else {
|
||||
// Layer 1: predict from GF and ARF, update GF.
|
||||
frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
|
||||
VP8_EFLAG_NO_UPD_ARF;
|
||||
}
|
||||
}
|
||||
}
|
||||
return frame_flags;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
|
||||
frame_flags_ &=
|
||||
~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF);
|
||||
// For temporal layer case.
|
||||
if (cfg_.ts_number_layers > 1) {
|
||||
frame_flags_ =
|
||||
SetFrameFlags(video->frame(), cfg_.ts_number_layers, pattern_switch_);
|
||||
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
||||
if (droppable_frames_[i] == video->frame()) {
|
||||
std::cout << "Encoding droppable frame: " << droppable_frames_[i]
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (droppable_nframes_ > 0 &&
|
||||
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
|
||||
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
||||
if (droppable_frames_[i] == video->frame()) {
|
||||
std::cout << "Encoding droppable frame: " << droppable_frames_[i]
|
||||
<< "\n";
|
||||
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
||||
VP8_EFLAG_NO_UPD_ARF);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double GetAveragePsnr() const {
|
||||
if (nframes_) return psnr_ / nframes_;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double GetAverageMismatchPsnr() const {
|
||||
if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
virtual bool DoDecode() const {
|
||||
if (error_nframes_ > 0 &&
|
||||
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
|
||||
for (unsigned int i = 0; i < error_nframes_; ++i) {
|
||||
if (error_frames_[i] == nframes_ - 1) {
|
||||
std::cout << " Skipping decoding frame: "
|
||||
<< error_frames_[i] << "\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||
double mismatch_psnr = compute_psnr(img1, img2);
|
||||
mismatch_psnr_ += mismatch_psnr;
|
||||
++mismatch_nframes_;
|
||||
// std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
|
||||
}
|
||||
|
||||
void SetErrorFrames(int num, unsigned int *list) {
|
||||
if (num > kMaxErrorFrames) {
|
||||
num = kMaxErrorFrames;
|
||||
} else if (num < 0) {
|
||||
num = 0;
|
||||
}
|
||||
error_nframes_ = num;
|
||||
for (unsigned int i = 0; i < error_nframes_; ++i) {
|
||||
error_frames_[i] = list[i];
|
||||
}
|
||||
}
|
||||
|
||||
void SetDroppableFrames(int num, unsigned int *list) {
|
||||
if (num > kMaxDroppableFrames) {
|
||||
num = kMaxDroppableFrames;
|
||||
} else if (num < 0) {
|
||||
num = 0;
|
||||
}
|
||||
droppable_nframes_ = num;
|
||||
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
||||
droppable_frames_[i] = list[i];
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
|
||||
|
||||
void SetPatternSwitch(int frame_switch) { pattern_switch_ = frame_switch; }
|
||||
|
||||
bool svc_support_;
|
||||
|
||||
private:
|
||||
double psnr_;
|
||||
unsigned int nframes_;
|
||||
unsigned int error_nframes_;
|
||||
unsigned int droppable_nframes_;
|
||||
unsigned int pattern_switch_;
|
||||
double mismatch_psnr_;
|
||||
unsigned int mismatch_nframes_;
|
||||
unsigned int error_frames_[kMaxErrorFrames];
|
||||
unsigned int droppable_frames_[kMaxDroppableFrames];
|
||||
libvpx_test::TestMode encoding_mode_;
|
||||
};
|
||||
|
||||
TEST_P(ErrorResilienceTestLarge, OnVersusOff) {
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = 2000;
|
||||
cfg_.g_lag_in_frames = 10;
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
timebase.den, timebase.num, 0, 30);
|
||||
|
||||
// Error resilient mode OFF.
|
||||
cfg_.g_error_resilient = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const double psnr_resilience_off = GetAveragePsnr();
|
||||
EXPECT_GT(psnr_resilience_off, 25.0);
|
||||
|
||||
// Error resilient mode ON.
|
||||
cfg_.g_error_resilient = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const double psnr_resilience_on = GetAveragePsnr();
|
||||
EXPECT_GT(psnr_resilience_on, 25.0);
|
||||
|
||||
// Test that turning on error resilient mode hurts by 10% at most.
|
||||
if (psnr_resilience_off > 0.0) {
|
||||
const double psnr_ratio = psnr_resilience_on / psnr_resilience_off;
|
||||
EXPECT_GE(psnr_ratio, 0.9);
|
||||
EXPECT_LE(psnr_ratio, 1.1);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for successful decoding and no encoder/decoder mismatch
|
||||
// if we lose (i.e., drop before decoding) a set of droppable
|
||||
// frames (i.e., frames that don't update any reference buffers).
|
||||
// Check both isolated and consecutive loss.
|
||||
TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = 500;
|
||||
// FIXME(debargha): Fix this to work for any lag.
|
||||
// Currently this test only works for lag = 0
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
timebase.den, timebase.num, 0, 40);
|
||||
|
||||
// Error resilient mode ON.
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||
|
||||
// Set an arbitrary set of error frames same as droppable frames.
|
||||
// In addition to isolated loss/drop, add a long consecutive series
|
||||
// (of size 9) of dropped frames.
|
||||
unsigned int num_droppable_frames = 11;
|
||||
unsigned int droppable_frame_list[] = { 5, 16, 22, 23, 24, 25,
|
||||
26, 27, 28, 29, 30 };
|
||||
SetDroppableFrames(num_droppable_frames, droppable_frame_list);
|
||||
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
// Test that no mismatches have been found
|
||||
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
||||
|
||||
// Reset previously set of error/droppable frames.
|
||||
Reset();
|
||||
|
||||
#if 0
|
||||
// TODO(jkoleszar): This test is disabled for the time being as too
|
||||
// sensitive. It's not clear how to set a reasonable threshold for
|
||||
// this behavior.
|
||||
|
||||
// Now set an arbitrary set of error frames that are non-droppable
|
||||
unsigned int num_error_frames = 3;
|
||||
unsigned int error_frame_list[] = {3, 10, 20};
|
||||
SetErrorFrames(num_error_frames, error_frame_list);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
// Test that dropping an arbitrary set of inter frames does not hurt too much
|
||||
// Note the Average Mismatch PSNR is the average of the PSNR between
|
||||
// decoded frame and encoder's version of the same frame for all frames
|
||||
// with mismatch.
|
||||
const double psnr_resilience_mismatch = GetAverageMismatchPsnr();
|
||||
std::cout << " Mismatch PSNR: "
|
||||
<< psnr_resilience_mismatch << "\n";
|
||||
EXPECT_GT(psnr_resilience_mismatch, 20.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check for successful decoding and no encoder/decoder mismatch
|
||||
// if we lose (i.e., drop before decoding) the enhancement layer frames for a
|
||||
// two layer temporal pattern. The base layer does not predict from the top
|
||||
// layer, so successful decoding is expected.
|
||||
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
||||
// This test doesn't run if SVC is not supported.
|
||||
if (!svc_support_) return;
|
||||
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = 500;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// 2 Temporal layers, no spatial layers, CBR mode.
|
||||
cfg_.ss_number_layers = 1;
|
||||
cfg_.ts_number_layers = 2;
|
||||
cfg_.ts_rate_decimator[0] = 2;
|
||||
cfg_.ts_rate_decimator[1] = 1;
|
||||
cfg_.ts_periodicity = 2;
|
||||
cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
timebase.den, timebase.num, 0, 40);
|
||||
|
||||
// Error resilient mode ON.
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||
SetPatternSwitch(0);
|
||||
|
||||
// The odd frames are the enhancement layer for 2 layer pattern, so set
|
||||
// those frames as droppable. Drop the last 7 frames.
|
||||
unsigned int num_droppable_frames = 7;
|
||||
unsigned int droppable_frame_list[] = { 27, 29, 31, 33, 35, 37, 39 };
|
||||
SetDroppableFrames(num_droppable_frames, droppable_frame_list);
|
||||
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
// Test that no mismatches have been found
|
||||
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
||||
|
||||
// Reset previously set of error/droppable frames.
|
||||
Reset();
|
||||
}
|
||||
|
||||
// Check for successful decoding and no encoder/decoder mismatch
|
||||
// for a two layer temporal pattern, where at some point in the
|
||||
// sequence, the LAST ref is not used anymore.
|
||||
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
||||
// This test doesn't run if SVC is not supported.
|
||||
if (!svc_support_) return;
|
||||
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = 500;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// 2 Temporal layers, no spatial layers, CBR mode.
|
||||
cfg_.ss_number_layers = 1;
|
||||
cfg_.ts_number_layers = 2;
|
||||
cfg_.ts_rate_decimator[0] = 2;
|
||||
cfg_.ts_rate_decimator[1] = 1;
|
||||
cfg_.ts_periodicity = 2;
|
||||
cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
|
||||
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
timebase.den, timebase.num, 0, 100);
|
||||
|
||||
// Error resilient mode ON.
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||
SetPatternSwitch(60);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
// Test that no mismatches have been found
|
||||
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
||||
|
||||
// Reset previously set of error/droppable frames.
|
||||
Reset();
|
||||
}
|
||||
|
||||
class ErrorResilienceTestLargeCodecControls
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
protected:
|
||||
ErrorResilienceTestLargeCodecControls()
|
||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)) {
|
||||
Reset();
|
||||
}
|
||||
|
||||
virtual ~ErrorResilienceTestLargeCodecControls() {}
|
||||
|
||||
void Reset() {
|
||||
last_pts_ = 0;
|
||||
tot_frame_number_ = 0;
|
||||
// For testing up to 3 layers.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
bits_total_[i] = 0;
|
||||
}
|
||||
duration_ = 0.0;
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
}
|
||||
|
||||
//
|
||||
// Frame flags and layer id for temporal layers.
|
||||
//
|
||||
|
||||
// For two layers, test pattern is:
|
||||
// 1 3
|
||||
// 0 2 .....
|
||||
// For three layers, test pattern is:
|
||||
// 1 3 5 7
|
||||
// 2 6
|
||||
// 0 4 ....
|
||||
// LAST is always update on base/layer 0, GOLDEN is updated on layer 1,
|
||||
// and ALTREF is updated on top layer for 3 layer pattern.
|
||||
int SetFrameFlags(int frame_num, int num_temp_layers) {
|
||||
int frame_flags = 0;
|
||||
if (num_temp_layers == 2) {
|
||||
if (frame_num % 2 == 0) {
|
||||
// Layer 0: predict from L and ARF, update L.
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||
} else {
|
||||
// Layer 1: predict from L, G and ARF, and update G.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
||||
}
|
||||
} else if (num_temp_layers == 3) {
|
||||
if (frame_num % 4 == 0) {
|
||||
// Layer 0: predict from L, update L.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
||||
} else if ((frame_num - 2) % 4 == 0) {
|
||||
// Layer 1: predict from L, G, update G.
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
|
||||
} else if ((frame_num - 1) % 2 == 0) {
|
||||
// Layer 2: predict from L, G, ARF; update ARG.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
||||
}
|
||||
}
|
||||
return frame_flags;
|
||||
}
|
||||
|
||||
int SetLayerId(int frame_num, int num_temp_layers) {
|
||||
int layer_id = 0;
|
||||
if (num_temp_layers == 2) {
|
||||
if (frame_num % 2 == 0) {
|
||||
layer_id = 0;
|
||||
} else {
|
||||
layer_id = 1;
|
||||
}
|
||||
} else if (num_temp_layers == 3) {
|
||||
if (frame_num % 4 == 0) {
|
||||
layer_id = 0;
|
||||
} else if ((frame_num - 2) % 4 == 0) {
|
||||
layer_id = 1;
|
||||
} else if ((frame_num - 1) % 2 == 0) {
|
||||
layer_id = 2;
|
||||
}
|
||||
}
|
||||
return layer_id;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (cfg_.ts_number_layers > 1) {
|
||||
int layer_id = SetLayerId(video->frame(), cfg_.ts_number_layers);
|
||||
int frame_flags = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
|
||||
if (video->frame() > 0) {
|
||||
encoder->Control(VP8E_SET_TEMPORAL_LAYER_ID, layer_id);
|
||||
encoder->Control(VP8E_SET_FRAME_FLAGS, frame_flags);
|
||||
}
|
||||
const vpx_rational_t tb = video->timebase();
|
||||
timebase_ = static_cast<double>(tb.num) / tb.den;
|
||||
duration_ = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
// Time since last timestamp = duration.
|
||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
||||
if (duration > 1) {
|
||||
// Update counter for total number of frames (#frames input to encoder).
|
||||
// Needed for setting the proper layer_id below.
|
||||
tot_frame_number_ += static_cast<int>(duration - 1);
|
||||
}
|
||||
int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
|
||||
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
// Update the total encoded bits. For temporal layers, update the cumulative
|
||||
// encoded bits per layer.
|
||||
for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
|
||||
bits_total_[i] += frame_size_in_bits;
|
||||
}
|
||||
// Update the most recent pts.
|
||||
last_pts_ = pkt->data.frame.pts;
|
||||
++tot_frame_number_;
|
||||
}
|
||||
|
||||
virtual void EndPassHook(void) {
|
||||
duration_ = (last_pts_ + 1) * timebase_;
|
||||
if (cfg_.ts_number_layers > 1) {
|
||||
for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
|
||||
++layer) {
|
||||
if (bits_total_[layer]) {
|
||||
// Effective file datarate:
|
||||
effective_datarate_[layer] =
|
||||
(bits_total_[layer] / 1000.0) / duration_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double effective_datarate_[3];
|
||||
|
||||
private:
|
||||
libvpx_test::TestMode encoding_mode_;
|
||||
vpx_codec_pts_t last_pts_;
|
||||
double timebase_;
|
||||
int64_t bits_total_[3];
|
||||
double duration_;
|
||||
int tot_frame_number_;
|
||||
};
|
||||
|
||||
// Check two codec controls used for:
|
||||
// (1) for setting temporal layer id, and (2) for settings encoder flags.
|
||||
// This test invokes those controls for each frame, and verifies encoder/decoder
|
||||
// mismatch and basic rate control response.
|
||||
// TODO(marpan): Maybe move this test to datarate_test.cc.
|
||||
TEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||
cfg_.g_error_resilient = 1;
|
||||
|
||||
// 3 Temporal layers. Framerate decimation (4, 2, 1).
|
||||
cfg_.ts_number_layers = 3;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
cfg_.ts_periodicity = 4;
|
||||
cfg_.ts_layer_id[0] = 0;
|
||||
cfg_.ts_layer_id[1] = 2;
|
||||
cfg_.ts_layer_id[2] = 1;
|
||||
cfg_.ts_layer_id[3] = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 200);
|
||||
for (int i = 200; i <= 800; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
Reset();
|
||||
// 40-20-40 bitrate allocation for 3 temporal layers.
|
||||
cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much, "
|
||||
"for layer: "
|
||||
<< j;
|
||||
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
|
||||
<< " The datarate for the file is greater than target by too much, "
|
||||
"for layer: "
|
||||
<< j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
||||
::testing::Values(true));
|
||||
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls,
|
||||
ONE_PASS_TEST_MODES);
|
||||
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
||||
::testing::Values(true));
|
||||
} // namespace
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file runs all of the tests for the libvpx examples.
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
example_tests=$(ls $(dirname $0)/*.sh)
|
||||
|
||||
# List of script names to exclude.
|
||||
exclude_list="examples stress tools_common"
|
||||
|
||||
# Filter out the scripts in $exclude_list.
|
||||
for word in ${exclude_list}; do
|
||||
example_tests=$(filter_strings "${example_tests}" "${word}" exclude)
|
||||
done
|
||||
|
||||
for test in ${example_tests}; do
|
||||
# Source each test script so that exporting variables can be avoided.
|
||||
VPX_TEST_NAME="$(basename ${test%.*})"
|
||||
. "${test}"
|
||||
done
|
||||
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <memory>
|
||||
#include <string>
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/test_vectors.h"
|
||||
#include "test/util.h"
|
||||
#if CONFIG_WEBM_IO
|
||||
#include "test/webm_video_source.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
const int kVideoNameParam = 1;
|
||||
|
||||
struct ExternalFrameBuffer {
|
||||
uint8_t *data;
|
||||
size_t size;
|
||||
int in_use;
|
||||
};
|
||||
|
||||
// Class to manipulate a list of external frame buffers.
|
||||
class ExternalFrameBufferList {
|
||||
public:
|
||||
ExternalFrameBufferList()
|
||||
: num_buffers_(0), num_used_buffers_(0), ext_fb_list_(NULL) {}
|
||||
|
||||
virtual ~ExternalFrameBufferList() {
|
||||
for (int i = 0; i < num_buffers_; ++i) {
|
||||
delete[] ext_fb_list_[i].data;
|
||||
}
|
||||
delete[] ext_fb_list_;
|
||||
}
|
||||
|
||||
// Creates the list to hold the external buffers. Returns true on success.
|
||||
bool CreateBufferList(int num_buffers) {
|
||||
if (num_buffers < 0) return false;
|
||||
|
||||
num_buffers_ = num_buffers;
|
||||
ext_fb_list_ = new ExternalFrameBuffer[num_buffers_];
|
||||
EXPECT_TRUE(ext_fb_list_ != NULL);
|
||||
memset(ext_fb_list_, 0, sizeof(ext_fb_list_[0]) * num_buffers_);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Searches the frame buffer list for a free frame buffer. Makes sure
|
||||
// that the frame buffer is at least |min_size| in bytes. Marks that the
|
||||
// frame buffer is in use by libvpx. Finally sets |fb| to point to the
|
||||
// external frame buffer. Returns < 0 on an error.
|
||||
int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
||||
EXPECT_TRUE(fb != NULL);
|
||||
const int idx = FindFreeBufferIndex();
|
||||
if (idx == num_buffers_) return -1;
|
||||
|
||||
if (ext_fb_list_[idx].size < min_size) {
|
||||
delete[] ext_fb_list_[idx].data;
|
||||
ext_fb_list_[idx].data = new uint8_t[min_size];
|
||||
memset(ext_fb_list_[idx].data, 0, min_size);
|
||||
ext_fb_list_[idx].size = min_size;
|
||||
}
|
||||
|
||||
SetFrameBuffer(idx, fb);
|
||||
|
||||
num_used_buffers_++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Test function that will not allocate any data for the frame buffer.
|
||||
// Returns < 0 on an error.
|
||||
int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
||||
EXPECT_TRUE(fb != NULL);
|
||||
const int idx = FindFreeBufferIndex();
|
||||
if (idx == num_buffers_) return -1;
|
||||
|
||||
if (ext_fb_list_[idx].size < min_size) {
|
||||
delete[] ext_fb_list_[idx].data;
|
||||
ext_fb_list_[idx].data = NULL;
|
||||
ext_fb_list_[idx].size = min_size;
|
||||
}
|
||||
|
||||
SetFrameBuffer(idx, fb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Marks the external frame buffer that |fb| is pointing to as free.
|
||||
// Returns < 0 on an error.
|
||||
int ReturnFrameBuffer(vpx_codec_frame_buffer_t *fb) {
|
||||
if (fb == NULL) {
|
||||
EXPECT_TRUE(fb != NULL);
|
||||
return -1;
|
||||
}
|
||||
ExternalFrameBuffer *const ext_fb =
|
||||
reinterpret_cast<ExternalFrameBuffer *>(fb->priv);
|
||||
if (ext_fb == NULL) {
|
||||
EXPECT_TRUE(ext_fb != NULL);
|
||||
return -1;
|
||||
}
|
||||
EXPECT_EQ(1, ext_fb->in_use);
|
||||
ext_fb->in_use = 0;
|
||||
num_used_buffers_--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Checks that the vpx_image_t data is contained within the external frame
|
||||
// buffer private data passed back in the vpx_image_t.
|
||||
void CheckImageFrameBuffer(const vpx_image_t *img) {
|
||||
if (img->fb_priv != NULL) {
|
||||
const struct ExternalFrameBuffer *const ext_fb =
|
||||
reinterpret_cast<ExternalFrameBuffer *>(img->fb_priv);
|
||||
|
||||
ASSERT_TRUE(img->planes[0] >= ext_fb->data &&
|
||||
img->planes[0] < (ext_fb->data + ext_fb->size));
|
||||
}
|
||||
}
|
||||
|
||||
int num_used_buffers() const { return num_used_buffers_; }
|
||||
|
||||
private:
|
||||
// Returns the index of the first free frame buffer. Returns |num_buffers_|
|
||||
// if there are no free frame buffers.
|
||||
int FindFreeBufferIndex() {
|
||||
int i;
|
||||
// Find a free frame buffer.
|
||||
for (i = 0; i < num_buffers_; ++i) {
|
||||
if (!ext_fb_list_[i].in_use) break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// Sets |fb| to an external frame buffer. idx is the index into the frame
|
||||
// buffer list.
|
||||
void SetFrameBuffer(int idx, vpx_codec_frame_buffer_t *fb) {
|
||||
ASSERT_TRUE(fb != NULL);
|
||||
fb->data = ext_fb_list_[idx].data;
|
||||
fb->size = ext_fb_list_[idx].size;
|
||||
ASSERT_EQ(0, ext_fb_list_[idx].in_use);
|
||||
ext_fb_list_[idx].in_use = 1;
|
||||
fb->priv = &ext_fb_list_[idx];
|
||||
}
|
||||
|
||||
int num_buffers_;
|
||||
int num_used_buffers_;
|
||||
ExternalFrameBuffer *ext_fb_list_;
|
||||
};
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
|
||||
// Callback used by libvpx to request the application to return a frame
|
||||
// buffer of at least |min_size| in bytes.
|
||||
int get_vp9_frame_buffer(void *user_priv, size_t min_size,
|
||||
vpx_codec_frame_buffer_t *fb) {
|
||||
ExternalFrameBufferList *const fb_list =
|
||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
||||
return fb_list->GetFreeFrameBuffer(min_size, fb);
|
||||
}
|
||||
|
||||
// Callback used by libvpx to tell the application that |fb| is not needed
|
||||
// anymore.
|
||||
int release_vp9_frame_buffer(void *user_priv, vpx_codec_frame_buffer_t *fb) {
|
||||
ExternalFrameBufferList *const fb_list =
|
||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
||||
return fb_list->ReturnFrameBuffer(fb);
|
||||
}
|
||||
|
||||
// Callback will not allocate data for frame buffer.
|
||||
int get_vp9_zero_frame_buffer(void *user_priv, size_t min_size,
|
||||
vpx_codec_frame_buffer_t *fb) {
|
||||
ExternalFrameBufferList *const fb_list =
|
||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
||||
return fb_list->GetZeroFrameBuffer(min_size, fb);
|
||||
}
|
||||
|
||||
// Callback will allocate one less byte than |min_size|.
|
||||
int get_vp9_one_less_byte_frame_buffer(void *user_priv, size_t min_size,
|
||||
vpx_codec_frame_buffer_t *fb) {
|
||||
ExternalFrameBufferList *const fb_list =
|
||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
||||
return fb_list->GetFreeFrameBuffer(min_size - 1, fb);
|
||||
}
|
||||
|
||||
// Callback will not release the external frame buffer.
|
||||
int do_not_release_vp9_frame_buffer(void *user_priv,
|
||||
vpx_codec_frame_buffer_t *fb) {
|
||||
(void)user_priv;
|
||||
(void)fb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
// Class for testing passing in external frame buffers to libvpx.
|
||||
class ExternalFrameBufferMD5Test
|
||||
: public ::libvpx_test::DecoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<const char *> {
|
||||
protected:
|
||||
ExternalFrameBufferMD5Test()
|
||||
: DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)),
|
||||
md5_file_(NULL), num_buffers_(0) {}
|
||||
|
||||
virtual ~ExternalFrameBufferMD5Test() {
|
||||
if (md5_file_ != NULL) fclose(md5_file_);
|
||||
}
|
||||
|
||||
virtual void PreDecodeFrameHook(
|
||||
const libvpx_test::CompressedVideoSource &video,
|
||||
libvpx_test::Decoder *decoder) {
|
||||
if (num_buffers_ > 0 && video.frame_number() == 0) {
|
||||
// Have libvpx use frame buffers we create.
|
||||
ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_));
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
decoder->SetFrameBufferFunctions(GetVP9FrameBuffer,
|
||||
ReleaseVP9FrameBuffer, this));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenMD5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
const unsigned int frame_number) {
|
||||
ASSERT_TRUE(md5_file_ != NULL);
|
||||
char expected_md5[33];
|
||||
char junk[128];
|
||||
|
||||
// Read correct md5 checksums.
|
||||
const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
|
||||
ASSERT_NE(EOF, res) << "Read md5 data failed";
|
||||
expected_md5[32] = '\0';
|
||||
|
||||
::libvpx_test::MD5 md5_res;
|
||||
md5_res.Add(&img);
|
||||
const char *const actual_md5 = md5_res.Get();
|
||||
|
||||
// Check md5 match.
|
||||
ASSERT_STREQ(expected_md5, actual_md5)
|
||||
<< "Md5 checksums don't match: frame number = " << frame_number;
|
||||
}
|
||||
|
||||
// Callback to get a free external frame buffer. Return value < 0 is an
|
||||
// error.
|
||||
static int GetVP9FrameBuffer(void *user_priv, size_t min_size,
|
||||
vpx_codec_frame_buffer_t *fb) {
|
||||
ExternalFrameBufferMD5Test *const md5Test =
|
||||
reinterpret_cast<ExternalFrameBufferMD5Test *>(user_priv);
|
||||
return md5Test->fb_list_.GetFreeFrameBuffer(min_size, fb);
|
||||
}
|
||||
|
||||
// Callback to release an external frame buffer. Return value < 0 is an
|
||||
// error.
|
||||
static int ReleaseVP9FrameBuffer(void *user_priv,
|
||||
vpx_codec_frame_buffer_t *fb) {
|
||||
ExternalFrameBufferMD5Test *const md5Test =
|
||||
reinterpret_cast<ExternalFrameBufferMD5Test *>(user_priv);
|
||||
return md5Test->fb_list_.ReturnFrameBuffer(fb);
|
||||
}
|
||||
|
||||
void set_num_buffers(int num_buffers) { num_buffers_ = num_buffers; }
|
||||
int num_buffers() const { return num_buffers_; }
|
||||
|
||||
private:
|
||||
FILE *md5_file_;
|
||||
int num_buffers_;
|
||||
ExternalFrameBufferList fb_list_;
|
||||
};
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
||||
const char kVP9NonRefTestFile[] = "vp90-2-22-svc_1280x720_1.webm";
|
||||
|
||||
// Class for testing passing in external frame buffers to libvpx.
|
||||
class ExternalFrameBufferTest : public ::testing::Test {
|
||||
protected:
|
||||
ExternalFrameBufferTest() : video_(NULL), decoder_(NULL), num_buffers_(0) {}
|
||||
|
||||
virtual void SetUp() {
|
||||
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
|
||||
ASSERT_TRUE(video_ != NULL);
|
||||
video_->Init();
|
||||
video_->Begin();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
||||
ASSERT_TRUE(decoder_ != NULL);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
delete decoder_;
|
||||
decoder_ = NULL;
|
||||
delete video_;
|
||||
video_ = NULL;
|
||||
}
|
||||
|
||||
// Passes the external frame buffer information to libvpx.
|
||||
vpx_codec_err_t SetFrameBufferFunctions(
|
||||
int num_buffers, vpx_get_frame_buffer_cb_fn_t cb_get,
|
||||
vpx_release_frame_buffer_cb_fn_t cb_release) {
|
||||
if (num_buffers > 0) {
|
||||
num_buffers_ = num_buffers;
|
||||
EXPECT_TRUE(fb_list_.CreateBufferList(num_buffers_));
|
||||
}
|
||||
|
||||
return decoder_->SetFrameBufferFunctions(cb_get, cb_release, &fb_list_);
|
||||
}
|
||||
|
||||
vpx_codec_err_t DecodeOneFrame() {
|
||||
const vpx_codec_err_t res =
|
||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||
CheckDecodedFrames();
|
||||
if (res == VPX_CODEC_OK) video_->Next();
|
||||
return res;
|
||||
}
|
||||
|
||||
vpx_codec_err_t DecodeRemainingFrames() {
|
||||
for (; video_->cxdata() != NULL; video_->Next()) {
|
||||
const vpx_codec_err_t res =
|
||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||
if (res != VPX_CODEC_OK) return res;
|
||||
CheckDecodedFrames();
|
||||
}
|
||||
return VPX_CODEC_OK;
|
||||
}
|
||||
|
||||
void CheckDecodedFrames() {
|
||||
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
||||
const vpx_image_t *img = NULL;
|
||||
|
||||
// Get decompressed data
|
||||
while ((img = dec_iter.Next()) != NULL) {
|
||||
fb_list_.CheckImageFrameBuffer(img);
|
||||
}
|
||||
}
|
||||
|
||||
libvpx_test::WebMVideoSource *video_;
|
||||
libvpx_test::VP9Decoder *decoder_;
|
||||
int num_buffers_;
|
||||
ExternalFrameBufferList fb_list_;
|
||||
};
|
||||
|
||||
class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
video_ = new libvpx_test::WebMVideoSource(kVP9NonRefTestFile);
|
||||
ASSERT_TRUE(video_ != NULL);
|
||||
video_->Init();
|
||||
video_->Begin();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
||||
ASSERT_TRUE(decoder_ != NULL);
|
||||
}
|
||||
|
||||
virtual void CheckFrameBufferRelease() {
|
||||
TearDown();
|
||||
ASSERT_EQ(0, fb_list_.num_used_buffers());
|
||||
}
|
||||
};
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
// This test runs through the set of test vectors, and decodes them.
|
||||
// Libvpx will call into the application to allocate a frame buffer when
|
||||
// needed. The md5 checksums are computed for each frame in the video file.
|
||||
// If md5 checksums match the correct md5 data, then the test is passed.
|
||||
// Otherwise, the test failed.
|
||||
TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
||||
const std::string filename = GET_PARAM(kVideoNameParam);
|
||||
|
||||
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
|
||||
// #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers.
|
||||
const int jitter_buffers = 4;
|
||||
const int num_buffers =
|
||||
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
|
||||
set_num_buffers(num_buffers);
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
// Tell compiler we are not using kVP8TestVectors.
|
||||
(void)libvpx_test::kVP8TestVectors;
|
||||
#endif
|
||||
|
||||
// Open compressed video file.
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
} else {
|
||||
#if CONFIG_WEBM_IO
|
||||
video.reset(new libvpx_test::WebMVideoSource(filename));
|
||||
#else
|
||||
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
||||
filename.c_str());
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
|
||||
// Construct md5 file name.
|
||||
const std::string md5_filename = filename + ".md5";
|
||||
OpenMD5File(md5_filename);
|
||||
|
||||
// Decode frame, and check the md5 matching.
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||
}
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
TEST_F(ExternalFrameBufferTest, MinFrameBuffers) {
|
||||
// Minimum number of external frame buffers for VP9 is
|
||||
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS.
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferTest, EightJitterBuffers) {
|
||||
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
|
||||
// #VPX_MAXIMUM_WORK_BUFFERS + eight jitter buffers.
|
||||
const int jitter_buffers = 8;
|
||||
const int num_buffers =
|
||||
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
|
||||
// Minimum number of external frame buffers for VP9 is
|
||||
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS. Most files will
|
||||
// only use 5 frame buffers at one time.
|
||||
const int num_buffers = 2;
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||
// Only run this on long clips. Decoding a very short clip will return
|
||||
// VPX_CODEC_OK even with only 2 buffers.
|
||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferTest, NoRelease) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
do_not_release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferTest, NullRealloc) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_zero_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_OK, SetFrameBufferFunctions(
|
||||
num_buffers, get_vp9_one_less_byte_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferTest, NullGetFunction) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(
|
||||
VPX_CODEC_INVALID_PARAM,
|
||||
SetFrameBufferFunctions(num_buffers, NULL, release_vp9_frame_buffer));
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferTest, NullReleaseFunction) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, NULL));
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||
ASSERT_EQ(VPX_CODEC_ERROR,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferNonRefTest, ReleaseNonRefFrameBuffer) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||
CheckFrameBufferRelease();
|
||||
}
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
ExternalFrameBufferMD5Test,
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
libvpx_test::kNumVP9TestVectors));
|
||||
} // namespace
|
||||
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* 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 <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vp9/common/vp9_scan.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
|
||||
const int kNumCoeffs = 64;
|
||||
const double kPi = 3.141592653589793238462643383279502884;
|
||||
|
||||
const int kSignBiasMaxDiff255 = 1500;
|
||||
const int kSignBiasMaxDiff15 = 10000;
|
||||
|
||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
||||
int tx_type);
|
||||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type);
|
||||
|
||||
typedef std::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
|
||||
typedef std::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
|
||||
typedef std::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
|
||||
|
||||
void reference_8x8_dct_1d(const double in[8], double out[8]) {
|
||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||
for (int k = 0; k < 8; k++) {
|
||||
out[k] = 0.0;
|
||||
for (int n = 0; n < 8; n++) {
|
||||
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 16.0);
|
||||
}
|
||||
if (k == 0) out[k] = out[k] * kInvSqrt2;
|
||||
}
|
||||
}
|
||||
|
||||
void reference_8x8_dct_2d(const int16_t input[kNumCoeffs],
|
||||
double output[kNumCoeffs]) {
|
||||
// First transform columns
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
double temp_in[8], temp_out[8];
|
||||
for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i];
|
||||
reference_8x8_dct_1d(temp_in, temp_out);
|
||||
for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j];
|
||||
}
|
||||
// Then transform rows
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
double temp_in[8], temp_out[8];
|
||||
for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8];
|
||||
reference_8x8_dct_1d(temp_in, temp_out);
|
||||
// Scale by some magic number
|
||||
for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j] * 2;
|
||||
}
|
||||
}
|
||||
|
||||
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
vpx_fdct8x8_c(in, out, stride);
|
||||
}
|
||||
|
||||
void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||
vp9_fht8x8_c(in, out, stride, tx_type);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
||||
}
|
||||
|
||||
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
|
||||
void idct8x8_12_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
#endif // HAVE_SSE2
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
class FwdTrans8x8TestBase {
|
||||
public:
|
||||
virtual ~FwdTrans8x8TestBase() {}
|
||||
|
||||
protected:
|
||||
virtual void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) = 0;
|
||||
virtual void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) = 0;
|
||||
|
||||
void RunSignBiasCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, test_output_block[64]);
|
||||
int count_sign_block[64][2];
|
||||
const int count_test_block = 100000;
|
||||
|
||||
memset(count_sign_block, 0, sizeof(count_sign_block));
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
test_input_block[j] = ((rnd.Rand16() >> (16 - bit_depth_)) & mask_) -
|
||||
((rnd.Rand16() >> (16 - bit_depth_)) & mask_);
|
||||
}
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
||||
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
if (test_output_block[j] < 0) {
|
||||
++count_sign_block[j][0];
|
||||
} else if (test_output_block[j] > 0) {
|
||||
++count_sign_block[j][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
||||
const int max_diff = kSignBiasMaxDiff255;
|
||||
EXPECT_LT(diff, max_diff << (bit_depth_ - 8))
|
||||
<< "Error: 8x8 FDCT/FHT has a sign bias > "
|
||||
<< 1. * max_diff / count_test_block * 100 << "%"
|
||||
<< " for input range [-255, 255] at index " << j
|
||||
<< " count0: " << count_sign_block[j][0]
|
||||
<< " count1: " << count_sign_block[j][1] << " diff: " << diff;
|
||||
}
|
||||
|
||||
memset(count_sign_block, 0, sizeof(count_sign_block));
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_ / 16, mask_ / 16].
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
test_input_block[j] =
|
||||
((rnd.Rand16() & mask_) >> 4) - ((rnd.Rand16() & mask_) >> 4);
|
||||
}
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
||||
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
if (test_output_block[j] < 0) {
|
||||
++count_sign_block[j][0];
|
||||
} else if (test_output_block[j] > 0) {
|
||||
++count_sign_block[j][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
||||
const int max_diff = kSignBiasMaxDiff15;
|
||||
EXPECT_LT(diff, max_diff << (bit_depth_ - 8))
|
||||
<< "Error: 8x8 FDCT/FHT has a sign bias > "
|
||||
<< 1. * max_diff / count_test_block * 100 << "%"
|
||||
<< " for input range [-15, 15] at index " << j
|
||||
<< " count0: " << count_sign_block[j][0]
|
||||
<< " count1: " << count_sign_block[j][1] << " diff: " << diff;
|
||||
}
|
||||
}
|
||||
|
||||
void RunRoundTripErrorCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
int max_error = 0;
|
||||
int total_error = 0;
|
||||
const int count_test_block = 100000;
|
||||
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[64]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[64]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[64]);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
test_input_block[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
test_input_block[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
if (test_temp_block[j] > 0) {
|
||||
test_temp_block[j] += 2;
|
||||
test_temp_block[j] /= 4;
|
||||
test_temp_block[j] *= 4;
|
||||
} else {
|
||||
test_temp_block[j] -= 2;
|
||||
test_temp_block[j] /= 4;
|
||||
test_temp_block[j] *= 4;
|
||||
}
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const int diff = dst[j] - src[j];
|
||||
#endif
|
||||
const int error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_GE(1 << 2 * (bit_depth_ - 8), max_error)
|
||||
<< "Error: 8x8 FDCT/IDCT or FHT/IHT has an individual"
|
||||
<< " roundtrip error > 1";
|
||||
|
||||
EXPECT_GE((count_test_block << 2 * (bit_depth_ - 8)) / 5, total_error)
|
||||
<< "Error: 8x8 FDCT/IDCT or FHT/IHT has average roundtrip "
|
||||
<< "error > 1/5 per block";
|
||||
}
|
||||
|
||||
void RunExtremalCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
int max_error = 0;
|
||||
int total_error = 0;
|
||||
int total_coeff_error = 0;
|
||||
const int count_test_block = 100000;
|
||||
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_temp_block[64]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[64]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[64]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[64]);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
if (i == 0) {
|
||||
src[j] = 255;
|
||||
dst[j] = 0;
|
||||
} else if (i == 1) {
|
||||
src[j] = 0;
|
||||
dst[j] = 255;
|
||||
} else {
|
||||
src[j] = rnd.Rand8() % 2 ? 255 : 0;
|
||||
dst[j] = rnd.Rand8() % 2 ? 255 : 0;
|
||||
}
|
||||
test_input_block[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
if (i == 0) {
|
||||
src16[j] = mask_;
|
||||
dst16[j] = 0;
|
||||
} else if (i == 1) {
|
||||
src16[j] = 0;
|
||||
dst16[j] = mask_;
|
||||
} else {
|
||||
src16[j] = rnd.Rand8() % 2 ? mask_ : 0;
|
||||
dst16[j] = rnd.Rand8() % 2 ? mask_ : 0;
|
||||
}
|
||||
test_input_block[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_));
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const int diff = dst[j] - src[j];
|
||||
#endif
|
||||
const int error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
|
||||
const int coeff_diff = test_temp_block[j] - ref_temp_block[j];
|
||||
total_coeff_error += abs(coeff_diff);
|
||||
}
|
||||
|
||||
EXPECT_GE(1 << 2 * (bit_depth_ - 8), max_error)
|
||||
<< "Error: Extremal 8x8 FDCT/IDCT or FHT/IHT has"
|
||||
<< "an individual roundtrip error > 1";
|
||||
|
||||
EXPECT_GE((count_test_block << 2 * (bit_depth_ - 8)) / 5, total_error)
|
||||
<< "Error: Extremal 8x8 FDCT/IDCT or FHT/IHT has average"
|
||||
<< " roundtrip error > 1/5 per block";
|
||||
|
||||
EXPECT_EQ(0, total_coeff_error)
|
||||
<< "Error: Extremal 8x8 FDCT/FHT has"
|
||||
<< "overflow issues in the intermediate steps > 1";
|
||||
}
|
||||
}
|
||||
|
||||
void RunInvAccuracyCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
double out_r[kNumCoeffs];
|
||||
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8() % 2 ? 255 : 0;
|
||||
dst[j] = src[j] > 0 ? 0 : 255;
|
||||
in[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand8() % 2 ? mask_ : 0;
|
||||
dst16[j] = src16[j] > 0 ? 0 : mask_;
|
||||
in[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
reference_8x8_dct_2d(in, out_r);
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||
}
|
||||
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const int diff = dst[j] - src[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(1u << 2 * (bit_depth_ - 8), error)
|
||||
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunFwdAccuracyCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_r[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
double out_r[kNumCoeffs];
|
||||
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
in[j] = rnd.Rand8() % 2 == 0 ? mask_ : -mask_;
|
||||
}
|
||||
|
||||
RunFwdTxfm(in, coeff, pitch_);
|
||||
reference_8x8_dct_2d(in, out_r);
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
coeff_r[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
const int32_t diff = coeff[j] - coeff_r[j];
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(9u << 2 * (bit_depth_ - 8), error)
|
||||
<< "Error: 8x8 DCT has error " << error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CompareInvReference(IdctFunc ref_txfm, int thresh) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 10000;
|
||||
const int eob = 12;
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
||||
#endif
|
||||
const int16_t *scan = vp9_default_scan_orders[TX_8X8].scan;
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (j < eob) {
|
||||
// Random values less than the threshold, either positive or negative
|
||||
coeff[scan[j]] = rnd(thresh) * (1 - 2 * (i % 2));
|
||||
} else {
|
||||
coeff[scan[j]] = 0;
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
dst[j] = 0;
|
||||
ref[j] = 0;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
dst16[j] = 0;
|
||||
ref16[j] = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ref_txfm(coeff, ref, pitch_);
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
||||
#else
|
||||
const int diff = dst[j] - ref[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_EQ(0u, error)
|
||||
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
int pitch_;
|
||||
int tx_type_;
|
||||
FhtFunc fwd_txfm_ref;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
};
|
||||
|
||||
class FwdTrans8x8DCT : public FwdTrans8x8TestBase,
|
||||
public ::testing::TestWithParam<Dct8x8Param> {
|
||||
public:
|
||||
virtual ~FwdTrans8x8DCT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
pitch_ = 8;
|
||||
fwd_txfm_ref = fdct8x8_ref;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride);
|
||||
}
|
||||
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride);
|
||||
}
|
||||
|
||||
FdctFunc fwd_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(FwdTrans8x8DCT, SignBiasCheck) { RunSignBiasCheck(); }
|
||||
|
||||
TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); }
|
||||
|
||||
TEST_P(FwdTrans8x8DCT, ExtremalCheck) { RunExtremalCheck(); }
|
||||
|
||||
TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) { RunFwdAccuracyCheck(); }
|
||||
|
||||
TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
|
||||
|
||||
class FwdTrans8x8HT : public FwdTrans8x8TestBase,
|
||||
public ::testing::TestWithParam<Ht8x8Param> {
|
||||
public:
|
||||
virtual ~FwdTrans8x8HT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
pitch_ = 8;
|
||||
fwd_txfm_ref = fht8x8_ref;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride, tx_type_);
|
||||
}
|
||||
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride, tx_type_);
|
||||
}
|
||||
|
||||
FhtFunc fwd_txfm_;
|
||||
IhtFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(FwdTrans8x8HT, SignBiasCheck) { RunSignBiasCheck(); }
|
||||
|
||||
TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); }
|
||||
|
||||
TEST_P(FwdTrans8x8HT, ExtremalCheck) { RunExtremalCheck(); }
|
||||
|
||||
class InvTrans8x8DCT : public FwdTrans8x8TestBase,
|
||||
public ::testing::TestWithParam<Idct8x8Param> {
|
||||
public:
|
||||
virtual ~InvTrans8x8DCT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
ref_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
thresh_ = GET_PARAM(2);
|
||||
pitch_ = 8;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride);
|
||||
}
|
||||
void RunFwdTxfm(int16_t * /*out*/, tran_low_t * /*dst*/, int /*stride*/) {}
|
||||
|
||||
IdctFunc ref_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
int thresh_;
|
||||
};
|
||||
|
||||
TEST_P(InvTrans8x8DCT, CompareReference) {
|
||||
CompareInvReference(ref_txfm_, thresh_);
|
||||
}
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, FwdTrans8x8DCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(C, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
||||
&vpx_idct8x8_64_add_c, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 3, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
||||
&vpx_idct8x8_64_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_sse2,
|
||||
&vpx_idct8x8_64_add_sse2,
|
||||
0, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_10_sse2,
|
||||
12, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
||||
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_12_sse2,
|
||||
12, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
||||
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||
|
||||
// Optimizations take effect at a threshold of 6201, so we use a value close to
|
||||
// that to test both branches.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, InvTrans8x8DCT,
|
||||
::testing::Values(
|
||||
make_tuple(&idct8x8_12_add_10_c, &idct8x8_12_add_10_sse2, 6225,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&idct8x8_10, &idct8x8_64_add_10_sse2, 6225, VPX_BITS_10),
|
||||
make_tuple(&idct8x8_12_add_12_c, &idct8x8_12_add_12_sse2, 6225,
|
||||
VPX_BITS_12),
|
||||
make_tuple(&idct8x8_12, &idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSSE3 && VPX_ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
|
||||
!CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_ssse3,
|
||||
&vpx_idct8x8_64_add_sse2,
|
||||
0, VPX_BITS_8)));
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(MSA, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_msa,
|
||||
&vpx_idct8x8_64_add_msa, 0,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(VSX, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
||||
&vpx_idct8x8_64_add_vsx, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/video_source.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class VP9FrameSizeTestsLarge : public ::libvpx_test::EncoderTest,
|
||||
public ::testing::Test {
|
||||
protected:
|
||||
VP9FrameSizeTestsLarge()
|
||||
: EncoderTest(&::libvpx_test::kVP9), expected_res_(VPX_CODEC_OK) {}
|
||||
virtual ~VP9FrameSizeTestsLarge() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(::libvpx_test::kRealTime);
|
||||
}
|
||||
|
||||
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
|
||||
const libvpx_test::VideoSource & /*video*/,
|
||||
libvpx_test::Decoder *decoder) {
|
||||
EXPECT_EQ(expected_res_, res_dec) << decoder->DecodeError();
|
||||
return !::testing::Test::HasFailure();
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, 7);
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||
}
|
||||
}
|
||||
|
||||
int expected_res_;
|
||||
};
|
||||
|
||||
TEST_F(VP9FrameSizeTestsLarge, TestInvalidSizes) {
|
||||
::libvpx_test::RandomVideoSource video;
|
||||
|
||||
#if CONFIG_SIZE_LIMIT
|
||||
video.SetSize(DECODE_WIDTH_LIMIT + 16, DECODE_HEIGHT_LIMIT + 16);
|
||||
video.set_limit(2);
|
||||
expected_res_ = VPX_CODEC_CORRUPT_FRAME;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(VP9FrameSizeTestsLarge, ValidSizes) {
|
||||
::libvpx_test::RandomVideoSource video;
|
||||
|
||||
#if CONFIG_SIZE_LIMIT
|
||||
video.SetSize(DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT);
|
||||
video.set_limit(2);
|
||||
expected_res_ = VPX_CODEC_OK;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#else
|
||||
// This test produces a pretty large single frame allocation, (roughly
|
||||
// 25 megabits). The encoder allocates a good number of these frames
|
||||
// one for each lag in frames (for 2 pass), and then one for each possible
|
||||
// reference buffer (8) - we can end up with up to 30 buffers of roughly this
|
||||
// size or almost 1 gig of memory.
|
||||
// In total the allocations will exceed 2GiB which may cause a failure with
|
||||
// mingw + wine, use a smaller size in that case.
|
||||
#if defined(_WIN32) && !defined(_WIN64) || defined(__OS2__)
|
||||
video.SetSize(4096, 3072);
|
||||
#else
|
||||
video.SetSize(4096, 4096);
|
||||
#endif
|
||||
video.set_limit(2);
|
||||
expected_res_ = VPX_CODEC_OK;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(VP9FrameSizeTestsLarge, OneByOneVideo) {
|
||||
::libvpx_test::RandomVideoSource video;
|
||||
|
||||
video.SetSize(1, 1);
|
||||
video.set_limit(2);
|
||||
expected_res_ = VPX_CODEC_OK;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
} // namespace
|
||||
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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 <algorithm>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/register_state_check.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::libvpx_test::ACMRandom;
|
||||
|
||||
typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride,
|
||||
tran_low_t *b);
|
||||
|
||||
void hadamard_loop(const tran_low_t *a, tran_low_t *out) {
|
||||
tran_low_t b[8];
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
b[i + 0] = a[i * 8] + a[(i + 1) * 8];
|
||||
b[i + 1] = a[i * 8] - a[(i + 1) * 8];
|
||||
}
|
||||
tran_low_t c[8];
|
||||
for (int i = 0; i < 8; i += 4) {
|
||||
c[i + 0] = b[i + 0] + b[i + 2];
|
||||
c[i + 1] = b[i + 1] + b[i + 3];
|
||||
c[i + 2] = b[i + 0] - b[i + 2];
|
||||
c[i + 3] = b[i + 1] - b[i + 3];
|
||||
}
|
||||
out[0] = c[0] + c[4];
|
||||
out[7] = c[1] + c[5];
|
||||
out[3] = c[2] + c[6];
|
||||
out[4] = c[3] + c[7];
|
||||
out[2] = c[0] - c[4];
|
||||
out[6] = c[1] - c[5];
|
||||
out[1] = c[2] - c[6];
|
||||
out[5] = c[3] - c[7];
|
||||
}
|
||||
|
||||
void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
tran_low_t input[64];
|
||||
tran_low_t buf[64];
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
input[i * 8 + j] = static_cast<tran_low_t>(a[i * a_stride + j]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 8; ++i) hadamard_loop(input + i, buf + i * 8);
|
||||
for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, b + i * 8);
|
||||
}
|
||||
|
||||
void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
||||
* Input is 9 bit. */
|
||||
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
|
||||
reference_hadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64);
|
||||
reference_hadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128);
|
||||
reference_hadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192);
|
||||
|
||||
/* Overlay the 8x8 blocks and combine. */
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
/* 8x8 steps the range up to 15 bits. */
|
||||
const tran_low_t a0 = b[0];
|
||||
const tran_low_t a1 = b[64];
|
||||
const tran_low_t a2 = b[128];
|
||||
const tran_low_t a3 = b[192];
|
||||
|
||||
/* Prevent the result from escaping int16_t. */
|
||||
const tran_low_t b0 = (a0 + a1) >> 1;
|
||||
const tran_low_t b1 = (a0 - a1) >> 1;
|
||||
const tran_low_t b2 = (a2 + a3) >> 1;
|
||||
const tran_low_t b3 = (a2 - a3) >> 1;
|
||||
|
||||
/* Store a 16 bit value. */
|
||||
b[0] = b0 + b2;
|
||||
b[64] = b1 + b3;
|
||||
b[128] = b0 - b2;
|
||||
b[192] = b1 - b3;
|
||||
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
void reference_hadamard32x32(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
reference_hadamard16x16(a + 0 + 0 * a_stride, a_stride, b + 0);
|
||||
reference_hadamard16x16(a + 16 + 0 * a_stride, a_stride, b + 256);
|
||||
reference_hadamard16x16(a + 0 + 16 * a_stride, a_stride, b + 512);
|
||||
reference_hadamard16x16(a + 16 + 16 * a_stride, a_stride, b + 768);
|
||||
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
const tran_low_t a0 = b[0];
|
||||
const tran_low_t a1 = b[256];
|
||||
const tran_low_t a2 = b[512];
|
||||
const tran_low_t a3 = b[768];
|
||||
|
||||
const tran_low_t b0 = (a0 + a1) >> 2;
|
||||
const tran_low_t b1 = (a0 - a1) >> 2;
|
||||
const tran_low_t b2 = (a2 + a3) >> 2;
|
||||
const tran_low_t b3 = (a2 - a3) >> 2;
|
||||
|
||||
b[0] = b0 + b2;
|
||||
b[256] = b1 + b3;
|
||||
b[512] = b0 - b2;
|
||||
b[768] = b1 - b3;
|
||||
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
struct HadamardFuncWithSize {
|
||||
HadamardFuncWithSize(HadamardFunc f, int s) : func(f), block_size(s) {}
|
||||
HadamardFunc func;
|
||||
int block_size;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const HadamardFuncWithSize &hfs) {
|
||||
return os << "block size: " << hfs.block_size;
|
||||
}
|
||||
|
||||
class HadamardTestBase : public ::testing::TestWithParam<HadamardFuncWithSize> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
h_func_ = GetParam().func;
|
||||
bwh_ = GetParam().block_size;
|
||||
block_size_ = bwh_ * bwh_;
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
virtual int16_t Rand() = 0;
|
||||
|
||||
void ReferenceHadamard(const int16_t *a, int a_stride, tran_low_t *b,
|
||||
int bwh) {
|
||||
if (bwh == 32)
|
||||
reference_hadamard32x32(a, a_stride, b);
|
||||
else if (bwh == 16)
|
||||
reference_hadamard16x16(a, a_stride, b);
|
||||
else
|
||||
reference_hadamard8x8(a, a_stride, b);
|
||||
}
|
||||
|
||||
void CompareReferenceRandom() {
|
||||
const int kMaxBlockSize = 32 * 32;
|
||||
DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]);
|
||||
memset(a, 0, sizeof(a));
|
||||
memset(b, 0, sizeof(b));
|
||||
|
||||
tran_low_t b_ref[kMaxBlockSize];
|
||||
memset(b_ref, 0, sizeof(b_ref));
|
||||
|
||||
for (int i = 0; i < block_size_; ++i) a[i] = Rand();
|
||||
|
||||
ReferenceHadamard(a, bwh_, b_ref, bwh_);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, bwh_, b));
|
||||
|
||||
// The order of the output is not important. Sort before checking.
|
||||
std::sort(b, b + block_size_);
|
||||
std::sort(b_ref, b_ref + block_size_);
|
||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||
}
|
||||
|
||||
void VaryStride() {
|
||||
const int kMaxBlockSize = 32 * 32;
|
||||
DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize * 8]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]);
|
||||
memset(a, 0, sizeof(a));
|
||||
for (int i = 0; i < block_size_ * 8; ++i) a[i] = Rand();
|
||||
|
||||
tran_low_t b_ref[kMaxBlockSize];
|
||||
for (int i = 8; i < 64; i += 8) {
|
||||
memset(b, 0, sizeof(b));
|
||||
memset(b_ref, 0, sizeof(b_ref));
|
||||
|
||||
ReferenceHadamard(a, i, b_ref, bwh_);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
||||
|
||||
// The order of the output is not important. Sort before checking.
|
||||
std::sort(b, b + block_size_);
|
||||
std::sort(b_ref, b_ref + block_size_);
|
||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||
}
|
||||
}
|
||||
|
||||
void SpeedTest(int times) {
|
||||
const int kMaxBlockSize = 32 * 32;
|
||||
DECLARE_ALIGNED(16, int16_t, input[kMaxBlockSize]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kMaxBlockSize]);
|
||||
memset(input, 1, sizeof(input));
|
||||
memset(output, 0, sizeof(output));
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < times; ++i) {
|
||||
h_func_(input, bwh_, output);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("Hadamard%dx%d[%12d runs]: %d us\n", bwh_, bwh_, times,
|
||||
elapsed_time);
|
||||
}
|
||||
|
||||
protected:
|
||||
int bwh_;
|
||||
int block_size_;
|
||||
HadamardFunc h_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
class HadamardLowbdTest : public HadamardTestBase {
|
||||
protected:
|
||||
virtual int16_t Rand() { return rnd_.Rand9Signed(); }
|
||||
};
|
||||
|
||||
TEST_P(HadamardLowbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
|
||||
|
||||
TEST_P(HadamardLowbdTest, VaryStride) { VaryStride(); }
|
||||
|
||||
TEST_P(HadamardLowbdTest, DISABLED_Speed) {
|
||||
SpeedTest(10);
|
||||
SpeedTest(10000);
|
||||
SpeedTest(10000000);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_c, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_c, 16),
|
||||
HadamardFuncWithSize(&vpx_hadamard_32x32_c, 32)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_sse2, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_sse2, 16),
|
||||
HadamardFuncWithSize(&vpx_hadamard_32x32_sse2, 32)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_16x16_avx2, 16),
|
||||
HadamardFuncWithSize(&vpx_hadamard_32x32_avx2, 32)));
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_SSSE3 && VPX_ARCH_X86_64
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_ssse3, 8)));
|
||||
#endif // HAVE_SSSE3 && VPX_ARCH_X86_64
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_neon, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_neon, 16)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
// TODO(jingning): Remove highbitdepth flag when the SIMD functions are
|
||||
// in place and turn on the unit test.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_msa, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_msa, 16)));
|
||||
#endif // HAVE_MSA
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VSX, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_vsx, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_vsx, 16)));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
class HadamardHighbdTest : public HadamardTestBase {
|
||||
protected:
|
||||
virtual int16_t Rand() { return rnd_.Rand13Signed(); }
|
||||
};
|
||||
|
||||
TEST_P(HadamardHighbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
|
||||
|
||||
TEST_P(HadamardHighbdTest, VaryStride) { VaryStride(); }
|
||||
|
||||
TEST_P(HadamardHighbdTest, DISABLED_Speed) {
|
||||
SpeedTest(10);
|
||||
SpeedTest(10000);
|
||||
SpeedTest(10000000);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, HadamardHighbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_c, 8),
|
||||
HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_c, 16),
|
||||
HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_c, 32)));
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, HadamardHighbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_avx2, 8),
|
||||
HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_avx2, 16),
|
||||
HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_avx2,
|
||||
32)));
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
} // namespace
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 VPX_TEST_I420_VIDEO_SOURCE_H_
|
||||
#define VPX_TEST_I420_VIDEO_SOURCE_H_
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include "test/yuv_video_source.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
// This class extends VideoSource to allow parsing of raw yv12
|
||||
// so that we can do actual file encodes.
|
||||
class I420VideoSource : public YUVVideoSource {
|
||||
public:
|
||||
I420VideoSource(const std::string &file_name, unsigned int width,
|
||||
unsigned int height, int rate_numerator, int rate_denominator,
|
||||
unsigned int start, int limit)
|
||||
: YUVVideoSource(file_name, VPX_IMG_FMT_I420, width, height,
|
||||
rate_numerator, rate_denominator, start, limit) {}
|
||||
};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // VPX_TEST_I420_VIDEO_SOURCE_H_
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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 <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/msvc.h" // for round()
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
|
||||
void reference_dct_1d(double input[8], double output[8]) {
|
||||
const double kPi = 3.141592653589793238462643383279502884;
|
||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||
for (int k = 0; k < 8; k++) {
|
||||
output[k] = 0.0;
|
||||
for (int n = 0; n < 8; n++) {
|
||||
output[k] += input[n] * cos(kPi * (2 * n + 1) * k / 16.0);
|
||||
}
|
||||
if (k == 0) output[k] = output[k] * kInvSqrt2;
|
||||
}
|
||||
}
|
||||
|
||||
void reference_dct_2d(int16_t input[64], double output[64]) {
|
||||
// First transform columns
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
double temp_in[8], temp_out[8];
|
||||
for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i];
|
||||
reference_dct_1d(temp_in, temp_out);
|
||||
for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j];
|
||||
}
|
||||
// Then transform rows
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
double temp_in[8], temp_out[8];
|
||||
for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8];
|
||||
reference_dct_1d(temp_in, temp_out);
|
||||
for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j];
|
||||
}
|
||||
// Scale by some magic number
|
||||
for (int i = 0; i < 64; ++i) output[i] *= 2;
|
||||
}
|
||||
|
||||
TEST(VP9Idct8x8Test, AccuracyCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 10000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int16_t input[64];
|
||||
tran_low_t coeff[64];
|
||||
double output_r[64];
|
||||
uint8_t dst[64], src[64];
|
||||
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
}
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < 64; ++j) input[j] = src[j] - dst[j];
|
||||
|
||||
reference_dct_2d(input, output_r);
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
coeff[j] = static_cast<tran_low_t>(round(output_r[j]));
|
||||
}
|
||||
vpx_idct8x8_64_add_c(coeff, dst, 8);
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
const int diff = dst[j] - src[j];
|
||||
const int error = diff * diff;
|
||||
EXPECT_GE(1, error) << "Error: 8x8 FDCT/IDCT has error " << error
|
||||
<< " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vp8_rtcd.h"
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
|
||||
int pred_stride, unsigned char *dst_ptr,
|
||||
int dst_stride);
|
||||
namespace {
|
||||
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
UUT = GetParam();
|
||||
|
||||
input = new Buffer<int16_t>(4, 4, 0);
|
||||
ASSERT_TRUE(input != NULL);
|
||||
ASSERT_TRUE(input->Init());
|
||||
predict = new Buffer<uint8_t>(4, 4, 3);
|
||||
ASSERT_TRUE(predict != NULL);
|
||||
ASSERT_TRUE(predict->Init());
|
||||
output = new Buffer<uint8_t>(4, 4, 3);
|
||||
ASSERT_TRUE(output != NULL);
|
||||
ASSERT_TRUE(output->Init());
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
delete input;
|
||||
delete predict;
|
||||
delete output;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
IdctFunc UUT;
|
||||
Buffer<int16_t> *input;
|
||||
Buffer<uint8_t> *predict;
|
||||
Buffer<uint8_t> *output;
|
||||
};
|
||||
|
||||
TEST_P(IDCTTest, TestAllZeros) {
|
||||
// When the input is '0' the output will be '0'.
|
||||
input->Set(0);
|
||||
predict->Set(0);
|
||||
output->Set(0);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
ASSERT_TRUE(input->CheckValues(0));
|
||||
ASSERT_TRUE(input->CheckPadding());
|
||||
ASSERT_TRUE(output->CheckValues(0));
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestAllOnes) {
|
||||
input->Set(0);
|
||||
ASSERT_TRUE(input->TopLeftPixel() != NULL);
|
||||
// When the first element is '4' it will fill the output buffer with '1'.
|
||||
input->TopLeftPixel()[0] = 4;
|
||||
predict->Set(0);
|
||||
output->Set(0);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
ASSERT_TRUE(output->CheckValues(1));
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestAddOne) {
|
||||
// Set the transform output to '1' and make sure it gets added to the
|
||||
// prediction buffer.
|
||||
input->Set(0);
|
||||
ASSERT_TRUE(input->TopLeftPixel() != NULL);
|
||||
input->TopLeftPixel()[0] = 4;
|
||||
output->Set(0);
|
||||
|
||||
uint8_t *pred = predict->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
pred[y * predict->stride() + x] = y * 4 + x;
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
uint8_t const *out = output->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
EXPECT_EQ(1 + y * 4 + x, out[y * output->stride() + x]);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasFailure()) {
|
||||
output->DumpBuffer();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestWithData) {
|
||||
// Test a single known input.
|
||||
predict->Set(0);
|
||||
|
||||
int16_t *in = input->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
in[y * input->stride() + x] = y * 4 + x;
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
uint8_t *out = output->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
switch (y * 4 + x) {
|
||||
case 0: EXPECT_EQ(11, out[y * output->stride() + x]); break;
|
||||
case 2:
|
||||
case 5:
|
||||
case 8: EXPECT_EQ(3, out[y * output->stride() + x]); break;
|
||||
case 10: EXPECT_EQ(1, out[y * output->stride() + x]); break;
|
||||
default: EXPECT_EQ(0, out[y * output->stride() + x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HasFailure()) {
|
||||
output->DumpBuffer();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MMX
|
||||
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_mmx));
|
||||
#endif // HAVE_MMX
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_msa));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(MMI, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_mmi));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "test/util.h"
|
||||
#if CONFIG_WEBM_IO
|
||||
#include "test/webm_video_source.h"
|
||||
#endif
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct DecodeParam {
|
||||
int threads;
|
||||
const char *filename;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const DecodeParam &dp) {
|
||||
return os << "threads: " << dp.threads << " file: " << dp.filename;
|
||||
}
|
||||
|
||||
class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
||||
protected:
|
||||
InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}
|
||||
|
||||
virtual ~InvalidFileTest() {
|
||||
if (res_file_ != NULL) fclose(res_file_);
|
||||
}
|
||||
|
||||
void OpenResFile(const std::string &res_file_name_) {
|
||||
res_file_ = libvpx_test::OpenTestDataFile(res_file_name_);
|
||||
ASSERT_TRUE(res_file_ != NULL)
|
||||
<< "Result file open failed. Filename: " << res_file_name_;
|
||||
}
|
||||
|
||||
virtual bool HandleDecodeResult(
|
||||
const vpx_codec_err_t res_dec,
|
||||
const libvpx_test::CompressedVideoSource &video,
|
||||
libvpx_test::Decoder *decoder) {
|
||||
EXPECT_TRUE(res_file_ != NULL);
|
||||
int expected_res_dec;
|
||||
|
||||
// Read integer result.
|
||||
const int res = fscanf(res_file_, "%d", &expected_res_dec);
|
||||
EXPECT_NE(res, EOF) << "Read result data failed";
|
||||
|
||||
// Check results match.
|
||||
const DecodeParam input = GET_PARAM(1);
|
||||
if (input.threads > 1) {
|
||||
// The serial decode check is too strict for tile-threaded decoding as
|
||||
// there is no guarantee on the decode order nor which specific error
|
||||
// will take precedence. Currently a tile-level error is not forwarded so
|
||||
// the frame will simply be marked corrupt.
|
||||
EXPECT_TRUE(res_dec == expected_res_dec ||
|
||||
res_dec == VPX_CODEC_CORRUPT_FRAME)
|
||||
<< "Results don't match: frame number = " << video.frame_number()
|
||||
<< ". (" << decoder->DecodeError()
|
||||
<< "). Expected: " << expected_res_dec << " or "
|
||||
<< VPX_CODEC_CORRUPT_FRAME;
|
||||
} else {
|
||||
EXPECT_EQ(expected_res_dec, res_dec)
|
||||
<< "Results don't match: frame number = " << video.frame_number()
|
||||
<< ". (" << decoder->DecodeError() << ")";
|
||||
}
|
||||
|
||||
return !HasFailure();
|
||||
}
|
||||
|
||||
void RunTest() {
|
||||
const DecodeParam input = GET_PARAM(1);
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
cfg.threads = input.threads;
|
||||
const std::string filename = input.filename;
|
||||
|
||||
// Open compressed video file.
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
|
||||
#if CONFIG_WEBM_IO
|
||||
video.reset(new libvpx_test::WebMVideoSource(filename));
|
||||
#else
|
||||
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
||||
filename.c_str());
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
|
||||
// Construct result file name. The file holds a list of expected integer
|
||||
// results, one for each decoded frame. Any result that doesn't match
|
||||
// the files list will cause a test failure.
|
||||
const std::string res_filename = filename + ".res";
|
||||
OpenResFile(res_filename);
|
||||
|
||||
// Decode frame, and check the md5 matching.
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
|
||||
}
|
||||
|
||||
private:
|
||||
FILE *res_file_;
|
||||
};
|
||||
|
||||
TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
const DecodeParam kVP8InvalidFileTests[] = {
|
||||
{ 1, "invalid-bug-1443.ivf" },
|
||||
{ 1, "invalid-token-partition.ivf" },
|
||||
{ 1, "invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf" },
|
||||
};
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||
::testing::ValuesIn(kVP8InvalidFileTests));
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
const DecodeParam kVP9InvalidFileTests[] = {
|
||||
{ 1, "invalid-vp90-02-v2.webm" },
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ 1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf" },
|
||||
{ 1,
|
||||
"invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-."
|
||||
"ivf" },
|
||||
#endif
|
||||
{ 1, "invalid-vp90-03-v3.webm" },
|
||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" },
|
||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf" },
|
||||
// This file will cause a large allocation which is expected to fail in 32-bit
|
||||
// environments. Test x86 for coverage purposes as the allocation failure will
|
||||
// be in platform agnostic code.
|
||||
#if VPX_ARCH_X86
|
||||
{ 1, "invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf" },
|
||||
#endif
|
||||
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf" },
|
||||
{ 1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf" },
|
||||
{ 1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf" },
|
||||
{ 1, "invalid-vp91-2-mixedrefcsp-444to420.ivf" },
|
||||
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf" },
|
||||
{ 1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf" },
|
||||
{ 1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf" },
|
||||
{ 1,
|
||||
"invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf" },
|
||||
{ 1, "invalid-crbug-667044.webm" },
|
||||
};
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||
::testing::ValuesIn(kVP9InvalidFileTests));
|
||||
#endif // CONFIG_VP9_DECODER
|
||||
|
||||
// This class will include test vectors that are expected to fail
|
||||
// peek. However they are still expected to have no fatal failures.
|
||||
class InvalidFileInvalidPeekTest : public InvalidFileTest {
|
||||
protected:
|
||||
InvalidFileInvalidPeekTest() : InvalidFileTest() {}
|
||||
virtual void HandlePeekResult(libvpx_test::Decoder *const /*decoder*/,
|
||||
libvpx_test::CompressedVideoSource * /*video*/,
|
||||
const vpx_codec_err_t /*res_peek*/) {}
|
||||
};
|
||||
|
||||
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
const DecodeParam kVP8InvalidPeekTests[] = {
|
||||
{ 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" },
|
||||
};
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||
::testing::ValuesIn(kVP8InvalidPeekTests));
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
|
||||
{ 1, "invalid-vp90-01-v3.webm" },
|
||||
};
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||
::testing::ValuesIn(kVP9InvalidFileInvalidPeekTests));
|
||||
|
||||
const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
||||
{ 4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm" },
|
||||
{ 4,
|
||||
"invalid-"
|
||||
"vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf" },
|
||||
{ 4,
|
||||
"invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf" },
|
||||
{ 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" },
|
||||
{ 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" },
|
||||
{ 2, "invalid-crbug-629481.webm" },
|
||||
{ 3, "invalid-crbug-1558.ivf" },
|
||||
{ 4, "invalid-crbug-1562.ivf" },
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9MultiThreaded, InvalidFileTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
|
||||
#endif // CONFIG_VP9_DECODER
|
||||
} // namespace
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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 VPX_TEST_IVF_VIDEO_SOURCE_H_
|
||||
#define VPX_TEST_IVF_VIDEO_SOURCE_H_
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include "test/video_source.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
const unsigned int kCodeBufferSize = 256 * 1024 * 1024;
|
||||
const unsigned int kIvfFileHdrSize = 32;
|
||||
const unsigned int kIvfFrameHdrSize = 12;
|
||||
|
||||
static unsigned int MemGetLe32(const uint8_t *mem) {
|
||||
return (mem[3] << 24) | (mem[2] << 16) | (mem[1] << 8) | (mem[0]);
|
||||
}
|
||||
|
||||
// This class extends VideoSource to allow parsing of ivf files,
|
||||
// so that we can do actual file decodes.
|
||||
class IVFVideoSource : public CompressedVideoSource {
|
||||
public:
|
||||
explicit IVFVideoSource(const std::string &file_name)
|
||||
: file_name_(file_name), input_file_(NULL), compressed_frame_buf_(NULL),
|
||||
frame_sz_(0), frame_(0), end_of_file_(false) {}
|
||||
|
||||
virtual ~IVFVideoSource() {
|
||||
delete[] compressed_frame_buf_;
|
||||
|
||||
if (input_file_) fclose(input_file_);
|
||||
}
|
||||
|
||||
virtual void Init() {
|
||||
// Allocate a buffer for read in the compressed video frame.
|
||||
compressed_frame_buf_ = new uint8_t[libvpx_test::kCodeBufferSize];
|
||||
ASSERT_TRUE(compressed_frame_buf_ != NULL)
|
||||
<< "Allocate frame buffer failed";
|
||||
}
|
||||
|
||||
virtual void Begin() {
|
||||
input_file_ = OpenTestDataFile(file_name_);
|
||||
ASSERT_TRUE(input_file_ != NULL)
|
||||
<< "Input file open failed. Filename: " << file_name_;
|
||||
|
||||
// Read file header
|
||||
uint8_t file_hdr[kIvfFileHdrSize];
|
||||
ASSERT_EQ(kIvfFileHdrSize, fread(file_hdr, 1, kIvfFileHdrSize, input_file_))
|
||||
<< "File header read failed.";
|
||||
// Check file header
|
||||
ASSERT_TRUE(file_hdr[0] == 'D' && file_hdr[1] == 'K' &&
|
||||
file_hdr[2] == 'I' && file_hdr[3] == 'F')
|
||||
<< "Input is not an IVF file.";
|
||||
|
||||
FillFrame();
|
||||
}
|
||||
|
||||
virtual void Next() {
|
||||
++frame_;
|
||||
FillFrame();
|
||||
}
|
||||
|
||||
void FillFrame() {
|
||||
ASSERT_TRUE(input_file_ != NULL);
|
||||
uint8_t frame_hdr[kIvfFrameHdrSize];
|
||||
// Check frame header and read a frame from input_file.
|
||||
if (fread(frame_hdr, 1, kIvfFrameHdrSize, input_file_) !=
|
||||
kIvfFrameHdrSize) {
|
||||
end_of_file_ = true;
|
||||
} else {
|
||||
end_of_file_ = false;
|
||||
|
||||
frame_sz_ = MemGetLe32(frame_hdr);
|
||||
ASSERT_LE(frame_sz_, kCodeBufferSize)
|
||||
<< "Frame is too big for allocated code buffer";
|
||||
ASSERT_EQ(frame_sz_,
|
||||
fread(compressed_frame_buf_, 1, frame_sz_, input_file_))
|
||||
<< "Failed to read complete frame";
|
||||
}
|
||||
}
|
||||
|
||||
virtual const uint8_t *cxdata() const {
|
||||
return end_of_file_ ? NULL : compressed_frame_buf_;
|
||||
}
|
||||
virtual size_t frame_size() const { return frame_sz_; }
|
||||
virtual unsigned int frame_number() const { return frame_; }
|
||||
|
||||
protected:
|
||||
std::string file_name_;
|
||||
FILE *input_file_;
|
||||
uint8_t *compressed_frame_buf_;
|
||||
size_t frame_sz_;
|
||||
unsigned int frame_;
|
||||
bool end_of_file_;
|
||||
};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // VPX_TEST_IVF_VIDEO_SOURCE_H_
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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 "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 {
|
||||
|
||||
class KeyframeTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
protected:
|
||||
KeyframeTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
virtual ~KeyframeTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
kf_count_ = 0;
|
||||
kf_count_max_ = INT_MAX;
|
||||
kf_do_force_kf_ = false;
|
||||
set_cpu_used_ = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (kf_do_force_kf_) {
|
||||
frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF;
|
||||
}
|
||||
if (set_cpu_used_ && video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
}
|
||||
}
|
||||
|
||||
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_;
|
||||
int set_cpu_used_;
|
||||
};
|
||||
|
||||
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));
|
||||
|
||||
// In realtime mode - auto placed keyframes are exceedingly rare, don't
|
||||
// bother with this check if(GetParam() > 0)
|
||||
if (GET_PARAM(1) > 0) {
|
||||
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<vpx_codec_pts_t>::const_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<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||
iter != kf_pts_list_.end(); ++iter) {
|
||||
ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(KeyframeTest, TestAutoKeyframe) {
|
||||
cfg_.kf_mode = VPX_KF_AUTO;
|
||||
kf_do_force_kf_ = false;
|
||||
|
||||
// Force a deterministic speed step in Real Time mode, as the faster modes
|
||||
// may not produce a keyframe like we expect. This is necessary when running
|
||||
// on very slow environments (like Valgrind). The step -11 was determined
|
||||
// experimentally as the fastest mode that still throws the keyframe.
|
||||
if (deadline_ == VPX_DL_REALTIME) set_cpu_used_ = -11;
|
||||
|
||||
// This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120.
|
||||
// I check only the first 40 frames to make sure there's a keyframe at frame
|
||||
// 0 and 30.
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 40);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
// In realtime mode - auto placed keyframes are exceedingly rare, don't
|
||||
// bother with this check
|
||||
if (GET_PARAM(1) > 0) {
|
||||
EXPECT_EQ(2u, kf_pts_list_.size()) << " Not the right number of keyframes ";
|
||||
}
|
||||
|
||||
// Verify that keyframes match the file keyframes in the file.
|
||||
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||
iter != kf_pts_list_.end(); ++iter) {
|
||||
if (deadline_ == VPX_DL_REALTIME && *iter > 0)
|
||||
EXPECT_EQ(0, (*iter - 1) % 30)
|
||||
<< "Unexpected keyframe at frame " << *iter;
|
||||
else
|
||||
EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter;
|
||||
}
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(KeyframeTest, ALL_TEST_MODES);
|
||||
} // namespace
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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 "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 {
|
||||
class LevelTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
LevelTest()
|
||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
||||
cpu_used_(GET_PARAM(2)), min_gf_internal_(24), target_level_(0),
|
||||
level_(0) {}
|
||||
virtual ~LevelTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
cfg_.g_lag_in_frames = 25;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
} else {
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
}
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_target_bitrate = 400;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||
encoder->Control(VP9E_SET_TARGET_LEVEL, target_level_);
|
||||
encoder->Control(VP9E_SET_MIN_GF_INTERVAL, min_gf_internal_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||
}
|
||||
}
|
||||
encoder->Control(VP9E_GET_LEVEL, &level_);
|
||||
ASSERT_LE(level_, 51);
|
||||
ASSERT_GE(level_, 0);
|
||||
}
|
||||
|
||||
::libvpx_test::TestMode encoding_mode_;
|
||||
int cpu_used_;
|
||||
int min_gf_internal_;
|
||||
int target_level_;
|
||||
int level_;
|
||||
};
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel11Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
60);
|
||||
target_level_ = 11;
|
||||
cfg_.rc_target_bitrate = 150;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel20Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 60);
|
||||
target_level_ = 20;
|
||||
cfg_.rc_target_bitrate = 1200;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel31Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 60);
|
||||
target_level_ = 31;
|
||||
cfg_.rc_target_bitrate = 8000;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
// Test for keeping level stats only
|
||||
TEST_P(LevelTest, TestTargetLevel0) {
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
40);
|
||||
target_level_ = 0;
|
||||
min_gf_internal_ = 4;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(11, level_);
|
||||
|
||||
cfg_.rc_target_bitrate = 1600;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(20, level_);
|
||||
}
|
||||
|
||||
// Test for level control being turned off
|
||||
TEST_P(LevelTest, TestTargetLevel255) {
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
30);
|
||||
target_level_ = 255;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevelApi) {
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, 1);
|
||||
static const vpx_codec_iface_t *codec = &vpx_codec_vp9_cx_algo;
|
||||
vpx_codec_ctx_t enc;
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(codec, &cfg, 0));
|
||||
cfg.rc_target_bitrate = 100;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, codec, &cfg, 0));
|
||||
for (int level = 0; level <= 256; ++level) {
|
||||
if (level == 10 || level == 11 || level == 20 || level == 21 ||
|
||||
level == 30 || level == 31 || level == 40 || level == 41 ||
|
||||
level == 50 || level == 51 || level == 52 || level == 60 ||
|
||||
level == 61 || level == 62 || level == 0 || level == 1 || level == 255)
|
||||
EXPECT_EQ(VPX_CODEC_OK,
|
||||
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
||||
else
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
||||
}
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(LevelTest,
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood),
|
||||
::testing::Range(0, 9));
|
||||
} // namespace
|
||||
@@ -0,0 +1,685 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <cmath>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vp9/common/vp9_loopfilter.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
// Horizontally and Vertically need 32x32: 8 Coeffs preceeding filtered section
|
||||
// 16 Coefs within filtered section
|
||||
// 8 Coeffs following filtered section
|
||||
const int kNumCoeffs = 1024;
|
||||
|
||||
const int number_of_iterations = 10000;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
typedef uint16_t Pixel;
|
||||
#define PIXEL_WIDTH 16
|
||||
|
||||
typedef void (*loop_op_t)(Pixel *s, int p, const uint8_t *blimit,
|
||||
const uint8_t *limit, const uint8_t *thresh, int bd);
|
||||
typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
|
||||
const uint8_t *limit0, const uint8_t *thresh0,
|
||||
const uint8_t *blimit1, const uint8_t *limit1,
|
||||
const uint8_t *thresh1, int bd);
|
||||
#else
|
||||
typedef uint8_t Pixel;
|
||||
#define PIXEL_WIDTH 8
|
||||
|
||||
typedef void (*loop_op_t)(Pixel *s, int p, const uint8_t *blimit,
|
||||
const uint8_t *limit, const uint8_t *thresh);
|
||||
typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
|
||||
const uint8_t *limit0, const uint8_t *thresh0,
|
||||
const uint8_t *blimit1, const uint8_t *limit1,
|
||||
const uint8_t *thresh1);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
typedef std::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
|
||||
typedef std::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
|
||||
|
||||
void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit,
|
||||
const int mask, const int32_t p, const int i) {
|
||||
uint16_t tmp_s[kNumCoeffs];
|
||||
|
||||
for (int j = 0; j < kNumCoeffs;) {
|
||||
const uint8_t val = rnd->Rand8();
|
||||
if (val & 0x80) { // 50% chance to choose a new value.
|
||||
tmp_s[j] = rnd->Rand16();
|
||||
j++;
|
||||
} else { // 50% chance to repeat previous value in row X times.
|
||||
int k = 0;
|
||||
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
|
||||
if (j < 1) {
|
||||
tmp_s[j] = rnd->Rand16();
|
||||
} else if (val & 0x20) { // Increment by a value within the limit.
|
||||
tmp_s[j] = static_cast<uint16_t>(tmp_s[j - 1] + (limit - 1));
|
||||
} else { // Decrement by a value within the limit.
|
||||
tmp_s[j] = static_cast<uint16_t>(tmp_s[j - 1] - (limit - 1));
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs;) {
|
||||
const uint8_t val = rnd->Rand8();
|
||||
if (val & 0x80) {
|
||||
j++;
|
||||
} else { // 50% chance to repeat previous value in column X times.
|
||||
int k = 0;
|
||||
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
|
||||
if (j < 1) {
|
||||
tmp_s[j] = rnd->Rand16();
|
||||
} else if (val & 0x20) { // Increment by a value within the limit.
|
||||
tmp_s[(j % 32) * 32 + j / 32] = static_cast<uint16_t>(
|
||||
tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] + (limit - 1));
|
||||
} else { // Decrement by a value within the limit.
|
||||
tmp_s[(j % 32) * 32 + j / 32] = static_cast<uint16_t>(
|
||||
tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] - (limit - 1));
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; j++) {
|
||||
if (i % 2) {
|
||||
s[j] = tmp_s[j] & mask;
|
||||
} else {
|
||||
s[j] = tmp_s[p * (j % p) + j / p] & mask;
|
||||
}
|
||||
ref_s[j] = s[j];
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GetOuterThresh(ACMRandom *rnd) {
|
||||
return static_cast<uint8_t>(rnd->RandRange(3 * MAX_LOOP_FILTER + 5));
|
||||
}
|
||||
|
||||
uint8_t GetInnerThresh(ACMRandom *rnd) {
|
||||
return static_cast<uint8_t>(rnd->RandRange(MAX_LOOP_FILTER + 1));
|
||||
}
|
||||
|
||||
uint8_t GetHevThresh(ACMRandom *rnd) {
|
||||
return static_cast<uint8_t>(rnd->RandRange(MAX_LOOP_FILTER + 1) >> 4);
|
||||
}
|
||||
|
||||
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
|
||||
public:
|
||||
virtual ~Loop8Test6Param() {}
|
||||
virtual void SetUp() {
|
||||
loopfilter_op_ = GET_PARAM(0);
|
||||
ref_loopfilter_op_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
int bit_depth_;
|
||||
int mask_;
|
||||
loop_op_t loopfilter_op_;
|
||||
loop_op_t ref_loopfilter_op_;
|
||||
};
|
||||
|
||||
class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> {
|
||||
public:
|
||||
virtual ~Loop8Test9Param() {}
|
||||
virtual void SetUp() {
|
||||
loopfilter_op_ = GET_PARAM(0);
|
||||
ref_loopfilter_op_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
int bit_depth_;
|
||||
int mask_;
|
||||
dual_loop_op_t loopfilter_op_;
|
||||
dual_loop_op_t ref_loopfilter_op_;
|
||||
};
|
||||
|
||||
TEST_P(Loop8Test6Param, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = number_of_iterations;
|
||||
const int32_t p = kNumCoeffs / 32;
|
||||
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int err_count = 0;
|
||||
uint8_t tmp = GetOuterThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
InitInput(s, ref_s, &rnd, *limit, mask_, p, i);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_));
|
||||
#else
|
||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
err_count += ref_s[j] != s[j];
|
||||
}
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Loop8Test6Param, C output doesn't match SSE2 "
|
||||
"loopfilter output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(Loop8Test6Param, ValueCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = number_of_iterations;
|
||||
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
|
||||
// NOTE: The code in vp9_loopfilter.c:update_sharpness computes mblim as a
|
||||
// function of sharpness_lvl and the loopfilter lvl as:
|
||||
// block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
|
||||
// ...
|
||||
// memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit),
|
||||
// SIMD_WIDTH);
|
||||
// This means that the largest value for mblim will occur when sharpness_lvl
|
||||
// is equal to 0, and lvl is equal to its greatest value (MAX_LOOP_FILTER).
|
||||
// In this case block_inside_limit will be equal to MAX_LOOP_FILTER and
|
||||
// therefore mblim will be equal to (2 * (lvl + 2) + block_inside_limit) =
|
||||
// 2 * (MAX_LOOP_FILTER + 2) + MAX_LOOP_FILTER = 3 * MAX_LOOP_FILTER + 4
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int err_count = 0;
|
||||
uint8_t tmp = GetOuterThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
int32_t p = kNumCoeffs / 32;
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
s[j] = rnd.Rand16() & mask_;
|
||||
ref_s[j] = s[j];
|
||||
}
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_));
|
||||
#else
|
||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
err_count += ref_s[j] != s[j];
|
||||
}
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Loop8Test6Param, C output doesn't match SSE2 "
|
||||
"loopfilter output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(Loop8Test9Param, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = number_of_iterations;
|
||||
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int err_count = 0;
|
||||
uint8_t tmp = GetOuterThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetOuterThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
int32_t p = kNumCoeffs / 32;
|
||||
const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1;
|
||||
InitInput(s, ref_s, &rnd, limit, mask_, p, i);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
|
||||
limit1, thresh1, bit_depth_);
|
||||
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
||||
thresh0, blimit1, limit1, thresh1,
|
||||
bit_depth_));
|
||||
#else
|
||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
|
||||
limit1, thresh1);
|
||||
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
||||
thresh0, blimit1, limit1, thresh1));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
err_count += ref_s[j] != s[j];
|
||||
}
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Loop8Test9Param, C output doesn't match SSE2 "
|
||||
"loopfilter output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(Loop8Test9Param, ValueCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = number_of_iterations;
|
||||
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int err_count = 0;
|
||||
uint8_t tmp = GetOuterThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetOuterThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
int32_t p = kNumCoeffs / 32; // TODO(pdlf) can we have non-square here?
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
s[j] = rnd.Rand16() & mask_;
|
||||
ref_s[j] = s[j];
|
||||
}
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
|
||||
limit1, thresh1, bit_depth_);
|
||||
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
||||
thresh0, blimit1, limit1, thresh1,
|
||||
bit_depth_));
|
||||
#else
|
||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
|
||||
limit1, thresh1);
|
||||
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
||||
thresh0, blimit1, limit1, thresh1));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
err_count += ref_s[j] != s[j];
|
||||
}
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Loop8Test9Param, C output doesn't match SSE2"
|
||||
"loopfilter output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
#if HAVE_SSE2
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Loop8Test6Param,
|
||||
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
||||
&vpx_highbd_lpf_horizontal_4_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
||||
&vpx_highbd_lpf_vertical_4_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||
&vpx_highbd_lpf_horizontal_8_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||
&vpx_highbd_lpf_horizontal_16_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_16_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||
&vpx_highbd_lpf_vertical_8_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||
&vpx_highbd_lpf_vertical_16_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
||||
&vpx_highbd_lpf_horizontal_4_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
||||
&vpx_highbd_lpf_vertical_4_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||
&vpx_highbd_lpf_horizontal_8_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||
&vpx_highbd_lpf_horizontal_16_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_16_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||
&vpx_highbd_lpf_vertical_8_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||
&vpx_highbd_lpf_vertical_16_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
||||
&vpx_highbd_lpf_horizontal_4_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
||||
&vpx_highbd_lpf_vertical_4_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||
&vpx_highbd_lpf_horizontal_8_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||
&vpx_highbd_lpf_horizontal_16_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_16_dual_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||
&vpx_highbd_lpf_vertical_8_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||
&vpx_highbd_lpf_vertical_16_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_16_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_16_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_16_dual_c, 12)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Loop8Test6Param,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_lpf_horizontal_4_sse2, &vpx_lpf_horizontal_4_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_8_sse2, &vpx_lpf_horizontal_8_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_16_dual_sse2,
|
||||
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_4_sse2, &vpx_lpf_vertical_4_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_8_sse2, &vpx_lpf_vertical_8_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_16_sse2, &vpx_lpf_vertical_16_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_16_dual_sse2, &vpx_lpf_vertical_16_dual_c,
|
||||
8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif
|
||||
|
||||
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, Loop8Test6Param,
|
||||
::testing::Values(make_tuple(&vpx_lpf_horizontal_16_avx2,
|
||||
&vpx_lpf_horizontal_16_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_16_dual_avx2,
|
||||
&vpx_lpf_horizontal_16_dual_c, 8)));
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE2
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Loop8Test9Param,
|
||||
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_4_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_8_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_4_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_8_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_4_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_8_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_4_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_8_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_4_dual_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
||||
&vpx_highbd_lpf_horizontal_8_dual_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_4_dual_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
||||
&vpx_highbd_lpf_vertical_8_dual_c, 12)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Loop8Test9Param,
|
||||
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_sse2,
|
||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_8_dual_sse2,
|
||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_4_dual_sse2,
|
||||
&vpx_lpf_vertical_4_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_8_dual_sse2,
|
||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Loop8Test6Param,
|
||||
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||
&vpx_highbd_lpf_horizontal_4_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||
&vpx_highbd_lpf_horizontal_4_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||
&vpx_highbd_lpf_horizontal_4_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||
&vpx_highbd_lpf_horizontal_8_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||
&vpx_highbd_lpf_horizontal_8_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||
&vpx_highbd_lpf_horizontal_8_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||
&vpx_highbd_lpf_horizontal_16_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||
&vpx_highbd_lpf_horizontal_16_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||
&vpx_highbd_lpf_horizontal_16_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_16_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_16_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_16_dual_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||
&vpx_highbd_lpf_vertical_4_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||
&vpx_highbd_lpf_vertical_4_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||
&vpx_highbd_lpf_vertical_4_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||
&vpx_highbd_lpf_vertical_8_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||
&vpx_highbd_lpf_vertical_8_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||
&vpx_highbd_lpf_vertical_8_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||
&vpx_highbd_lpf_vertical_16_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||
&vpx_highbd_lpf_vertical_16_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||
&vpx_highbd_lpf_vertical_16_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_16_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_16_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_16_dual_c, 12)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Loop8Test9Param,
|
||||
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_4_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_4_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_4_dual_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_8_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_8_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||
&vpx_highbd_lpf_horizontal_8_dual_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_4_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_4_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_4_dual_c, 12),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_8_dual_c, 8),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_8_dual_c, 10),
|
||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||
&vpx_highbd_lpf_vertical_8_dual_c, 12)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Loop8Test6Param,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_lpf_horizontal_16_neon, &vpx_lpf_horizontal_16_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_16_dual_neon,
|
||||
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_16_neon, &vpx_lpf_vertical_16_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_16_dual_neon, &vpx_lpf_vertical_16_dual_c,
|
||||
8),
|
||||
make_tuple(&vpx_lpf_horizontal_8_neon, &vpx_lpf_horizontal_8_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_8_neon, &vpx_lpf_vertical_8_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_4_neon, &vpx_lpf_horizontal_4_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_4_neon, &vpx_lpf_vertical_4_c, 8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Loop8Test9Param,
|
||||
::testing::Values(make_tuple(&vpx_lpf_horizontal_8_dual_neon,
|
||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_8_dual_neon,
|
||||
&vpx_lpf_vertical_8_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_4_dual_neon,
|
||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_4_dual_neon,
|
||||
&vpx_lpf_vertical_4_dual_c, 8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
DSPR2, Loop8Test6Param,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_lpf_horizontal_4_dspr2, &vpx_lpf_horizontal_4_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_8_dspr2, &vpx_lpf_horizontal_8_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_16_dspr2, &vpx_lpf_horizontal_16_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_16_dual_dspr2,
|
||||
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_4_dspr2, &vpx_lpf_vertical_4_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_8_dspr2, &vpx_lpf_vertical_8_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_16_dspr2, &vpx_lpf_vertical_16_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_16_dual_dspr2, &vpx_lpf_vertical_16_dual_c,
|
||||
8)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
DSPR2, Loop8Test9Param,
|
||||
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_dspr2,
|
||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_8_dual_dspr2,
|
||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_4_dual_dspr2,
|
||||
&vpx_lpf_vertical_4_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_8_dual_dspr2,
|
||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
||||
#endif // HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, Loop8Test6Param,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_lpf_horizontal_4_msa, &vpx_lpf_horizontal_4_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_8_msa, &vpx_lpf_horizontal_8_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_16_dual_msa,
|
||||
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_4_msa, &vpx_lpf_vertical_4_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_8_msa, &vpx_lpf_vertical_8_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_16_msa, &vpx_lpf_vertical_16_c, 8)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, Loop8Test9Param,
|
||||
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_msa,
|
||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_horizontal_8_dual_msa,
|
||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_4_dual_msa,
|
||||
&vpx_lpf_vertical_4_dual_c, 8),
|
||||
make_tuple(&vpx_lpf_vertical_8_dual_msa,
|
||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
||||
#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 VPX_TEST_MD5_HELPER_H_
|
||||
#define VPX_TEST_MD5_HELPER_H_
|
||||
|
||||
#include "./md5_utils.h"
|
||||
#include "vpx/vpx_decoder.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
class MD5 {
|
||||
public:
|
||||
MD5() { MD5Init(&md5_); }
|
||||
|
||||
void Add(const vpx_image_t *img) {
|
||||
for (int plane = 0; plane < 3; ++plane) {
|
||||
const uint8_t *buf = img->planes[plane];
|
||||
// Calculate the width and height to do the md5 check. For the chroma
|
||||
// plane, we never want to round down and thus skip a pixel so if
|
||||
// we are shifting by 1 (chroma_shift) we add 1 before doing the shift.
|
||||
// This works only for chroma_shift of 0 and 1.
|
||||
const int bytes_per_sample =
|
||||
(img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
|
||||
const int h =
|
||||
plane ? (img->d_h + img->y_chroma_shift) >> img->y_chroma_shift
|
||||
: img->d_h;
|
||||
const int w =
|
||||
(plane ? (img->d_w + img->x_chroma_shift) >> img->x_chroma_shift
|
||||
: img->d_w) *
|
||||
bytes_per_sample;
|
||||
|
||||
for (int y = 0; y < h; ++y) {
|
||||
MD5Update(&md5_, buf, w);
|
||||
buf += img->stride[plane];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Add(const uint8_t *data, size_t size) {
|
||||
MD5Update(&md5_, data, static_cast<uint32_t>(size));
|
||||
}
|
||||
|
||||
const char *Get(void) {
|
||||
static const char hex[16] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
};
|
||||
uint8_t tmp[16];
|
||||
MD5Context ctx_tmp = md5_;
|
||||
|
||||
MD5Final(tmp, &ctx_tmp);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
res_[i * 2 + 0] = hex[tmp[i] >> 4];
|
||||
res_[i * 2 + 1] = hex[tmp[i] & 0xf];
|
||||
}
|
||||
res_[32] = 0;
|
||||
|
||||
return res_;
|
||||
}
|
||||
|
||||
protected:
|
||||
char res_[33];
|
||||
MD5Context md5_;
|
||||
};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // VPX_TEST_MD5_HELPER_H_
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/register_state_check.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::libvpx_test::ACMRandom;
|
||||
|
||||
typedef void (*MinMaxFunc)(const uint8_t *a, int a_stride, const uint8_t *b,
|
||||
int b_stride, int *min, int *max);
|
||||
|
||||
class MinMaxTest : public ::testing::TestWithParam<MinMaxFunc> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
mm_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
MinMaxFunc mm_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
void reference_minmax(const uint8_t *a, int a_stride, const uint8_t *b,
|
||||
int b_stride, int *min_ret, int *max_ret) {
|
||||
int min = 255;
|
||||
int max = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
const int diff = abs(a[i * a_stride + j] - b[i * b_stride + j]);
|
||||
if (min > diff) min = diff;
|
||||
if (max < diff) max = diff;
|
||||
}
|
||||
}
|
||||
|
||||
*min_ret = min;
|
||||
*max_ret = max;
|
||||
}
|
||||
|
||||
TEST_P(MinMaxTest, MinValue) {
|
||||
for (int i = 0; i < 64; i++) {
|
||||
uint8_t a[64], b[64];
|
||||
memset(a, 0, sizeof(a));
|
||||
memset(b, 255, sizeof(b));
|
||||
b[i] = i; // Set a minimum difference of i.
|
||||
|
||||
int min, max;
|
||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
|
||||
EXPECT_EQ(255, max);
|
||||
EXPECT_EQ(i, min);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(MinMaxTest, MaxValue) {
|
||||
for (int i = 0; i < 64; i++) {
|
||||
uint8_t a[64], b[64];
|
||||
memset(a, 0, sizeof(a));
|
||||
memset(b, 0, sizeof(b));
|
||||
b[i] = i; // Set a maximum difference of i.
|
||||
|
||||
int min, max;
|
||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
|
||||
EXPECT_EQ(i, max);
|
||||
EXPECT_EQ(0, min);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(MinMaxTest, CompareReference) {
|
||||
uint8_t a[64], b[64];
|
||||
for (int j = 0; j < 64; j++) {
|
||||
a[j] = rnd_.Rand8();
|
||||
b[j] = rnd_.Rand8();
|
||||
}
|
||||
|
||||
int min_ref, max_ref, min, max;
|
||||
reference_minmax(a, 8, b, 8, &min_ref, &max_ref);
|
||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
|
||||
EXPECT_EQ(max_ref, max);
|
||||
EXPECT_EQ(min_ref, min);
|
||||
}
|
||||
|
||||
TEST_P(MinMaxTest, CompareReferenceAndVaryStride) {
|
||||
uint8_t a[8 * 64], b[8 * 64];
|
||||
for (int i = 0; i < 8 * 64; i++) {
|
||||
a[i] = rnd_.Rand8();
|
||||
b[i] = rnd_.Rand8();
|
||||
}
|
||||
for (int a_stride = 8; a_stride <= 64; a_stride += 8) {
|
||||
for (int b_stride = 8; b_stride <= 64; b_stride += 8) {
|
||||
int min_ref, max_ref, min, max;
|
||||
reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
|
||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
|
||||
EXPECT_EQ(max_ref, max)
|
||||
<< "when a_stride = " << a_stride << " and b_stride = " << b_stride;
|
||||
EXPECT_EQ(min_ref, min)
|
||||
<< "when a_stride = " << a_stride << " and b_stride = " << b_stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, MinMaxTest, ::testing::Values(&vpx_minmax_8x8_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, MinMaxTest,
|
||||
::testing::Values(&vpx_minmax_8x8_sse2));
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, MinMaxTest,
|
||||
::testing::Values(&vpx_minmax_8x8_neon));
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, MinMaxTest,
|
||||
::testing::Values(&vpx_minmax_8x8_msa));
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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 <math.h>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "vp9/encoder/vp9_non_greedy_mv.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
|
||||
namespace {
|
||||
|
||||
static void read_in_mf(const char *filename, int *rows_ptr, int *cols_ptr,
|
||||
MV **buffer_ptr) {
|
||||
FILE *input = fopen(filename, "rb");
|
||||
int row, col;
|
||||
int idx;
|
||||
|
||||
ASSERT_NE(input, nullptr) << "Cannot open file: " << filename << std::endl;
|
||||
|
||||
fscanf(input, "%d,%d\n", rows_ptr, cols_ptr);
|
||||
|
||||
*buffer_ptr = (MV *)malloc((*rows_ptr) * (*cols_ptr) * sizeof(MV));
|
||||
|
||||
for (idx = 0; idx < (*rows_ptr) * (*cols_ptr); ++idx) {
|
||||
fscanf(input, "%d,%d;", &row, &col);
|
||||
(*buffer_ptr)[idx].row = row;
|
||||
(*buffer_ptr)[idx].col = col;
|
||||
}
|
||||
fclose(input);
|
||||
}
|
||||
|
||||
static void read_in_local_var(const char *filename, int *rows_ptr,
|
||||
int *cols_ptr,
|
||||
int (**M_ptr)[MF_LOCAL_STRUCTURE_SIZE]) {
|
||||
FILE *input = fopen(filename, "rb");
|
||||
int M00, M01, M10, M11;
|
||||
int idx;
|
||||
int int_type;
|
||||
|
||||
ASSERT_NE(input, nullptr) << "Cannot open file: " << filename << std::endl;
|
||||
|
||||
fscanf(input, "%d,%d\n", rows_ptr, cols_ptr);
|
||||
|
||||
*M_ptr = (int(*)[MF_LOCAL_STRUCTURE_SIZE])malloc(
|
||||
(*rows_ptr) * (*cols_ptr) * MF_LOCAL_STRUCTURE_SIZE * sizeof(int_type));
|
||||
|
||||
for (idx = 0; idx < (*rows_ptr) * (*cols_ptr); ++idx) {
|
||||
fscanf(input, "%d,%d,%d,%d;", &M00, &M01, &M10, &M11);
|
||||
(*M_ptr)[idx][0] = M00;
|
||||
(*M_ptr)[idx][1] = M01;
|
||||
(*M_ptr)[idx][2] = M10;
|
||||
(*M_ptr)[idx][3] = M11;
|
||||
}
|
||||
fclose(input);
|
||||
}
|
||||
|
||||
static void compare_mf(const MV *mf1, const MV *mf2, int rows, int cols,
|
||||
float *mean_ptr, float *std_ptr) {
|
||||
float float_type;
|
||||
float *diffs = (float *)malloc(rows * cols * sizeof(float_type));
|
||||
int idx;
|
||||
float accu = 0.0f;
|
||||
for (idx = 0; idx < rows * cols; ++idx) {
|
||||
MV mv1 = mf1[idx];
|
||||
MV mv2 = mf2[idx];
|
||||
float row_diff2 = (float)((mv1.row - mv2.row) * (mv1.row - mv2.row));
|
||||
float col_diff2 = (float)((mv1.col - mv2.col) * (mv1.col - mv2.col));
|
||||
diffs[idx] = sqrt(row_diff2 + col_diff2);
|
||||
accu += diffs[idx];
|
||||
}
|
||||
*mean_ptr = accu / rows / cols;
|
||||
*std_ptr = 0;
|
||||
for (idx = 0; idx < rows * cols; ++idx) {
|
||||
*std_ptr += (diffs[idx] - (*mean_ptr)) * (diffs[idx] - (*mean_ptr));
|
||||
}
|
||||
*std_ptr = sqrt(*std_ptr / rows / cols);
|
||||
free(diffs);
|
||||
}
|
||||
|
||||
static void load_frame_info(const char *filename,
|
||||
YV12_BUFFER_CONFIG *ref_frame_ptr) {
|
||||
FILE *input = fopen(filename, "rb");
|
||||
int idx;
|
||||
uint8_t data_type;
|
||||
|
||||
ASSERT_NE(input, nullptr) << "Cannot open file: " << filename << std::endl;
|
||||
|
||||
fscanf(input, "%d,%d\n", &(ref_frame_ptr->y_height),
|
||||
&(ref_frame_ptr->y_width));
|
||||
|
||||
ref_frame_ptr->y_buffer = (uint8_t *)malloc(
|
||||
(ref_frame_ptr->y_width) * (ref_frame_ptr->y_height) * sizeof(data_type));
|
||||
|
||||
for (idx = 0; idx < (ref_frame_ptr->y_width) * (ref_frame_ptr->y_height);
|
||||
++idx) {
|
||||
int value;
|
||||
fscanf(input, "%d,", &value);
|
||||
ref_frame_ptr->y_buffer[idx] = (uint8_t)value;
|
||||
}
|
||||
|
||||
ref_frame_ptr->y_stride = ref_frame_ptr->y_width;
|
||||
fclose(input);
|
||||
}
|
||||
|
||||
static int compare_local_var(const int (*local_var1)[MF_LOCAL_STRUCTURE_SIZE],
|
||||
const int (*local_var2)[MF_LOCAL_STRUCTURE_SIZE],
|
||||
int rows, int cols) {
|
||||
int diff = 0;
|
||||
int outter_idx, inner_idx;
|
||||
for (outter_idx = 0; outter_idx < rows * cols; ++outter_idx) {
|
||||
for (inner_idx = 0; inner_idx < MF_LOCAL_STRUCTURE_SIZE; ++inner_idx) {
|
||||
diff += abs(local_var1[outter_idx][inner_idx] -
|
||||
local_var2[outter_idx][inner_idx]);
|
||||
}
|
||||
}
|
||||
return diff / rows / cols;
|
||||
}
|
||||
|
||||
TEST(non_greedy_mv, smooth_mf) {
|
||||
const char *search_mf_file = "non_greedy_mv_test_files/exhaust_16x16.txt";
|
||||
const char *local_var_file = "non_greedy_mv_test_files/localVar_16x16.txt";
|
||||
const char *estimation_file = "non_greedy_mv_test_files/estimation_16x16.txt";
|
||||
const char *ground_truth_file =
|
||||
"non_greedy_mv_test_files/ground_truth_16x16.txt";
|
||||
BLOCK_SIZE bsize = BLOCK_32X32;
|
||||
MV *search_mf = NULL;
|
||||
MV *smooth_mf = NULL;
|
||||
MV *estimation = NULL;
|
||||
MV *ground_truth = NULL;
|
||||
int(*local_var)[MF_LOCAL_STRUCTURE_SIZE] = NULL;
|
||||
int rows = 0, cols = 0;
|
||||
|
||||
int alpha = 100, max_iter = 100;
|
||||
|
||||
read_in_mf(search_mf_file, &rows, &cols, &search_mf);
|
||||
read_in_local_var(local_var_file, &rows, &cols, &local_var);
|
||||
read_in_mf(estimation_file, &rows, &cols, &estimation);
|
||||
read_in_mf(ground_truth_file, &rows, &cols, &ground_truth);
|
||||
|
||||
float sm_mean, sm_std;
|
||||
float est_mean, est_std;
|
||||
|
||||
smooth_mf = (MV *)malloc(rows * cols * sizeof(MV));
|
||||
vp9_get_smooth_motion_field(search_mf, local_var, rows, cols, bsize, alpha,
|
||||
max_iter, smooth_mf);
|
||||
|
||||
compare_mf(smooth_mf, ground_truth, rows, cols, &sm_mean, &sm_std);
|
||||
compare_mf(smooth_mf, estimation, rows, cols, &est_mean, &est_std);
|
||||
|
||||
EXPECT_LE(sm_mean, 3);
|
||||
EXPECT_LE(est_mean, 2);
|
||||
|
||||
free(search_mf);
|
||||
free(local_var);
|
||||
free(estimation);
|
||||
free(ground_truth);
|
||||
free(smooth_mf);
|
||||
}
|
||||
|
||||
TEST(non_greedy_mv, local_var) {
|
||||
const char *ref_frame_file = "non_greedy_mv_test_files/ref_frame_16x16.txt";
|
||||
const char *cur_frame_file = "non_greedy_mv_test_files/cur_frame_16x16.txt";
|
||||
const char *gt_local_var_file = "non_greedy_mv_test_files/localVar_16x16.txt";
|
||||
const char *search_mf_file = "non_greedy_mv_test_files/exhaust_16x16.txt";
|
||||
BLOCK_SIZE bsize = BLOCK_16X16;
|
||||
int(*gt_local_var)[MF_LOCAL_STRUCTURE_SIZE] = NULL;
|
||||
int(*est_local_var)[MF_LOCAL_STRUCTURE_SIZE] = NULL;
|
||||
YV12_BUFFER_CONFIG ref_frame, cur_frame;
|
||||
int rows, cols;
|
||||
MV *search_mf;
|
||||
int int_type;
|
||||
int local_var_diff;
|
||||
vp9_variance_fn_ptr_t fn;
|
||||
|
||||
load_frame_info(ref_frame_file, &ref_frame);
|
||||
load_frame_info(cur_frame_file, &cur_frame);
|
||||
read_in_mf(search_mf_file, &rows, &cols, &search_mf);
|
||||
|
||||
fn.sdf = vpx_sad16x16;
|
||||
est_local_var = (int(*)[MF_LOCAL_STRUCTURE_SIZE])malloc(
|
||||
rows * cols * MF_LOCAL_STRUCTURE_SIZE * sizeof(int_type));
|
||||
vp9_get_local_structure(&cur_frame, &ref_frame, search_mf, &fn, rows, cols,
|
||||
bsize, est_local_var);
|
||||
read_in_local_var(gt_local_var_file, &rows, &cols, >_local_var);
|
||||
|
||||
local_var_diff = compare_local_var(est_local_var, gt_local_var, rows, cols);
|
||||
|
||||
EXPECT_LE(local_var_diff, 1);
|
||||
|
||||
free(gt_local_var);
|
||||
free(est_local_var);
|
||||
free(ref_frame.y_buffer);
|
||||
}
|
||||
} // namespace
|
||||
@@ -0,0 +1,959 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_blockd.h"
|
||||
#include "vp9/common/vp9_scan.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
|
||||
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
typedef void (*InvTxfmWithBdFunc)(const tran_low_t *in, uint8_t *out,
|
||||
int stride, int bd);
|
||||
|
||||
template <InvTxfmFunc fn>
|
||||
void wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) {
|
||||
(void)bd;
|
||||
fn(in, out, stride);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
typedef void (*InvTxfmHighbdFunc)(const tran_low_t *in, uint16_t *out,
|
||||
int stride, int bd);
|
||||
template <InvTxfmHighbdFunc fn>
|
||||
void highbd_wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) {
|
||||
fn(in, CAST_TO_SHORTPTR(out), stride, bd);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef std::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc, TX_SIZE,
|
||||
int, int, int>
|
||||
PartialInvTxfmParam;
|
||||
const int kMaxNumCoeffs = 1024;
|
||||
const int kCountTestBlock = 1000;
|
||||
|
||||
class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
|
||||
public:
|
||||
virtual ~PartialIDctTest() {}
|
||||
virtual void SetUp() {
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
full_inv_txfm_ = GET_PARAM(1);
|
||||
partial_inv_txfm_ = GET_PARAM(2);
|
||||
tx_size_ = GET_PARAM(3);
|
||||
last_nonzero_ = GET_PARAM(4);
|
||||
bit_depth_ = GET_PARAM(5);
|
||||
pixel_size_ = GET_PARAM(6);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
|
||||
switch (tx_size_) {
|
||||
case TX_4X4: size_ = 4; break;
|
||||
case TX_8X8: size_ = 8; break;
|
||||
case TX_16X16: size_ = 16; break;
|
||||
case TX_32X32: size_ = 32; break;
|
||||
default: FAIL() << "Wrong Size!"; break;
|
||||
}
|
||||
|
||||
// Randomize stride_ to a value less than or equal to 1024
|
||||
stride_ = rnd_(1024) + 1;
|
||||
if (stride_ < size_) {
|
||||
stride_ = size_;
|
||||
}
|
||||
// Align stride_ to 16 if it's bigger than 16.
|
||||
if (stride_ > 16) {
|
||||
stride_ &= ~15;
|
||||
}
|
||||
|
||||
input_block_size_ = size_ * size_;
|
||||
output_block_size_ = size_ * stride_;
|
||||
|
||||
input_block_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*input_block_) * input_block_size_));
|
||||
output_block_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(16, pixel_size_ * output_block_size_));
|
||||
output_block_ref_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(16, pixel_size_ * output_block_size_));
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
vpx_free(input_block_);
|
||||
input_block_ = NULL;
|
||||
vpx_free(output_block_);
|
||||
output_block_ = NULL;
|
||||
vpx_free(output_block_ref_);
|
||||
output_block_ref_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
void InitMem() {
|
||||
memset(input_block_, 0, sizeof(*input_block_) * input_block_size_);
|
||||
if (pixel_size_ == 1) {
|
||||
for (int j = 0; j < output_block_size_; ++j) {
|
||||
output_block_[j] = output_block_ref_[j] = rnd_.Rand16() & mask_;
|
||||
}
|
||||
} else {
|
||||
ASSERT_EQ(2, pixel_size_);
|
||||
uint16_t *const output = reinterpret_cast<uint16_t *>(output_block_);
|
||||
uint16_t *const output_ref =
|
||||
reinterpret_cast<uint16_t *>(output_block_ref_);
|
||||
for (int j = 0; j < output_block_size_; ++j) {
|
||||
output[j] = output_ref[j] = rnd_.Rand16() & mask_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitInput() {
|
||||
const int64_t max_coeff = (32766 << (bit_depth_ - 8)) / 4;
|
||||
int64_t max_energy_leftover = max_coeff * max_coeff;
|
||||
for (int j = 0; j < last_nonzero_; ++j) {
|
||||
tran_low_t coeff = static_cast<tran_low_t>(
|
||||
sqrt(1.0 * max_energy_leftover) * (rnd_.Rand16() - 32768) / 65536);
|
||||
max_energy_leftover -= static_cast<int64_t>(coeff) * coeff;
|
||||
if (max_energy_leftover < 0) {
|
||||
max_energy_leftover = 0;
|
||||
coeff = 0;
|
||||
}
|
||||
input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = coeff;
|
||||
}
|
||||
}
|
||||
|
||||
void PrintDiff() {
|
||||
if (memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_)) {
|
||||
uint16_t ref, opt;
|
||||
for (int y = 0; y < size_; y++) {
|
||||
for (int x = 0; x < size_; x++) {
|
||||
if (pixel_size_ == 1) {
|
||||
ref = output_block_ref_[y * stride_ + x];
|
||||
opt = output_block_[y * stride_ + x];
|
||||
} else {
|
||||
ref = reinterpret_cast<uint16_t *>(
|
||||
output_block_ref_)[y * stride_ + x];
|
||||
opt = reinterpret_cast<uint16_t *>(output_block_)[y * stride_ + x];
|
||||
}
|
||||
if (ref != opt) {
|
||||
printf("dest[%d][%d] diff:%6d (ref),%6d (opt)\n", y, x, ref, opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\ninput_block_:\n");
|
||||
for (int y = 0; y < size_; y++) {
|
||||
for (int x = 0; x < size_; x++) {
|
||||
printf("%6d,", input_block_[y * size_ + x]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
int last_nonzero_;
|
||||
TX_SIZE tx_size_;
|
||||
tran_low_t *input_block_;
|
||||
uint8_t *output_block_;
|
||||
uint8_t *output_block_ref_;
|
||||
int size_;
|
||||
int stride_;
|
||||
int pixel_size_;
|
||||
int input_block_size_;
|
||||
int output_block_size_;
|
||||
int bit_depth_;
|
||||
int mask_;
|
||||
FwdTxfmFunc fwd_txfm_;
|
||||
InvTxfmWithBdFunc full_inv_txfm_;
|
||||
InvTxfmWithBdFunc partial_inv_txfm_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(PartialIDctTest, RunQuantCheck) {
|
||||
const int count_test_block = (size_ != 4) ? kCountTestBlock : 65536;
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);
|
||||
|
||||
InitMem();
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
if (size_ != 4) {
|
||||
if (i == 0) {
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = mask_;
|
||||
}
|
||||
} else if (i == 1) {
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = -mask_;
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = rnd_.Rand8() % 2 ? mask_ : -mask_;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Try all possible combinations.
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = (i & (1 << k)) ? mask_ : -mask_;
|
||||
}
|
||||
}
|
||||
|
||||
fwd_txfm_(input_extreme_block, output_ref_block, size_);
|
||||
|
||||
// quantization with minimum allowed step sizes
|
||||
input_block_[0] = (output_ref_block[0] / 4) * 4;
|
||||
for (int k = 1; k < last_nonzero_; ++k) {
|
||||
const int pos = vp9_default_scan_orders[tx_size_].scan[k];
|
||||
input_block_[pos] = (output_ref_block[pos] / 4) * 4;
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: partial inverse transform produces different results";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(PartialIDctTest, ResultsMatch) {
|
||||
for (int i = 0; i < kCountTestBlock; ++i) {
|
||||
InitMem();
|
||||
InitInput();
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: partial inverse transform produces different results";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(PartialIDctTest, AddOutputBlock) {
|
||||
for (int i = 0; i < kCountTestBlock; ++i) {
|
||||
InitMem();
|
||||
for (int j = 0; j < last_nonzero_; ++j) {
|
||||
input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = 10;
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: Transform results are not correctly added to output.";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(PartialIDctTest, SingleExtremeCoeff) {
|
||||
const int16_t max_coeff = std::numeric_limits<int16_t>::max();
|
||||
const int16_t min_coeff = std::numeric_limits<int16_t>::min();
|
||||
for (int i = 0; i < last_nonzero_; ++i) {
|
||||
memset(input_block_, 0, sizeof(*input_block_) * input_block_size_);
|
||||
// Run once for min and once for max.
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
const int coeff = j ? min_coeff : max_coeff;
|
||||
|
||||
memset(output_block_, 0, pixel_size_ * output_block_size_);
|
||||
memset(output_block_ref_, 0, pixel_size_ * output_block_size_);
|
||||
input_block_[vp9_default_scan_orders[tx_size_].scan[i]] = coeff;
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: Fails with single coeff of " << coeff << " at " << i
|
||||
<< ".";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(PartialIDctTest, DISABLED_Speed) {
|
||||
// Keep runtime stable with transform size.
|
||||
const int kCountSpeedTestBlock = 500000000 / input_block_size_;
|
||||
InitMem();
|
||||
InitInput();
|
||||
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
}
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_);
|
||||
}
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||
printf("idct%dx%d_%d (%s %d) time: %5d ms\n", size_, size_, last_nonzero_,
|
||||
(pixel_size_ == 1) ? "bitdepth" : "high bitdepth", bit_depth_,
|
||||
elapsed_time);
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: partial inverse transform produces different results";
|
||||
}
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
const PartialInvTxfmParam c_partial_idct_tests[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>, TX_32X32, 1024, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>, TX_32X32, 1024, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>, TX_32X32, 1024, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>, TX_32X32, 135, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>, TX_32X32, 135, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>, TX_32X32, 135, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_c>, TX_32X32, 34, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_c>, TX_32X32, 34, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_c>, TX_32X32, 34, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_c>, TX_32X32, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_c>, TX_32X32, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_c>, TX_32X32, 1, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>, TX_16X16, 256, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>, TX_16X16, 256, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>, TX_16X16, 256, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_c>, TX_16X16, 38, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_c>, TX_16X16, 38, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_c>, TX_16X16, 38, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_c>, TX_16X16, 10, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_c>, TX_16X16, 10, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_c>, TX_16X16, 10, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_c>, TX_16X16, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_c>, TX_16X16, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_c>, TX_16X16, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>, TX_8X8, 64, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>, TX_8X8, 64, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>, TX_8X8, 64, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>, TX_8X8, 12, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>, TX_8X8, 12, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>, TX_8X8, 12, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_c>, TX_8X8, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_c>, TX_8X8, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_c>, TX_8X8, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>, TX_4X4, 16, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>, TX_4X4, 16, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>, TX_4X4, 16, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_c>, TX_4X4, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_c>, TX_4X4, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_c>, TX_4X4, 1, 12, 2),
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_c>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_135_add_c>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_c>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_c>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_c>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_38_add_c>, TX_16X16, 38, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_c>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_c>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_c>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_c>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_c>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_c>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_c>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, PartialIDctTest,
|
||||
::testing::ValuesIn(c_partial_idct_tests));
|
||||
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_NEON
|
||||
const PartialInvTxfmParam neon_partial_idct_tests[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_neon>, TX_32X32,
|
||||
1024, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_neon>, TX_32X32,
|
||||
1024, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_neon>, TX_32X32,
|
||||
1024, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_neon>, TX_32X32, 135, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_neon>, TX_32X32, 135, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_neon>, TX_32X32, 135, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_neon>, TX_32X32, 34, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_neon>, TX_32X32, 34, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_neon>, TX_32X32, 34, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_neon>, TX_32X32, 1, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_neon>, TX_32X32, 1, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_neon>, TX_32X32, 1, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_neon>, TX_16X16, 256, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_neon>, TX_16X16, 256, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_neon>, TX_16X16, 256, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_neon>, TX_16X16, 38, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_neon>, TX_16X16, 38, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_neon>, TX_16X16, 38, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_neon>, TX_16X16, 10, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_neon>, TX_16X16, 10, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_neon>, TX_16X16, 10, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_neon>, TX_16X16, 1, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_neon>, TX_16X16, 1, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_neon>, TX_16X16, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_neon>, TX_8X8, 64, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_neon>, TX_8X8, 64, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_neon>, TX_8X8, 64, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_neon>, TX_8X8, 12, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_neon>, TX_8X8, 12, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_neon>, TX_8X8, 12, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_neon>, TX_8X8, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_neon>, TX_8X8, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_neon>, TX_8X8, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_neon>, TX_4X4, 16, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_neon>, TX_4X4, 16, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_neon>, TX_4X4, 16, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_neon>, TX_4X4, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_neon>, TX_4X4, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_neon>, TX_4X4, 1, 12, 2),
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_neon>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_135_add_c>,
|
||||
&wrapper<vpx_idct32x32_135_add_neon>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_neon>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_neon>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_neon>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_38_add_c>,
|
||||
&wrapper<vpx_idct16x16_38_add_neon>, TX_16X16, 38, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_10_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_neon>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_1_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_neon>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_neon>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_neon>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_1_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_neon>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_neon>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_1_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_neon>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, PartialIDctTest,
|
||||
::testing::ValuesIn(neon_partial_idct_tests));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_SSE2
|
||||
// 32x32_135_ is implemented using the 1024 version.
|
||||
const PartialInvTxfmParam sse2_partial_idct_tests[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse2>, TX_32X32,
|
||||
1024, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse2>, TX_32X32,
|
||||
1024, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse2>, TX_32X32,
|
||||
1024, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse2>, TX_32X32, 135, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse2>, TX_32X32, 135, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse2>, TX_32X32, 135, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse2>, TX_32X32, 34, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse2>, TX_32X32, 34, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse2>, TX_32X32, 34, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse2>, TX_16X16, 256, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse2>, TX_16X16, 256, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse2>, TX_16X16, 256, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse2>, TX_16X16, 38, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse2>, TX_16X16, 38, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse2>, TX_16X16, 38, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_sse2>, TX_16X16, 1, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_sse2>, TX_16X16, 1, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_sse2>, TX_16X16, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse2>, TX_8X8, 64, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse2>, TX_8X8, 64, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse2>, TX_8X8, 64, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_sse2>, TX_8X8, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_sse2>, TX_8X8, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_sse2>, TX_8X8, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse2>, TX_4X4, 16, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse2>, TX_4X4, 16, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse2>, TX_4X4, 16, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_sse2>, TX_4X4, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_sse2>, TX_4X4, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_sse2>, TX_4X4, 1, 12, 2),
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_sse2>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_135_add_c>,
|
||||
&wrapper<vpx_idct32x32_135_add_sse2>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_sse2>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_sse2>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_sse2>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_38_add_c>,
|
||||
&wrapper<vpx_idct16x16_38_add_sse2>, TX_16X16, 38, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_10_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_sse2>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_1_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_sse2>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_sse2>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_sse2>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_1_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_sse2>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_sse2>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_1_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_sse2>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialIDctTest,
|
||||
::testing::ValuesIn(sse2_partial_idct_tests));
|
||||
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3
|
||||
const PartialInvTxfmParam ssse3_partial_idct_tests[] = {
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_135_add_c>,
|
||||
&wrapper<vpx_idct32x32_135_add_ssse3>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_ssse3>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_ssse3>, TX_8X8, 12, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, PartialIDctTest,
|
||||
::testing::ValuesIn(ssse3_partial_idct_tests));
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH
|
||||
const PartialInvTxfmParam sse4_1_partial_idct_tests[] = {
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse4_1>, TX_32X32,
|
||||
1024, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse4_1>, TX_32X32,
|
||||
1024, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse4_1>, TX_32X32,
|
||||
1024, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse4_1>, TX_32X32,
|
||||
135, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse4_1>, TX_32X32,
|
||||
135, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse4_1>, TX_32X32,
|
||||
135, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse4_1>, TX_32X32, 34, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse4_1>, TX_32X32, 34, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse4_1>, TX_32X32, 34, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse4_1>, TX_16X16,
|
||||
256, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse4_1>, TX_16X16,
|
||||
256, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse4_1>, TX_16X16,
|
||||
256, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse4_1>, TX_16X16, 38, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse4_1>, TX_16X16, 38, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse4_1>, TX_16X16, 38, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse4_1>, TX_16X16, 10, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse4_1>, TX_16X16, 10, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse4_1>, TX_16X16, 10, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse4_1>, TX_8X8, 64, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse4_1>, TX_8X8, 64, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse4_1>, TX_8X8, 64, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse4_1>, TX_8X8, 12, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse4_1>, TX_8X8, 12, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse4_1>, TX_8X8, 12, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse4_1>, TX_4X4, 16, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse4_1>, TX_4X4, 16, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse4_1>, TX_4X4, 16, 12, 2)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE4_1, PartialIDctTest,
|
||||
::testing::ValuesIn(sse4_1_partial_idct_tests));
|
||||
#endif // HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
const PartialInvTxfmParam dspr2_partial_idct_tests[] = {
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_dspr2>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_dspr2>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_dspr2>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_dspr2>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_10_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_dspr2>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_1_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_dspr2>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_dspr2>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_dspr2>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_1_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_dspr2>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_dspr2>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_1_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_dspr2>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(DSPR2, PartialIDctTest,
|
||||
::testing::ValuesIn(dspr2_partial_idct_tests));
|
||||
#endif // HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH
|
||||
// 32x32_135_ is implemented using the 1024 version.
|
||||
const PartialInvTxfmParam msa_partial_idct_tests[] = {
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_msa>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_msa>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_msa>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_msa>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_10_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_msa>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_1_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_msa>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_msa>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_msa>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_1_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_msa>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_msa>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_1_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_msa>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialIDctTest,
|
||||
::testing::ValuesIn(msa_partial_idct_tests));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file tests the libvpx postproc example code. To add new tests to this
|
||||
## file, do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to postproc_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: Make sure input is available:
|
||||
# $VP8_IVF_FILE and $VP9_IVF_FILE are required.
|
||||
postproc_verify_environment() {
|
||||
if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs postproc using $1 as input file. $2 is the codec name, and is used
|
||||
# solely to name the output file.
|
||||
postproc() {
|
||||
local decoder="${LIBVPX_BIN_PATH}/postproc${VPX_TEST_EXE_SUFFIX}"
|
||||
local input_file="$1"
|
||||
local codec="$2"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/postproc_${codec}.raw"
|
||||
|
||||
if [ ! -x "${decoder}" ]; then
|
||||
elog "${decoder} does not exist or is not executable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
|
||||
${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
}
|
||||
|
||||
postproc_vp8() {
|
||||
if [ "$(vp8_decode_available)" = "yes" ]; then
|
||||
postproc "${VP8_IVF_FILE}" vp8 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
postproc_vp9() {
|
||||
if [ "$(vpx_config_option_enabled CONFIG_VP9_POSTPROC)" = "yes" ]; then
|
||||
if [ "$(vp9_decode_available)" = "yes" ]; then
|
||||
postproc "${VP9_IVF_FILE}" vp9 || return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
postproc_tests="postproc_vp8
|
||||
postproc_vp9"
|
||||
|
||||
run_tests postproc_verify_environment "${postproc_tests}"
|
||||
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* 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 <limits.h>
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
typedef void (*VpxPostProcDownAndAcrossMbRowFunc)(
|
||||
unsigned char *src_ptr, unsigned char *dst_ptr, int src_pixels_per_line,
|
||||
int dst_pixels_per_line, int cols, unsigned char *flimit, int size);
|
||||
|
||||
typedef void (*VpxMbPostProcAcrossIpFunc)(unsigned char *src, int pitch,
|
||||
int rows, int cols, int flimit);
|
||||
|
||||
typedef void (*VpxMbPostProcDownFunc)(unsigned char *dst, int pitch, int rows,
|
||||
int cols, int flimit);
|
||||
|
||||
namespace {
|
||||
// Compute the filter level used in post proc from the loop filter strength
|
||||
int q2mbl(int x) {
|
||||
if (x < 20) x = 20;
|
||||
|
||||
x = 50 + (x - 50) * 10 / 8;
|
||||
return x * x / 3;
|
||||
}
|
||||
|
||||
class VpxPostProcDownAndAcrossMbRowTest
|
||||
: public AbstractBench,
|
||||
public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
|
||||
public:
|
||||
VpxPostProcDownAndAcrossMbRowTest()
|
||||
: mb_post_proc_down_and_across_(GetParam()) {}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
virtual void Run();
|
||||
|
||||
const VpxPostProcDownAndAcrossMbRowFunc mb_post_proc_down_and_across_;
|
||||
// Size of the underlying data block that will be filtered.
|
||||
int block_width_;
|
||||
int block_height_;
|
||||
Buffer<uint8_t> *src_image_;
|
||||
Buffer<uint8_t> *dst_image_;
|
||||
uint8_t *flimits_;
|
||||
};
|
||||
|
||||
void VpxPostProcDownAndAcrossMbRowTest::Run() {
|
||||
mb_post_proc_down_and_across_(
|
||||
src_image_->TopLeftPixel(), dst_image_->TopLeftPixel(),
|
||||
src_image_->stride(), dst_image_->stride(), block_width_, flimits_, 16);
|
||||
}
|
||||
|
||||
// Test routine for the VPx post-processing function
|
||||
// vpx_post_proc_down_and_across_mb_row_c.
|
||||
|
||||
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
||||
// Size of the underlying data block that will be filtered.
|
||||
block_width_ = 16;
|
||||
block_height_ = 16;
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width_, block_height_, 2);
|
||||
ASSERT_TRUE(src_image.Init());
|
||||
|
||||
// Filter extends output block by 8 samples at left and right edges.
|
||||
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||
// read 16 bytes before the pointer.
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width_, block_height_, 8, 16, 8, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
|
||||
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width_));
|
||||
(void)memset(flimits_, 255, block_width_);
|
||||
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to value 1,
|
||||
// border pixels to value 10.
|
||||
src_image.SetPadding(10);
|
||||
src_image.Set(1);
|
||||
|
||||
// Initialize pixels in the output to 99.
|
||||
dst_image.Set(99);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_(
|
||||
src_image.TopLeftPixel(), dst_image.TopLeftPixel(), src_image.stride(),
|
||||
dst_image.stride(), block_width_, flimits_, 16));
|
||||
|
||||
static const uint8_t kExpectedOutput[] = { 4, 3, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 3, 4 };
|
||||
|
||||
uint8_t *pixel_ptr = dst_image.TopLeftPixel();
|
||||
for (int i = 0; i < block_height_; ++i) {
|
||||
for (int j = 0; j < block_width_; ++j) {
|
||||
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j])
|
||||
<< "at (" << i << ", " << j << ")";
|
||||
}
|
||||
pixel_ptr += dst_image.stride();
|
||||
}
|
||||
|
||||
vpx_free(flimits_);
|
||||
};
|
||||
|
||||
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
||||
// Size of the underlying data block that will be filtered.
|
||||
// Y blocks are always a multiple of 16 wide and exactly 16 high. U and V
|
||||
// blocks are always a multiple of 8 wide and exactly 8 high.
|
||||
block_width_ = 136;
|
||||
block_height_ = 16;
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
|
||||
Buffer<uint8_t> src_image =
|
||||
Buffer<uint8_t>(block_width_, block_height_, 2, 2, 10, 2);
|
||||
ASSERT_TRUE(src_image.Init());
|
||||
|
||||
// Filter extends output block by 8 samples at left and right edges.
|
||||
// Though the left padding is only 8 bytes, there is 'above' padding as well
|
||||
// so when the assembly code tries to read 16 bytes before the pointer it is
|
||||
// not a problem.
|
||||
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width_, block_height_, 8, 8, 16, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
Buffer<uint8_t> dst_image_ref =
|
||||
Buffer<uint8_t>(block_width_, block_height_, 8);
|
||||
ASSERT_TRUE(dst_image_ref.Init());
|
||||
|
||||
// Filter values are set in blocks of 16 for Y and 8 for U/V. Each macroblock
|
||||
// can have a different filter. SSE2 assembly reads flimits in blocks of 16 so
|
||||
// it must be padded out.
|
||||
const int flimits_width = block_width_ % 16 ? block_width_ + 8 : block_width_;
|
||||
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, flimits_width));
|
||||
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to random values.
|
||||
// border pixels to value 10.
|
||||
src_image.SetPadding(10);
|
||||
src_image.Set(&rnd, &ACMRandom::Rand8);
|
||||
|
||||
for (int blocks = 0; blocks < block_width_; blocks += 8) {
|
||||
(void)memset(flimits_, 0, sizeof(*flimits_) * flimits_width);
|
||||
|
||||
for (int f = 0; f < 255; f++) {
|
||||
(void)memset(flimits_ + blocks, f, sizeof(*flimits_) * 8);
|
||||
dst_image.Set(0);
|
||||
dst_image_ref.Set(0);
|
||||
|
||||
vpx_post_proc_down_and_across_mb_row_c(
|
||||
src_image.TopLeftPixel(), dst_image_ref.TopLeftPixel(),
|
||||
src_image.stride(), dst_image_ref.stride(), block_width_, flimits_,
|
||||
block_height_);
|
||||
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_(
|
||||
src_image.TopLeftPixel(), dst_image.TopLeftPixel(),
|
||||
src_image.stride(), dst_image.stride(), block_width_, flimits_,
|
||||
block_height_));
|
||||
|
||||
ASSERT_TRUE(dst_image.CheckValues(dst_image_ref));
|
||||
}
|
||||
}
|
||||
|
||||
vpx_free(flimits_);
|
||||
}
|
||||
|
||||
TEST_P(VpxPostProcDownAndAcrossMbRowTest, DISABLED_Speed) {
|
||||
// Size of the underlying data block that will be filtered.
|
||||
block_width_ = 16;
|
||||
block_height_ = 16;
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width_, block_height_, 2);
|
||||
ASSERT_TRUE(src_image.Init());
|
||||
this->src_image_ = &src_image;
|
||||
|
||||
// Filter extends output block by 8 samples at left and right edges.
|
||||
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||
// read 16 bytes before the pointer.
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width_, block_height_, 8, 16, 8, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
this->dst_image_ = &dst_image;
|
||||
|
||||
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width_));
|
||||
(void)memset(flimits_, 255, block_width_);
|
||||
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to value 1,
|
||||
// border pixels to value 10.
|
||||
src_image.SetPadding(10);
|
||||
src_image.Set(1);
|
||||
|
||||
// Initialize pixels in the output to 99.
|
||||
dst_image.Set(99);
|
||||
|
||||
RunNTimes(INT16_MAX);
|
||||
PrintMedian("16x16");
|
||||
|
||||
vpx_free(flimits_);
|
||||
};
|
||||
|
||||
class VpxMbPostProcAcrossIpTest
|
||||
: public AbstractBench,
|
||||
public ::testing::TestWithParam<VpxMbPostProcAcrossIpFunc> {
|
||||
public:
|
||||
VpxMbPostProcAcrossIpTest()
|
||||
: rows_(16), cols_(16), mb_post_proc_across_ip_(GetParam()),
|
||||
src_(Buffer<uint8_t>(rows_, cols_, 8, 8, 17, 8)) {}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
virtual void Run();
|
||||
|
||||
void SetCols(unsigned char *s, int rows, int cols, int src_width) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
s[c] = c;
|
||||
}
|
||||
s += src_width;
|
||||
}
|
||||
}
|
||||
|
||||
void RunComparison(const unsigned char *expected_output, unsigned char *src_c,
|
||||
int rows, int cols, int src_pitch) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
ASSERT_EQ(expected_output[c], src_c[c])
|
||||
<< "at (" << r << ", " << c << ")";
|
||||
}
|
||||
src_c += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width,
|
||||
int filter_level, const unsigned char *expected_output) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(s, src_width, rows, cols, filter_level));
|
||||
RunComparison(expected_output, s, rows, cols, src_width);
|
||||
}
|
||||
|
||||
const int rows_;
|
||||
const int cols_;
|
||||
const VpxMbPostProcAcrossIpFunc mb_post_proc_across_ip_;
|
||||
Buffer<uint8_t> src_;
|
||||
};
|
||||
|
||||
void VpxMbPostProcAcrossIpTest::Run() {
|
||||
mb_post_proc_across_ip_(src_.TopLeftPixel(), src_.stride(), rows_, cols_,
|
||||
q2mbl(0));
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckLowFilterOutput) {
|
||||
ASSERT_TRUE(src_.Init());
|
||||
src_.SetPadding(10);
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
Buffer<uint8_t> expected_output = Buffer<uint8_t>(cols_, rows_, 0);
|
||||
ASSERT_TRUE(expected_output.Init());
|
||||
SetCols(expected_output.TopLeftPixel(), rows_, cols_,
|
||||
expected_output.stride());
|
||||
|
||||
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(0),
|
||||
expected_output.TopLeftPixel());
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) {
|
||||
ASSERT_TRUE(src_.Init());
|
||||
src_.SetPadding(10);
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[] = {
|
||||
2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(70),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) {
|
||||
ASSERT_TRUE(src_.Init());
|
||||
src_.SetPadding(10);
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[] = {
|
||||
2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), INT_MAX,
|
||||
kExpectedOutput);
|
||||
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(100),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
|
||||
Buffer<uint8_t> c_mem = Buffer<uint8_t>(cols_, rows_, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(c_mem.Init());
|
||||
Buffer<uint8_t> asm_mem = Buffer<uint8_t>(cols_, rows_, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(asm_mem.Init());
|
||||
|
||||
// When level >= 100, the filter behaves the same as the level = INT_MAX
|
||||
// When level < 20, it behaves the same as the level = 0
|
||||
for (int level = 0; level < 100; level++) {
|
||||
c_mem.SetPadding(10);
|
||||
asm_mem.SetPadding(10);
|
||||
SetCols(c_mem.TopLeftPixel(), rows_, cols_, c_mem.stride());
|
||||
SetCols(asm_mem.TopLeftPixel(), rows_, cols_, asm_mem.stride());
|
||||
|
||||
vpx_mbpost_proc_across_ip_c(c_mem.TopLeftPixel(), c_mem.stride(), rows_,
|
||||
cols_, q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
asm_mem.TopLeftPixel(), asm_mem.stride(), rows_, cols_, q2mbl(level)));
|
||||
|
||||
ASSERT_TRUE(asm_mem.CheckValues(c_mem));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, DISABLED_Speed) {
|
||||
ASSERT_TRUE(src_.Init());
|
||||
src_.SetPadding(10);
|
||||
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
RunNTimes(100000);
|
||||
PrintMedian("16x16");
|
||||
}
|
||||
|
||||
class VpxMbPostProcDownTest
|
||||
: public AbstractBench,
|
||||
public ::testing::TestWithParam<VpxMbPostProcDownFunc> {
|
||||
public:
|
||||
VpxMbPostProcDownTest()
|
||||
: rows_(16), cols_(16), mb_post_proc_down_(GetParam()),
|
||||
src_c_(Buffer<uint8_t>(rows_, cols_, 8, 8, 8, 17)) {}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
virtual void Run();
|
||||
|
||||
void SetRows(unsigned char *src_c, int rows, int cols, int src_width) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
memset(src_c, r, cols);
|
||||
src_c += src_width;
|
||||
}
|
||||
}
|
||||
|
||||
void RunComparison(const unsigned char *expected_output, unsigned char *src_c,
|
||||
int rows, int cols, int src_pitch) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
ASSERT_EQ(expected_output[r * rows + c], src_c[c])
|
||||
<< "at (" << r << ", " << c << ")";
|
||||
}
|
||||
src_c += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width,
|
||||
int filter_level, const unsigned char *expected_output) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
mb_post_proc_down_(s, src_width, rows, cols, filter_level));
|
||||
RunComparison(expected_output, s, rows, cols, src_width);
|
||||
}
|
||||
|
||||
const int rows_;
|
||||
const int cols_;
|
||||
const VpxMbPostProcDownFunc mb_post_proc_down_;
|
||||
Buffer<uint8_t> src_c_;
|
||||
};
|
||||
|
||||
void VpxMbPostProcDownTest::Run() {
|
||||
mb_post_proc_down_(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
|
||||
q2mbl(0));
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
src_c_.SetPadding(10);
|
||||
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[] = {
|
||||
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 4, 4, 3, 3, 3,
|
||||
4, 4, 3, 4, 4, 3, 3, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 9,
|
||||
9, 8, 9, 9, 8, 8, 8, 9, 9, 10, 10, 9, 9, 9, 10, 10, 9, 10, 10,
|
||||
9, 9, 9, 10, 10, 10, 11, 10, 10, 10, 11, 10, 11, 10, 11, 10, 10, 10, 11,
|
||||
10, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 12, 11, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12,
|
||||
13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13,
|
||||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), INT_MAX,
|
||||
kExpectedOutput);
|
||||
|
||||
src_c_.SetPadding(10);
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(),
|
||||
q2mbl(100), kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
src_c_.SetPadding(10);
|
||||
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[] = {
|
||||
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 13, 12,
|
||||
13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13,
|
||||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(),
|
||||
q2mbl(70), kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) {
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
src_c_.SetPadding(10);
|
||||
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
|
||||
unsigned char *expected_output = new unsigned char[rows_ * cols_];
|
||||
ASSERT_TRUE(expected_output != NULL);
|
||||
SetRows(expected_output, rows_, cols_, cols_);
|
||||
|
||||
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), q2mbl(0),
|
||||
expected_output);
|
||||
|
||||
delete[] expected_output;
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckCvsAssembly) {
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
Buffer<uint8_t> src_asm = Buffer<uint8_t>(cols_, rows_, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_asm.Init());
|
||||
|
||||
for (int level = 0; level < 100; level++) {
|
||||
src_c_.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c_.Set(&rnd, &ACMRandom::Rand8);
|
||||
src_asm.CopyFrom(src_c_);
|
||||
|
||||
vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
|
||||
q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_(
|
||||
src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level)));
|
||||
ASSERT_TRUE(src_asm.CheckValues(src_c_));
|
||||
|
||||
src_c_.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c_.Set(&rnd, &ACMRandom::Rand8Extremes);
|
||||
src_asm.CopyFrom(src_c_);
|
||||
|
||||
vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
|
||||
q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_(
|
||||
src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level)));
|
||||
ASSERT_TRUE(src_asm.CheckValues(src_c_));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, DISABLED_Speed) {
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
src_c_.SetPadding(10);
|
||||
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
|
||||
RunNTimes(100000);
|
||||
PrintMedian("16x16");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_c));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_c));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_sse2));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_neon));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_neon));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_msa));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_msa));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_msa));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VSX, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_vsx));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VSX, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_vsx));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VSX, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_vsx));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/msvc.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using std::make_tuple;
|
||||
|
||||
typedef void (*PredictFunc)(uint8_t *src_ptr, int src_pixels_per_line,
|
||||
int xoffset, int yoffset, uint8_t *dst_ptr,
|
||||
int dst_pitch);
|
||||
|
||||
typedef std::tuple<int, int, PredictFunc> PredictParam;
|
||||
|
||||
class PredictTestBase : public AbstractBench,
|
||||
public ::testing::TestWithParam<PredictParam> {
|
||||
public:
|
||||
PredictTestBase()
|
||||
: width_(GET_PARAM(0)), height_(GET_PARAM(1)), predict_(GET_PARAM(2)),
|
||||
src_(NULL), padded_dst_(NULL), dst_(NULL), dst_c_(NULL) {}
|
||||
|
||||
virtual void SetUp() {
|
||||
src_ = new uint8_t[kSrcSize];
|
||||
ASSERT_TRUE(src_ != NULL);
|
||||
|
||||
// padded_dst_ provides a buffer of kBorderSize around the destination
|
||||
// memory to facilitate detecting out of bounds writes.
|
||||
dst_stride_ = kBorderSize + width_ + kBorderSize;
|
||||
padded_dst_size_ = dst_stride_ * (kBorderSize + height_ + kBorderSize);
|
||||
padded_dst_ =
|
||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, padded_dst_size_));
|
||||
ASSERT_TRUE(padded_dst_ != NULL);
|
||||
dst_ = padded_dst_ + (kBorderSize * dst_stride_) + kBorderSize;
|
||||
|
||||
dst_c_ = new uint8_t[16 * 16];
|
||||
ASSERT_TRUE(dst_c_ != NULL);
|
||||
|
||||
memset(src_, 0, kSrcSize);
|
||||
memset(padded_dst_, 128, padded_dst_size_);
|
||||
memset(dst_c_, 0, 16 * 16);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
delete[] src_;
|
||||
src_ = NULL;
|
||||
vpx_free(padded_dst_);
|
||||
padded_dst_ = NULL;
|
||||
dst_ = NULL;
|
||||
delete[] dst_c_;
|
||||
dst_c_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
protected:
|
||||
// Make reference arrays big enough for 16x16 functions. Six-tap filters need
|
||||
// 5 extra pixels outside of the macroblock.
|
||||
static const int kSrcStride = 21;
|
||||
static const int kSrcSize = kSrcStride * kSrcStride;
|
||||
static const int kBorderSize = 16;
|
||||
|
||||
int width_;
|
||||
int height_;
|
||||
PredictFunc predict_;
|
||||
uint8_t *src_;
|
||||
uint8_t *padded_dst_;
|
||||
uint8_t *dst_;
|
||||
int padded_dst_size_;
|
||||
uint8_t *dst_c_;
|
||||
int dst_stride_;
|
||||
|
||||
bool CompareBuffers(const uint8_t *a, int a_stride, const uint8_t *b,
|
||||
int b_stride) const {
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
EXPECT_EQ(0, memcmp(a + height * a_stride, b + height * b_stride,
|
||||
sizeof(*a) * width_))
|
||||
<< "Row " << height << " does not match.";
|
||||
}
|
||||
|
||||
return !HasFailure();
|
||||
}
|
||||
|
||||
// Given a block of memory 'a' with size 'a_size', determine if all regions
|
||||
// excepting block 'b' described by 'b_stride', 'b_height', and 'b_width'
|
||||
// match pixel value 'c'.
|
||||
bool CheckBorder(const uint8_t *a, int a_size, const uint8_t *b, int b_width,
|
||||
int b_height, int b_stride, uint8_t c) const {
|
||||
const uint8_t *a_end = a + a_size;
|
||||
const int b_size = (b_stride * b_height) + b_width;
|
||||
const uint8_t *b_end = b + b_size;
|
||||
const int left_border = (b_stride - b_width) / 2;
|
||||
const int right_border = left_border + ((b_stride - b_width) % 2);
|
||||
|
||||
EXPECT_GE(b - left_border, a) << "'b' does not start within 'a'";
|
||||
EXPECT_LE(b_end + right_border, a_end) << "'b' does not end within 'a'";
|
||||
|
||||
// Top border.
|
||||
for (int pixel = 0; pixel < b - a - left_border; ++pixel) {
|
||||
EXPECT_EQ(c, a[pixel]) << "Mismatch at " << pixel << " in top border.";
|
||||
}
|
||||
|
||||
// Left border.
|
||||
for (int height = 0; height < b_height; ++height) {
|
||||
for (int width = left_border; width > 0; --width) {
|
||||
EXPECT_EQ(c, b[height * b_stride - width])
|
||||
<< "Mismatch at row " << height << " column " << left_border - width
|
||||
<< " in left border.";
|
||||
}
|
||||
}
|
||||
|
||||
// Right border.
|
||||
for (int height = 0; height < b_height; ++height) {
|
||||
for (int width = b_width; width < b_width + right_border; ++width) {
|
||||
EXPECT_EQ(c, b[height * b_stride + width])
|
||||
<< "Mismatch at row " << height << " column " << width - b_width
|
||||
<< " in right border.";
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom border.
|
||||
for (int pixel = static_cast<int>(b - a + b_size); pixel < a_size;
|
||||
++pixel) {
|
||||
EXPECT_EQ(c, a[pixel]) << "Mismatch at " << pixel << " in bottom border.";
|
||||
}
|
||||
|
||||
return !HasFailure();
|
||||
}
|
||||
|
||||
void TestWithRandomData(PredictFunc reference) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
|
||||
// Run tests for almost all possible offsets.
|
||||
for (int xoffset = 0; xoffset < 8; ++xoffset) {
|
||||
for (int yoffset = 0; yoffset < 8; ++yoffset) {
|
||||
if (xoffset == 0 && yoffset == 0) {
|
||||
// This represents a copy which is not required to be handled by this
|
||||
// module.
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < kSrcSize; ++i) {
|
||||
src_[i] = rnd.Rand8();
|
||||
}
|
||||
reference(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset,
|
||||
dst_c_, 16);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(predict_(&src_[kSrcStride * 2 + 2], kSrcStride,
|
||||
xoffset, yoffset, dst_, dst_stride_));
|
||||
|
||||
ASSERT_TRUE(CompareBuffers(dst_c_, 16, dst_, dst_stride_));
|
||||
ASSERT_TRUE(CheckBorder(padded_dst_, padded_dst_size_, dst_, width_,
|
||||
height_, dst_stride_, 128));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TestWithUnalignedDst(PredictFunc reference) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
|
||||
// Only the 4x4 need to be able to handle unaligned writes.
|
||||
if (width_ == 4 && height_ == 4) {
|
||||
for (int xoffset = 0; xoffset < 8; ++xoffset) {
|
||||
for (int yoffset = 0; yoffset < 8; ++yoffset) {
|
||||
if (xoffset == 0 && yoffset == 0) {
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < kSrcSize; ++i) {
|
||||
src_[i] = rnd.Rand8();
|
||||
}
|
||||
reference(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset,
|
||||
dst_c_, 16);
|
||||
|
||||
for (int i = 1; i < 4; ++i) {
|
||||
memset(padded_dst_, 128, padded_dst_size_);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(predict_(&src_[kSrcStride * 2 + 2],
|
||||
kSrcStride, xoffset, yoffset,
|
||||
dst_ + i, dst_stride_ + i));
|
||||
|
||||
ASSERT_TRUE(CompareBuffers(dst_c_, 16, dst_ + i, dst_stride_ + i));
|
||||
ASSERT_TRUE(CheckBorder(padded_dst_, padded_dst_size_, dst_ + i,
|
||||
width_, height_, dst_stride_ + i, 128));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Run() {
|
||||
for (int xoffset = 0; xoffset < 8; ++xoffset) {
|
||||
for (int yoffset = 0; yoffset < 8; ++yoffset) {
|
||||
if (xoffset == 0 && yoffset == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
predict_(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset, dst_,
|
||||
dst_stride_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}; // namespace
|
||||
|
||||
class SixtapPredictTest : public PredictTestBase {};
|
||||
|
||||
TEST_P(SixtapPredictTest, TestWithRandomData) {
|
||||
TestWithRandomData(vp8_sixtap_predict16x16_c);
|
||||
}
|
||||
TEST_P(SixtapPredictTest, TestWithUnalignedDst) {
|
||||
TestWithUnalignedDst(vp8_sixtap_predict16x16_c);
|
||||
}
|
||||
|
||||
TEST_P(SixtapPredictTest, TestWithPresetData) {
|
||||
// Test input
|
||||
static const uint8_t kTestData[kSrcSize] = {
|
||||
184, 4, 191, 82, 92, 41, 0, 1, 226, 236, 172, 20, 182, 42, 226,
|
||||
177, 79, 94, 77, 179, 203, 206, 198, 22, 192, 19, 75, 17, 192, 44,
|
||||
233, 120, 48, 168, 203, 141, 210, 203, 143, 180, 184, 59, 201, 110, 102,
|
||||
171, 32, 182, 10, 109, 105, 213, 60, 47, 236, 253, 67, 55, 14, 3,
|
||||
99, 247, 124, 148, 159, 71, 34, 114, 19, 177, 38, 203, 237, 239, 58,
|
||||
83, 155, 91, 10, 166, 201, 115, 124, 5, 163, 104, 2, 231, 160, 16,
|
||||
234, 4, 8, 103, 153, 167, 174, 187, 26, 193, 109, 64, 141, 90, 48,
|
||||
200, 174, 204, 36, 184, 114, 237, 43, 238, 242, 207, 86, 245, 182, 247,
|
||||
6, 161, 251, 14, 8, 148, 182, 182, 79, 208, 120, 188, 17, 6, 23,
|
||||
65, 206, 197, 13, 242, 126, 128, 224, 170, 110, 211, 121, 197, 200, 47,
|
||||
188, 207, 208, 184, 221, 216, 76, 148, 143, 156, 100, 8, 89, 117, 14,
|
||||
112, 183, 221, 54, 197, 208, 180, 69, 176, 94, 180, 131, 215, 121, 76,
|
||||
7, 54, 28, 216, 238, 249, 176, 58, 142, 64, 215, 242, 72, 49, 104,
|
||||
87, 161, 32, 52, 216, 230, 4, 141, 44, 181, 235, 224, 57, 195, 89,
|
||||
134, 203, 144, 162, 163, 126, 156, 84, 185, 42, 148, 145, 29, 221, 194,
|
||||
134, 52, 100, 166, 105, 60, 140, 110, 201, 184, 35, 181, 153, 93, 121,
|
||||
243, 227, 68, 131, 134, 232, 2, 35, 60, 187, 77, 209, 76, 106, 174,
|
||||
15, 241, 227, 115, 151, 77, 175, 36, 187, 121, 221, 223, 47, 118, 61,
|
||||
168, 105, 32, 237, 236, 167, 213, 238, 202, 17, 170, 24, 226, 247, 131,
|
||||
145, 6, 116, 117, 121, 11, 194, 41, 48, 126, 162, 13, 93, 209, 131,
|
||||
154, 122, 237, 187, 103, 217, 99, 60, 200, 45, 78, 115, 69, 49, 106,
|
||||
200, 194, 112, 60, 56, 234, 72, 251, 19, 120, 121, 182, 134, 215, 135,
|
||||
10, 114, 2, 247, 46, 105, 209, 145, 165, 153, 191, 243, 12, 5, 36,
|
||||
119, 206, 231, 231, 11, 32, 209, 83, 27, 229, 204, 149, 155, 83, 109,
|
||||
35, 93, 223, 37, 84, 14, 142, 37, 160, 52, 191, 96, 40, 204, 101,
|
||||
77, 67, 52, 53, 43, 63, 85, 253, 147, 113, 226, 96, 6, 125, 179,
|
||||
115, 161, 17, 83, 198, 101, 98, 85, 139, 3, 137, 75, 99, 178, 23,
|
||||
201, 255, 91, 253, 52, 134, 60, 138, 131, 208, 251, 101, 48, 2, 227,
|
||||
228, 118, 132, 245, 202, 75, 91, 44, 160, 231, 47, 41, 50, 147, 220,
|
||||
74, 92, 219, 165, 89, 16
|
||||
};
|
||||
|
||||
// Expected results for xoffset = 2 and yoffset = 2.
|
||||
static const int kExpectedDstStride = 16;
|
||||
static const uint8_t kExpectedDst[256] = {
|
||||
117, 102, 74, 135, 42, 98, 175, 206, 70, 73, 222, 197, 50, 24, 39,
|
||||
49, 38, 105, 90, 47, 169, 40, 171, 215, 200, 73, 109, 141, 53, 85,
|
||||
177, 164, 79, 208, 124, 89, 212, 18, 81, 145, 151, 164, 217, 153, 91,
|
||||
154, 102, 102, 159, 75, 164, 152, 136, 51, 213, 219, 186, 116, 193, 224,
|
||||
186, 36, 231, 208, 84, 211, 155, 167, 35, 59, 42, 76, 216, 149, 73,
|
||||
201, 78, 149, 184, 100, 96, 196, 189, 198, 188, 235, 195, 117, 129, 120,
|
||||
129, 49, 25, 133, 113, 69, 221, 114, 70, 143, 99, 157, 108, 189, 140,
|
||||
78, 6, 55, 65, 240, 255, 245, 184, 72, 90, 100, 116, 131, 39, 60,
|
||||
234, 167, 33, 160, 88, 185, 200, 157, 159, 176, 127, 151, 138, 102, 168,
|
||||
106, 170, 86, 82, 219, 189, 76, 33, 115, 197, 106, 96, 198, 136, 97,
|
||||
141, 237, 151, 98, 137, 191, 185, 2, 57, 95, 142, 91, 255, 185, 97,
|
||||
137, 76, 162, 94, 173, 131, 193, 161, 81, 106, 72, 135, 222, 234, 137,
|
||||
66, 137, 106, 243, 210, 147, 95, 15, 137, 110, 85, 66, 16, 96, 167,
|
||||
147, 150, 173, 203, 140, 118, 196, 84, 147, 160, 19, 95, 101, 123, 74,
|
||||
132, 202, 82, 166, 12, 131, 166, 189, 170, 159, 85, 79, 66, 57, 152,
|
||||
132, 203, 194, 0, 1, 56, 146, 180, 224, 156, 28, 83, 181, 79, 76,
|
||||
80, 46, 160, 175, 59, 106, 43, 87, 75, 136, 85, 189, 46, 71, 200,
|
||||
90
|
||||
};
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
predict_(const_cast<uint8_t *>(kTestData) + kSrcStride * 2 + 2,
|
||||
kSrcStride, 2, 2, dst_, dst_stride_));
|
||||
|
||||
ASSERT_TRUE(
|
||||
CompareBuffers(kExpectedDst, kExpectedDstStride, dst_, dst_stride_));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_c),
|
||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_c),
|
||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_c),
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_c)));
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_neon),
|
||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_neon),
|
||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_neon),
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_neon)));
|
||||
#endif
|
||||
#if HAVE_MMX
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MMX, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(4, 4, &vp8_sixtap_predict4x4_mmx)));
|
||||
#endif
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_sse2),
|
||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_sse2),
|
||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_sse2)));
|
||||
#endif
|
||||
#if HAVE_SSSE3
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_ssse3),
|
||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_ssse3),
|
||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_ssse3),
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_ssse3)));
|
||||
#endif
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_msa),
|
||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_msa),
|
||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_msa),
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_msa)));
|
||||
#endif
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MMI, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_mmi),
|
||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_mmi),
|
||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_mmi),
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_mmi)));
|
||||
#endif
|
||||
|
||||
class BilinearPredictTest : public PredictTestBase {};
|
||||
|
||||
TEST_P(BilinearPredictTest, TestWithRandomData) {
|
||||
TestWithRandomData(vp8_bilinear_predict16x16_c);
|
||||
}
|
||||
TEST_P(BilinearPredictTest, TestWithUnalignedDst) {
|
||||
TestWithUnalignedDst(vp8_bilinear_predict16x16_c);
|
||||
}
|
||||
TEST_P(BilinearPredictTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 5000000 / (width_ * height_);
|
||||
RunNTimes(kCountSpeedTestBlock);
|
||||
|
||||
char title[16];
|
||||
snprintf(title, sizeof(title), "%dx%d", width_, height_);
|
||||
PrintMedian(title);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, BilinearPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_c),
|
||||
make_tuple(8, 8, &vp8_bilinear_predict8x8_c),
|
||||
make_tuple(8, 4, &vp8_bilinear_predict8x4_c),
|
||||
make_tuple(4, 4, &vp8_bilinear_predict4x4_c)));
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, BilinearPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_neon),
|
||||
make_tuple(8, 8, &vp8_bilinear_predict8x8_neon),
|
||||
make_tuple(8, 4, &vp8_bilinear_predict8x4_neon),
|
||||
make_tuple(4, 4, &vp8_bilinear_predict4x4_neon)));
|
||||
#endif
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, BilinearPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_sse2),
|
||||
make_tuple(8, 8, &vp8_bilinear_predict8x8_sse2),
|
||||
make_tuple(8, 4, &vp8_bilinear_predict8x4_sse2),
|
||||
make_tuple(4, 4, &vp8_bilinear_predict4x4_sse2)));
|
||||
#endif
|
||||
#if HAVE_SSSE3
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3, BilinearPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_ssse3),
|
||||
make_tuple(8, 8, &vp8_bilinear_predict8x8_ssse3)));
|
||||
#endif
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, BilinearPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_msa),
|
||||
make_tuple(8, 8, &vp8_bilinear_predict8x8_msa),
|
||||
make_tuple(8, 4, &vp8_bilinear_predict8x4_msa),
|
||||
make_tuple(4, 4, &vp8_bilinear_predict4x4_msa)));
|
||||
#endif
|
||||
} // namespace
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp8/common/blockd.h"
|
||||
#include "vp8/common/onyx.h"
|
||||
#include "vp8/encoder/block.h"
|
||||
#include "vp8/encoder/onyx_int.h"
|
||||
#include "vp8/encoder/quantize.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const int kNumBlocks = 25;
|
||||
const int kNumBlockEntries = 16;
|
||||
|
||||
typedef void (*VP8Quantize)(BLOCK *b, BLOCKD *d);
|
||||
|
||||
typedef std::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using std::make_tuple;
|
||||
|
||||
// Create and populate a VP8_COMP instance which has a complete set of
|
||||
// quantization inputs as well as a second MACROBLOCKD for output.
|
||||
class QuantizeTestBase {
|
||||
public:
|
||||
virtual ~QuantizeTestBase() {
|
||||
vp8_remove_compressor(&vp8_comp_);
|
||||
vp8_comp_ = NULL;
|
||||
vpx_free(macroblockd_dst_);
|
||||
macroblockd_dst_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetupCompressor() {
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
|
||||
// The full configuration is necessary to generate the quantization tables.
|
||||
VP8_CONFIG vp8_config;
|
||||
memset(&vp8_config, 0, sizeof(vp8_config));
|
||||
|
||||
vp8_comp_ = vp8_create_compressor(&vp8_config);
|
||||
|
||||
// Set the tables based on a quantizer of 0.
|
||||
vp8_set_quantizer(vp8_comp_, 0);
|
||||
|
||||
// Set up all the block/blockd pointers for the mb in vp8_comp_.
|
||||
vp8cx_frame_init_quantizer(vp8_comp_);
|
||||
|
||||
// Copy macroblockd from the reference to get pre-set-up dequant values.
|
||||
macroblockd_dst_ = reinterpret_cast<MACROBLOCKD *>(
|
||||
vpx_memalign(32, sizeof(*macroblockd_dst_)));
|
||||
memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd, sizeof(*macroblockd_dst_));
|
||||
// Fix block pointers - currently they point to the blocks in the reference
|
||||
// structure.
|
||||
vp8_setup_block_dptrs(macroblockd_dst_);
|
||||
}
|
||||
|
||||
void UpdateQuantizer(int q) {
|
||||
vp8_set_quantizer(vp8_comp_, q);
|
||||
|
||||
memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd, sizeof(*macroblockd_dst_));
|
||||
vp8_setup_block_dptrs(macroblockd_dst_);
|
||||
}
|
||||
|
||||
void FillCoeffConstant(int16_t c) {
|
||||
for (int i = 0; i < kNumBlocks * kNumBlockEntries; ++i) {
|
||||
vp8_comp_->mb.coeff[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void FillCoeffRandom() {
|
||||
for (int i = 0; i < kNumBlocks * kNumBlockEntries; ++i) {
|
||||
vp8_comp_->mb.coeff[i] = rnd_.Rand8();
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOutput() {
|
||||
EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.qcoeff, macroblockd_dst_->qcoeff,
|
||||
sizeof(*macroblockd_dst_->qcoeff) * kNumBlocks *
|
||||
kNumBlockEntries))
|
||||
<< "qcoeff mismatch";
|
||||
EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.dqcoeff, macroblockd_dst_->dqcoeff,
|
||||
sizeof(*macroblockd_dst_->dqcoeff) * kNumBlocks *
|
||||
kNumBlockEntries))
|
||||
<< "dqcoeff mismatch";
|
||||
EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.eobs, macroblockd_dst_->eobs,
|
||||
sizeof(*macroblockd_dst_->eobs) * kNumBlocks))
|
||||
<< "eobs mismatch";
|
||||
}
|
||||
|
||||
VP8_COMP *vp8_comp_;
|
||||
MACROBLOCKD *macroblockd_dst_;
|
||||
|
||||
private:
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
class QuantizeTest : public QuantizeTestBase,
|
||||
public ::testing::TestWithParam<VP8QuantizeParam>,
|
||||
public AbstractBench {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
SetupCompressor();
|
||||
asm_quant_ = GET_PARAM(0);
|
||||
c_quant_ = GET_PARAM(1);
|
||||
}
|
||||
|
||||
virtual void Run() {
|
||||
asm_quant_(&vp8_comp_->mb.block[0], ¯oblockd_dst_->block[0]);
|
||||
}
|
||||
|
||||
void RunComparison() {
|
||||
for (int i = 0; i < kNumBlocks; ++i) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
c_quant_(&vp8_comp_->mb.block[i], &vp8_comp_->mb.e_mbd.block[i]));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
asm_quant_(&vp8_comp_->mb.block[i], ¯oblockd_dst_->block[i]));
|
||||
}
|
||||
|
||||
CheckOutput();
|
||||
}
|
||||
|
||||
private:
|
||||
VP8Quantize asm_quant_;
|
||||
VP8Quantize c_quant_;
|
||||
};
|
||||
|
||||
TEST_P(QuantizeTest, TestZeroInput) {
|
||||
FillCoeffConstant(0);
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(QuantizeTest, TestLargeNegativeInput) {
|
||||
FillCoeffConstant(0);
|
||||
// Generate a qcoeff which contains 512/-512 (0x0100/0xFE00) to catch issues
|
||||
// like BUG=883 where the constant being compared was incorrectly initialized.
|
||||
vp8_comp_->mb.coeff[0] = -8191;
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(QuantizeTest, TestRandomInput) {
|
||||
FillCoeffRandom();
|
||||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(QuantizeTest, TestMultipleQ) {
|
||||
for (int q = 0; q < QINDEX_RANGE; ++q) {
|
||||
UpdateQuantizer(q);
|
||||
FillCoeffRandom();
|
||||
RunComparison();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(QuantizeTest, DISABLED_Speed) {
|
||||
FillCoeffRandom();
|
||||
|
||||
RunNTimes(10000000);
|
||||
PrintMedian("vp8 quantize");
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vp8_fast_quantize_b_sse2, &vp8_fast_quantize_b_c),
|
||||
make_tuple(&vp8_regular_quantize_b_sse2, &vp8_regular_quantize_b_c)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, QuantizeTest,
|
||||
::testing::Values(make_tuple(&vp8_fast_quantize_b_ssse3,
|
||||
&vp8_fast_quantize_b_c)));
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_SSE4_1
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE4_1, QuantizeTest,
|
||||
::testing::Values(make_tuple(&vp8_regular_quantize_b_sse4_1,
|
||||
&vp8_regular_quantize_b_c)));
|
||||
#endif // HAVE_SSE4_1
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, QuantizeTest,
|
||||
::testing::Values(make_tuple(&vp8_fast_quantize_b_neon,
|
||||
&vp8_fast_quantize_b_c)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vp8_fast_quantize_b_msa, &vp8_fast_quantize_b_c),
|
||||
make_tuple(&vp8_regular_quantize_b_msa, &vp8_regular_quantize_b_c)));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MMI, QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vp8_fast_quantize_b_mmi, &vp8_fast_quantize_b_c),
|
||||
make_tuple(&vp8_regular_quantize_b_mmi, &vp8_regular_quantize_b_c)));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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/codec_factory.h"
|
||||
#include "test/encode_test_driver.h"
|
||||
#include "test/util.h"
|
||||
#include "test/video_source.h"
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const int kVideoSourceWidth = 320;
|
||||
const int kVideoSourceHeight = 240;
|
||||
const int kFramesToEncode = 2;
|
||||
|
||||
class RealtimeTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
protected:
|
||||
RealtimeTest() : EncoderTest(GET_PARAM(0)), frame_packets_(0) {}
|
||||
virtual ~RealtimeTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
SetMode(::libvpx_test::kRealTime);
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
// TODO(tomfinegan): We're changing the pass value here to make sure
|
||||
// we get frames when real time mode is combined with |g_pass| set to
|
||||
// VPX_RC_FIRST_PASS. This is necessary because EncoderTest::RunLoop() sets
|
||||
// the pass value based on the mode passed into EncoderTest::SetMode(),
|
||||
// which overrides the one specified in SetUp() above.
|
||||
cfg_.g_pass = VPX_RC_FIRST_PASS;
|
||||
}
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {
|
||||
frame_packets_++;
|
||||
}
|
||||
|
||||
int frame_packets_;
|
||||
};
|
||||
|
||||
TEST_P(RealtimeTest, RealtimeFirstPassProducesFrames) {
|
||||
::libvpx_test::RandomVideoSource video;
|
||||
video.SetSize(kVideoSourceWidth, kVideoSourceHeight);
|
||||
video.set_limit(kFramesToEncode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
EXPECT_EQ(kFramesToEncode, frame_packets_);
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(RealtimeTest,
|
||||
::testing::Values(::libvpx_test::kRealTime));
|
||||
VP9_INSTANTIATE_TEST_CASE(RealtimeTest,
|
||||
::testing::Values(::libvpx_test::kRealTime));
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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 VPX_TEST_REGISTER_STATE_CHECK_H_
|
||||
#define VPX_TEST_REGISTER_STATE_CHECK_H_
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
// ASM_REGISTER_STATE_CHECK(asm_function)
|
||||
// Minimally validates the environment pre & post function execution. This
|
||||
// variant should be used with assembly functions which are not expected to
|
||||
// fully restore the system state. See platform implementations of
|
||||
// RegisterStateCheck for details.
|
||||
//
|
||||
// API_REGISTER_STATE_CHECK(api_function)
|
||||
// Performs all the checks done by ASM_REGISTER_STATE_CHECK() and any
|
||||
// additional checks to ensure the environment is in a consistent state pre &
|
||||
// post function execution. This variant should be used with API functions.
|
||||
// See platform implementations of RegisterStateCheckXXX for details.
|
||||
//
|
||||
|
||||
#if defined(_WIN64) && VPX_ARCH_X86_64
|
||||
|
||||
#undef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <winnt.h>
|
||||
|
||||
inline bool operator==(const M128A &lhs, const M128A &rhs) {
|
||||
return (lhs.Low == rhs.Low && lhs.High == rhs.High);
|
||||
}
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
// Compares the state of xmm[6-15] at construction with their state at
|
||||
// destruction. These registers should be preserved by the callee on
|
||||
// Windows x64.
|
||||
class RegisterStateCheck {
|
||||
public:
|
||||
RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); }
|
||||
~RegisterStateCheck() { Check(); }
|
||||
|
||||
private:
|
||||
static bool StoreRegisters(CONTEXT *const context) {
|
||||
const HANDLE this_thread = GetCurrentThread();
|
||||
EXPECT_TRUE(this_thread != NULL);
|
||||
context->ContextFlags = CONTEXT_FLOATING_POINT;
|
||||
const bool context_saved = GetThreadContext(this_thread, context) == TRUE;
|
||||
EXPECT_TRUE(context_saved) << "GetLastError: " << GetLastError();
|
||||
return context_saved;
|
||||
}
|
||||
|
||||
// Compares the register state. Returns true if the states match.
|
||||
void Check() const {
|
||||
ASSERT_TRUE(initialized_);
|
||||
CONTEXT post_context;
|
||||
ASSERT_TRUE(StoreRegisters(&post_context));
|
||||
|
||||
const M128A *xmm_pre = &pre_context_.Xmm6;
|
||||
const M128A *xmm_post = &post_context.Xmm6;
|
||||
for (int i = 6; i <= 15; ++i) {
|
||||
EXPECT_EQ(*xmm_pre, *xmm_post) << "xmm" << i << " has been modified!";
|
||||
++xmm_pre;
|
||||
++xmm_post;
|
||||
}
|
||||
}
|
||||
|
||||
bool initialized_;
|
||||
CONTEXT pre_context_;
|
||||
};
|
||||
|
||||
#define ASM_REGISTER_STATE_CHECK(statement) \
|
||||
do { \
|
||||
libvpx_test::RegisterStateCheck reg_check; \
|
||||
statement; \
|
||||
} while (false)
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && \
|
||||
defined(CONFIG_VP9) && !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9
|
||||
|
||||
extern "C" {
|
||||
// Save the d8-d15 registers into store.
|
||||
void vpx_push_neon(int64_t *store);
|
||||
}
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
// Compares the state of d8-d15 at construction with their state at
|
||||
// destruction. These registers should be preserved by the callee on
|
||||
// arm platform.
|
||||
class RegisterStateCheck {
|
||||
public:
|
||||
RegisterStateCheck() { vpx_push_neon(pre_store_); }
|
||||
~RegisterStateCheck() { Check(); }
|
||||
|
||||
private:
|
||||
// Compares the register state. Returns true if the states match.
|
||||
void Check() const {
|
||||
int64_t post_store[8];
|
||||
vpx_push_neon(post_store);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
EXPECT_EQ(pre_store_[i], post_store[i])
|
||||
<< "d" << i + 8 << " has been modified";
|
||||
}
|
||||
}
|
||||
|
||||
int64_t pre_store_[8];
|
||||
};
|
||||
|
||||
#define ASM_REGISTER_STATE_CHECK(statement) \
|
||||
do { \
|
||||
libvpx_test::RegisterStateCheck reg_check; \
|
||||
statement; \
|
||||
} while (false)
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#else
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
class RegisterStateCheck {};
|
||||
#define ASM_REGISTER_STATE_CHECK(statement) statement
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // _WIN64 && VPX_ARCH_X86_64
|
||||
|
||||
#if VPX_ARCH_X86 || VPX_ARCH_X86_64
|
||||
#if defined(__GNUC__)
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
// Checks the FPU tag word pre/post execution to ensure emms has been called.
|
||||
class RegisterStateCheckMMX {
|
||||
public:
|
||||
RegisterStateCheckMMX() {
|
||||
__asm__ volatile("fstenv %0" : "=rm"(pre_fpu_env_));
|
||||
}
|
||||
~RegisterStateCheckMMX() { Check(); }
|
||||
|
||||
private:
|
||||
// Checks the FPU tag word pre/post execution, returning false if not cleared
|
||||
// to 0xffff.
|
||||
void Check() const {
|
||||
EXPECT_EQ(0xffff, pre_fpu_env_[4])
|
||||
<< "FPU was in an inconsistent state prior to call";
|
||||
|
||||
uint16_t post_fpu_env[14];
|
||||
__asm__ volatile("fstenv %0" : "=rm"(post_fpu_env));
|
||||
EXPECT_EQ(0xffff, post_fpu_env[4])
|
||||
<< "FPU was left in an inconsistent state after call";
|
||||
}
|
||||
|
||||
uint16_t pre_fpu_env_[14];
|
||||
};
|
||||
|
||||
#define API_REGISTER_STATE_CHECK(statement) \
|
||||
do { \
|
||||
libvpx_test::RegisterStateCheckMMX reg_check; \
|
||||
ASM_REGISTER_STATE_CHECK(statement); \
|
||||
} while (false)
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // __GNUC__
|
||||
#endif // VPX_ARCH_X86 || VPX_ARCH_X86_64
|
||||
|
||||
#ifndef API_REGISTER_STATE_CHECK
|
||||
#define API_REGISTER_STATE_CHECK ASM_REGISTER_STATE_CHECK
|
||||
#endif
|
||||
|
||||
#endif // VPX_TEST_REGISTER_STATE_CHECK_H_
|
||||
@@ -0,0 +1,806 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#include <climits>
|
||||
#include <vector>
|
||||
#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/video_source.h"
|
||||
#include "test/util.h"
|
||||
|
||||
// Enable(1) or Disable(0) writing of the compressed bitstream.
|
||||
#define WRITE_COMPRESSED_STREAM 0
|
||||
|
||||
namespace {
|
||||
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
static void mem_put_le16(char *const mem, const unsigned int val) {
|
||||
mem[0] = val;
|
||||
mem[1] = val >> 8;
|
||||
}
|
||||
|
||||
static void mem_put_le32(char *const mem, const unsigned int val) {
|
||||
mem[0] = val;
|
||||
mem[1] = val >> 8;
|
||||
mem[2] = val >> 16;
|
||||
mem[3] = val >> 24;
|
||||
}
|
||||
|
||||
static void write_ivf_file_header(const vpx_codec_enc_cfg_t *const cfg,
|
||||
int frame_cnt, FILE *const outfile) {
|
||||
char header[32];
|
||||
|
||||
header[0] = 'D';
|
||||
header[1] = 'K';
|
||||
header[2] = 'I';
|
||||
header[3] = 'F';
|
||||
mem_put_le16(header + 4, 0); /* version */
|
||||
mem_put_le16(header + 6, 32); /* headersize */
|
||||
mem_put_le32(header + 8, 0x30395056); /* fourcc (vp9) */
|
||||
mem_put_le16(header + 12, cfg->g_w); /* width */
|
||||
mem_put_le16(header + 14, cfg->g_h); /* height */
|
||||
mem_put_le32(header + 16, cfg->g_timebase.den); /* rate */
|
||||
mem_put_le32(header + 20, cfg->g_timebase.num); /* scale */
|
||||
mem_put_le32(header + 24, frame_cnt); /* length */
|
||||
mem_put_le32(header + 28, 0); /* unused */
|
||||
|
||||
(void)fwrite(header, 1, 32, outfile);
|
||||
}
|
||||
|
||||
static void write_ivf_frame_size(FILE *const outfile, const size_t size) {
|
||||
char header[4];
|
||||
mem_put_le32(header, static_cast<unsigned int>(size));
|
||||
(void)fwrite(header, 1, 4, outfile);
|
||||
}
|
||||
|
||||
static void write_ivf_frame_header(const vpx_codec_cx_pkt_t *const pkt,
|
||||
FILE *const outfile) {
|
||||
char header[12];
|
||||
vpx_codec_pts_t pts;
|
||||
|
||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
||||
|
||||
pts = pkt->data.frame.pts;
|
||||
mem_put_le32(header, static_cast<unsigned int>(pkt->data.frame.sz));
|
||||
mem_put_le32(header + 4, pts & 0xFFFFFFFF);
|
||||
mem_put_le32(header + 8, pts >> 32);
|
||||
|
||||
(void)fwrite(header, 1, 12, outfile);
|
||||
}
|
||||
#endif // WRITE_COMPRESSED_STREAM
|
||||
|
||||
const unsigned int kInitialWidth = 320;
|
||||
const unsigned int kInitialHeight = 240;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
void ScaleForFrameNumber(unsigned int frame, unsigned int initial_w,
|
||||
unsigned int initial_h, unsigned int *w,
|
||||
unsigned int *h, bool flag_codec,
|
||||
bool smaller_width_larger_size_) {
|
||||
if (smaller_width_larger_size_) {
|
||||
if (frame < 30) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
if (frame < 100) {
|
||||
*w = initial_w * 7 / 10;
|
||||
*h = initial_h * 16 / 10;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (frame < 10) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
if (frame < 20) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 30) {
|
||||
*w = initial_w / 2;
|
||||
*h = initial_h / 2;
|
||||
return;
|
||||
}
|
||||
if (frame < 40) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
if (frame < 50) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 60) {
|
||||
*w = initial_w / 2;
|
||||
*h = initial_h / 2;
|
||||
return;
|
||||
}
|
||||
if (frame < 70) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
if (frame < 80) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 90) {
|
||||
*w = initial_w / 2;
|
||||
*h = initial_h / 2;
|
||||
return;
|
||||
}
|
||||
if (frame < 100) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 110) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
if (frame < 120) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 130) {
|
||||
*w = initial_w / 2;
|
||||
*h = initial_h / 2;
|
||||
return;
|
||||
}
|
||||
if (frame < 140) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 150) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
if (frame < 160) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 170) {
|
||||
*w = initial_w / 2;
|
||||
*h = initial_h / 2;
|
||||
return;
|
||||
}
|
||||
if (frame < 180) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 190) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
if (frame < 200) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 210) {
|
||||
*w = initial_w / 2;
|
||||
*h = initial_h / 2;
|
||||
return;
|
||||
}
|
||||
if (frame < 220) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 230) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
if (frame < 240) {
|
||||
*w = initial_w * 3 / 4;
|
||||
*h = initial_h * 3 / 4;
|
||||
return;
|
||||
}
|
||||
if (frame < 250) {
|
||||
*w = initial_w / 2;
|
||||
*h = initial_h / 2;
|
||||
return;
|
||||
}
|
||||
if (frame < 260) {
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
return;
|
||||
}
|
||||
// Go down very low.
|
||||
if (frame < 270) {
|
||||
*w = initial_w / 4;
|
||||
*h = initial_h / 4;
|
||||
return;
|
||||
}
|
||||
if (flag_codec == 1) {
|
||||
// Cases that only works for VP9.
|
||||
// For VP9: Swap width and height of original.
|
||||
if (frame < 320) {
|
||||
*w = initial_h;
|
||||
*h = initial_w;
|
||||
return;
|
||||
}
|
||||
}
|
||||
*w = initial_w;
|
||||
*h = initial_h;
|
||||
}
|
||||
|
||||
class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
|
||||
public:
|
||||
ResizingVideoSource() {
|
||||
SetSize(kInitialWidth, kInitialHeight);
|
||||
limit_ = 350;
|
||||
smaller_width_larger_size_ = false;
|
||||
}
|
||||
bool flag_codec_;
|
||||
bool smaller_width_larger_size_;
|
||||
virtual ~ResizingVideoSource() {}
|
||||
|
||||
protected:
|
||||
virtual void Next() {
|
||||
++frame_;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
ScaleForFrameNumber(frame_, kInitialWidth, kInitialHeight, &width, &height,
|
||||
flag_codec_, smaller_width_larger_size_);
|
||||
SetSize(width, height);
|
||||
FillFrame();
|
||||
}
|
||||
};
|
||||
|
||||
class ResizeTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
protected:
|
||||
ResizeTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
|
||||
virtual ~ResizeTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
ASSERT_NE(static_cast<int>(pkt->data.frame.width[0]), 0);
|
||||
ASSERT_NE(static_cast<int>(pkt->data.frame.height[0]), 0);
|
||||
encode_frame_width_.push_back(pkt->data.frame.width[0]);
|
||||
encode_frame_height_.push_back(pkt->data.frame.height[0]);
|
||||
}
|
||||
|
||||
unsigned int GetFrameWidth(size_t idx) const {
|
||||
return encode_frame_width_[idx];
|
||||
}
|
||||
|
||||
unsigned int GetFrameHeight(size_t idx) const {
|
||||
return encode_frame_height_[idx];
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
vpx_codec_pts_t pts) {
|
||||
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
|
||||
}
|
||||
|
||||
std::vector<FrameInfo> frame_info_list_;
|
||||
std::vector<unsigned int> encode_frame_width_;
|
||||
std::vector<unsigned int> encode_frame_height_;
|
||||
};
|
||||
|
||||
TEST_P(ResizeTest, TestExternalResizeWorks) {
|
||||
ResizingVideoSource video;
|
||||
video.flag_codec_ = false;
|
||||
video.smaller_width_larger_size_ = false;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
||||
info != frame_info_list_.end(); ++info) {
|
||||
const unsigned int frame = static_cast<unsigned>(info->pts);
|
||||
unsigned int expected_w;
|
||||
unsigned int expected_h;
|
||||
const size_t idx = info - frame_info_list_.begin();
|
||||
ASSERT_EQ(info->w, GetFrameWidth(idx));
|
||||
ASSERT_EQ(info->h, GetFrameHeight(idx));
|
||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||
&expected_h, video.flag_codec_,
|
||||
video.smaller_width_larger_size_);
|
||||
EXPECT_EQ(expected_w, info->w)
|
||||
<< "Frame " << frame << " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h)
|
||||
<< "Frame " << frame << " had unexpected height";
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned int kStepDownFrame = 3;
|
||||
const unsigned int kStepUpFrame = 6;
|
||||
|
||||
class ResizeInternalTest : public ResizeTest {
|
||||
protected:
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
ResizeInternalTest()
|
||||
: ResizeTest(), frame0_psnr_(0.0), outfile_(NULL), out_frames_(0) {}
|
||||
#else
|
||||
ResizeInternalTest() : ResizeTest(), frame0_psnr_(0.0) {}
|
||||
#endif
|
||||
|
||||
virtual ~ResizeInternalTest() {}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
outfile_ = fopen("vp90-2-05-resize.ivf", "wb");
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void EndPassHook() {
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
if (outfile_) {
|
||||
if (!fseek(outfile_, 0, SEEK_SET))
|
||||
write_ivf_file_header(&cfg_, out_frames_, outfile_);
|
||||
fclose(outfile_);
|
||||
outfile_ = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (change_config_) {
|
||||
int new_q = 60;
|
||||
if (video->frame() == 0) {
|
||||
struct vpx_scaling_mode mode = { VP8E_ONETWO, VP8E_ONETWO };
|
||||
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
||||
}
|
||||
if (video->frame() == 1) {
|
||||
struct vpx_scaling_mode mode = { VP8E_NORMAL, VP8E_NORMAL };
|
||||
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
||||
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = new_q;
|
||||
encoder->Config(&cfg_);
|
||||
}
|
||||
} else {
|
||||
if (video->frame() == kStepDownFrame) {
|
||||
struct vpx_scaling_mode mode = { VP8E_FOURFIVE, VP8E_THREEFIVE };
|
||||
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
||||
}
|
||||
if (video->frame() == kStepUpFrame) {
|
||||
struct vpx_scaling_mode mode = { VP8E_NORMAL, VP8E_NORMAL };
|
||||
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0];
|
||||
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
||||
}
|
||||
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
++out_frames_;
|
||||
|
||||
// Write initial file header if first frame.
|
||||
if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_);
|
||||
|
||||
// Write frame header and data.
|
||||
write_ivf_frame_header(pkt, outfile_);
|
||||
(void)fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_);
|
||||
}
|
||||
#endif
|
||||
|
||||
double frame0_psnr_;
|
||||
bool change_config_;
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
FILE *outfile_;
|
||||
unsigned int out_frames_;
|
||||
#endif
|
||||
};
|
||||
|
||||
TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 10);
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
change_config_ = false;
|
||||
|
||||
// q picked such that initial keyframe on this clip is ~30dB PSNR
|
||||
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48;
|
||||
|
||||
// If the number of frames being encoded is smaller than g_lag_in_frames
|
||||
// the encoded frame is unavailable using the current API. Comparing
|
||||
// frames to detect mismatch would then not be possible. Set
|
||||
// g_lag_in_frames = 0 to get around this.
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
||||
info != frame_info_list_.end(); ++info) {
|
||||
const vpx_codec_pts_t pts = info->pts;
|
||||
if (pts >= kStepDownFrame && pts < kStepUpFrame) {
|
||||
ASSERT_EQ(282U, info->w) << "Frame " << pts << " had unexpected width";
|
||||
ASSERT_EQ(173U, info->h) << "Frame " << pts << " had unexpected height";
|
||||
} else {
|
||||
EXPECT_EQ(352U, info->w) << "Frame " << pts << " had unexpected width";
|
||||
EXPECT_EQ(288U, info->h) << "Frame " << pts << " had unexpected height";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResizeInternalTest, TestInternalResizeChangeConfig) {
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 10);
|
||||
cfg_.g_w = 352;
|
||||
cfg_.g_h = 288;
|
||||
change_config_ = true;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
class ResizeRealtimeTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
ResizeRealtimeTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
virtual ~ResizeRealtimeTest() {}
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
}
|
||||
|
||||
if (change_bitrate_ && video->frame() == 120) {
|
||||
change_bitrate_ = false;
|
||||
cfg_.rc_target_bitrate = 500;
|
||||
encoder->Config(&cfg_);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
set_cpu_used_ = GET_PARAM(2);
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
vpx_codec_pts_t pts) {
|
||||
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
|
||||
}
|
||||
|
||||
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||
double mismatch_psnr = compute_psnr(img1, img2);
|
||||
mismatch_psnr_ += mismatch_psnr;
|
||||
++mismatch_nframes_;
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
ASSERT_NE(static_cast<int>(pkt->data.frame.width[0]), 0);
|
||||
ASSERT_NE(static_cast<int>(pkt->data.frame.height[0]), 0);
|
||||
encode_frame_width_.push_back(pkt->data.frame.width[0]);
|
||||
encode_frame_height_.push_back(pkt->data.frame.height[0]);
|
||||
}
|
||||
|
||||
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
|
||||
|
||||
unsigned int GetFrameWidth(size_t idx) const {
|
||||
return encode_frame_width_[idx];
|
||||
}
|
||||
|
||||
unsigned int GetFrameHeight(size_t idx) const {
|
||||
return encode_frame_height_[idx];
|
||||
}
|
||||
|
||||
void DefaultConfig() {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 600;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_undershoot_pct = 50;
|
||||
cfg_.rc_overshoot_pct = 50;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.kf_mode = VPX_KF_AUTO;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.kf_min_dist = cfg_.kf_max_dist = 3000;
|
||||
// Enable dropped frames.
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
// Enable error_resilience mode.
|
||||
cfg_.g_error_resilient = 1;
|
||||
// Enable dynamic resizing.
|
||||
cfg_.rc_resize_allowed = 1;
|
||||
// Run at low bitrate.
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
}
|
||||
|
||||
std::vector<FrameInfo> frame_info_list_;
|
||||
int set_cpu_used_;
|
||||
bool change_bitrate_;
|
||||
double mismatch_psnr_;
|
||||
int mismatch_nframes_;
|
||||
std::vector<unsigned int> encode_frame_width_;
|
||||
std::vector<unsigned int> encode_frame_height_;
|
||||
};
|
||||
|
||||
TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
|
||||
ResizingVideoSource video;
|
||||
video.flag_codec_ = true;
|
||||
video.smaller_width_larger_size_ = false;
|
||||
DefaultConfig();
|
||||
// Disable internal resize for this test.
|
||||
cfg_.rc_resize_allowed = 0;
|
||||
change_bitrate_ = false;
|
||||
mismatch_psnr_ = 0.0;
|
||||
mismatch_nframes_ = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
||||
info != frame_info_list_.end(); ++info) {
|
||||
const unsigned int frame = static_cast<unsigned>(info->pts);
|
||||
unsigned int expected_w;
|
||||
unsigned int expected_h;
|
||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||
&expected_h, video.flag_codec_,
|
||||
video.smaller_width_larger_size_);
|
||||
EXPECT_EQ(expected_w, info->w)
|
||||
<< "Frame " << frame << " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h)
|
||||
<< "Frame " << frame << " had unexpected height";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResizeRealtimeTest, DISABLED_TestExternalResizeSmallerWidthBiggerSize) {
|
||||
ResizingVideoSource video;
|
||||
video.flag_codec_ = true;
|
||||
video.smaller_width_larger_size_ = true;
|
||||
DefaultConfig();
|
||||
// Disable internal resize for this test.
|
||||
cfg_.rc_resize_allowed = 0;
|
||||
change_bitrate_ = false;
|
||||
mismatch_psnr_ = 0.0;
|
||||
mismatch_nframes_ = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
||||
info != frame_info_list_.end(); ++info) {
|
||||
const unsigned int frame = static_cast<unsigned>(info->pts);
|
||||
unsigned int expected_w;
|
||||
unsigned int expected_h;
|
||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||
&expected_h, video.flag_codec_,
|
||||
video.smaller_width_larger_size_);
|
||||
EXPECT_EQ(expected_w, info->w)
|
||||
<< "Frame " << frame << " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h)
|
||||
<< "Frame " << frame << " had unexpected height";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the dynamic resizer behavior for real time, 1 pass CBR mode.
|
||||
// Run at low bitrate, with resize_allowed = 1, and verify that we get
|
||||
// one resize down event.
|
||||
TEST_P(ResizeRealtimeTest, TestInternalResizeDown) {
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 299);
|
||||
DefaultConfig();
|
||||
cfg_.g_w = 352;
|
||||
cfg_.g_h = 288;
|
||||
change_bitrate_ = false;
|
||||
mismatch_psnr_ = 0.0;
|
||||
mismatch_nframes_ = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
unsigned int last_w = cfg_.g_w;
|
||||
unsigned int last_h = cfg_.g_h;
|
||||
int resize_count = 0;
|
||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
||||
info != frame_info_list_.end(); ++info) {
|
||||
if (info->w != last_w || info->h != last_h) {
|
||||
// Verify that resize down occurs.
|
||||
ASSERT_LT(info->w, last_w);
|
||||
ASSERT_LT(info->h, last_h);
|
||||
last_w = info->w;
|
||||
last_h = info->h;
|
||||
resize_count++;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Verify that we get 1 resize down event in this test.
|
||||
ASSERT_EQ(1, resize_count) << "Resizing should occur.";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
#else
|
||||
printf("Warning: VP9 decoder unavailable, unable to check resize count!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Verify the dynamic resizer behavior for real time, 1 pass CBR mode.
|
||||
// Start at low target bitrate, raise the bitrate in the middle of the clip,
|
||||
// scaling-up should occur after bitrate changed.
|
||||
TEST_P(ResizeRealtimeTest, TestInternalResizeDownUpChangeBitRate) {
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 359);
|
||||
DefaultConfig();
|
||||
cfg_.g_w = 352;
|
||||
cfg_.g_h = 288;
|
||||
change_bitrate_ = true;
|
||||
mismatch_psnr_ = 0.0;
|
||||
mismatch_nframes_ = 0;
|
||||
// Disable dropped frames.
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
// Starting bitrate low.
|
||||
cfg_.rc_target_bitrate = 80;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
unsigned int last_w = cfg_.g_w;
|
||||
unsigned int last_h = cfg_.g_h;
|
||||
int resize_count = 0;
|
||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
||||
info != frame_info_list_.end(); ++info) {
|
||||
const size_t idx = info - frame_info_list_.begin();
|
||||
ASSERT_EQ(info->w, GetFrameWidth(idx));
|
||||
ASSERT_EQ(info->h, GetFrameHeight(idx));
|
||||
if (info->w != last_w || info->h != last_h) {
|
||||
resize_count++;
|
||||
if (resize_count == 1) {
|
||||
// Verify that resize down occurs.
|
||||
ASSERT_LT(info->w, last_w);
|
||||
ASSERT_LT(info->h, last_h);
|
||||
} else if (resize_count == 2) {
|
||||
// Verify that resize up occurs.
|
||||
ASSERT_GT(info->w, last_w);
|
||||
ASSERT_GT(info->h, last_h);
|
||||
}
|
||||
last_w = info->w;
|
||||
last_h = info->h;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Verify that we get 2 resize events in this test.
|
||||
ASSERT_EQ(resize_count, 2) << "Resizing should occur twice.";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
#else
|
||||
printf("Warning: VP9 decoder unavailable, unable to check resize count!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
vpx_img_fmt_t CspForFrameNumber(int frame) {
|
||||
if (frame < 10) return VPX_IMG_FMT_I420;
|
||||
if (frame < 20) return VPX_IMG_FMT_I444;
|
||||
return VPX_IMG_FMT_I420;
|
||||
}
|
||||
|
||||
class ResizeCspTest : public ResizeTest {
|
||||
protected:
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
ResizeCspTest()
|
||||
: ResizeTest(), frame0_psnr_(0.0), outfile_(NULL), out_frames_(0) {}
|
||||
#else
|
||||
ResizeCspTest() : ResizeTest(), frame0_psnr_(0.0) {}
|
||||
#endif
|
||||
|
||||
virtual ~ResizeCspTest() {}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
outfile_ = fopen("vp91-2-05-cspchape.ivf", "wb");
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void EndPassHook() {
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
if (outfile_) {
|
||||
if (!fseek(outfile_, 0, SEEK_SET))
|
||||
write_ivf_file_header(&cfg_, out_frames_, outfile_);
|
||||
fclose(outfile_);
|
||||
outfile_ = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (CspForFrameNumber(video->frame()) != VPX_IMG_FMT_I420 &&
|
||||
cfg_.g_profile != 1) {
|
||||
cfg_.g_profile = 1;
|
||||
encoder->Config(&cfg_);
|
||||
}
|
||||
if (CspForFrameNumber(video->frame()) == VPX_IMG_FMT_I420 &&
|
||||
cfg_.g_profile != 0) {
|
||||
cfg_.g_profile = 0;
|
||||
encoder->Config(&cfg_);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0];
|
||||
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
||||
}
|
||||
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
++out_frames_;
|
||||
|
||||
// Write initial file header if first frame.
|
||||
if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_);
|
||||
|
||||
// Write frame header and data.
|
||||
write_ivf_frame_header(pkt, outfile_);
|
||||
(void)fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_);
|
||||
}
|
||||
#endif
|
||||
|
||||
double frame0_psnr_;
|
||||
#if WRITE_COMPRESSED_STREAM
|
||||
FILE *outfile_;
|
||||
unsigned int out_frames_;
|
||||
#endif
|
||||
};
|
||||
|
||||
class ResizingCspVideoSource : public ::libvpx_test::DummyVideoSource {
|
||||
public:
|
||||
ResizingCspVideoSource() {
|
||||
SetSize(kInitialWidth, kInitialHeight);
|
||||
limit_ = 30;
|
||||
}
|
||||
|
||||
virtual ~ResizingCspVideoSource() {}
|
||||
|
||||
protected:
|
||||
virtual void Next() {
|
||||
++frame_;
|
||||
SetImageFormat(CspForFrameNumber(frame_));
|
||||
FillFrame();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(ResizeCspTest, TestResizeCspWorks) {
|
||||
ResizingCspVideoSource video;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(ResizeTest, ONE_PASS_TEST_MODES);
|
||||
VP9_INSTANTIATE_TEST_CASE(ResizeTest,
|
||||
::testing::Values(::libvpx_test::kRealTime));
|
||||
VP9_INSTANTIATE_TEST_CASE(ResizeInternalTest,
|
||||
::testing::Values(::libvpx_test::kOnePassBest));
|
||||
VP9_INSTANTIATE_TEST_CASE(ResizeRealtimeTest,
|
||||
::testing::Values(::libvpx_test::kRealTime),
|
||||
::testing::Range(5, 9));
|
||||
VP9_INSTANTIATE_TEST_CASE(ResizeCspTest,
|
||||
::testing::Values(::libvpx_test::kRealTime));
|
||||
} // namespace
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file tests the libvpx resize_util example code. To add new tests to
|
||||
## this file, do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to resize_util_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: $YUV_RAW_INPUT is required.
|
||||
resize_util_verify_environment() {
|
||||
if [ ! -e "${YUV_RAW_INPUT}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Resizes $YUV_RAW_INPUT using the resize_util example. $1 is the output
|
||||
# dimensions that will be passed to resize_util.
|
||||
resize_util() {
|
||||
local resizer="${LIBVPX_BIN_PATH}/resize_util${VPX_TEST_EXE_SUFFIX}"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/resize_util.raw"
|
||||
local frames_to_resize="10"
|
||||
local target_dimensions="$1"
|
||||
|
||||
# resize_util is available only when CONFIG_SHARED is disabled.
|
||||
if [ -z "$(vpx_config_option_enabled CONFIG_SHARED)" ]; then
|
||||
if [ ! -x "${resizer}" ]; then
|
||||
elog "${resizer} does not exist or is not executable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${resizer}" "${YUV_RAW_INPUT}" \
|
||||
"${YUV_RAW_INPUT_WIDTH}x${YUV_RAW_INPUT_HEIGHT}" \
|
||||
"${target_dimensions}" "${output_file}" ${frames_to_resize} \
|
||||
${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Halves each dimension of $YUV_RAW_INPUT using resize_util().
|
||||
resize_down() {
|
||||
local target_width=$((${YUV_RAW_INPUT_WIDTH} / 2))
|
||||
local target_height=$((${YUV_RAW_INPUT_HEIGHT} / 2))
|
||||
|
||||
resize_util "${target_width}x${target_height}"
|
||||
}
|
||||
|
||||
# Doubles each dimension of $YUV_RAW_INPUT using resize_util().
|
||||
resize_up() {
|
||||
local target_width=$((${YUV_RAW_INPUT_WIDTH} * 2))
|
||||
local target_height=$((${YUV_RAW_INPUT_HEIGHT} * 2))
|
||||
|
||||
resize_util "${target_width}x${target_height}"
|
||||
}
|
||||
|
||||
resize_util_tests="resize_down
|
||||
resize_up"
|
||||
|
||||
run_tests resize_util_verify_environment "${resize_util_tests}"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file tests the libvpx set_maps example. To add new tests to this file,
|
||||
## do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to set_maps_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: $YUV_RAW_INPUT is required, and set_maps must exist in
|
||||
# $LIBVPX_BIN_PATH.
|
||||
set_maps_verify_environment() {
|
||||
if [ ! -e "${YUV_RAW_INPUT}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$(vpx_tool_path set_maps)" ]; then
|
||||
elog "set_maps not found. It must exist in LIBVPX_BIN_PATH or its parent."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs set_maps using the codec specified by $1.
|
||||
set_maps() {
|
||||
local encoder="$(vpx_tool_path set_maps)"
|
||||
local codec="$1"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/set_maps_${codec}.ivf"
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
|
||||
${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
}
|
||||
|
||||
set_maps_vp8() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
set_maps vp8 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
set_maps_vp9() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
set_maps vp9 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
set_maps_tests="set_maps_vp8
|
||||
set_maps_vp9"
|
||||
|
||||
run_tests set_maps_verify_environment "${set_maps_tests}"
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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 <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "vp8/encoder/onyx_int.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(VP8RoiMapTest, ParameterCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
int delta_q[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 };
|
||||
int delta_lf[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 };
|
||||
unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 };
|
||||
|
||||
const int internalq_trans[] = {
|
||||
0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19,
|
||||
20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 35, 37, 39, 41,
|
||||
43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 64, 67, 70, 73, 76, 79,
|
||||
82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127,
|
||||
};
|
||||
|
||||
// Initialize elements of cpi with valid defaults.
|
||||
VP8_COMP cpi;
|
||||
cpi.mb.e_mbd.mb_segement_abs_delta = SEGMENT_DELTADATA;
|
||||
cpi.cyclic_refresh_mode_enabled = 0;
|
||||
cpi.mb.e_mbd.segmentation_enabled = 0;
|
||||
cpi.mb.e_mbd.update_mb_segmentation_map = 0;
|
||||
cpi.mb.e_mbd.update_mb_segmentation_data = 0;
|
||||
cpi.common.mb_rows = 240 >> 4;
|
||||
cpi.common.mb_cols = 320 >> 4;
|
||||
const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols);
|
||||
memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data));
|
||||
|
||||
// Segment map
|
||||
cpi.segmentation_map = reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
|
||||
|
||||
// Allocate memory for the source memory map.
|
||||
unsigned char *roi_map =
|
||||
reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
|
||||
memset(&roi_map[mbs >> 2], 1, (mbs >> 2));
|
||||
memset(&roi_map[mbs >> 1], 2, (mbs >> 2));
|
||||
memset(&roi_map[mbs - (mbs >> 2)], 3, (mbs >> 2));
|
||||
|
||||
// Do a test call with valid parameters.
|
||||
int roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||
delta_q, delta_lf, threshold);
|
||||
EXPECT_EQ(0, roi_retval)
|
||||
<< "vp8_set_roimap roi failed with default test parameters";
|
||||
|
||||
// Check that the values in the cpi structure get set as expected.
|
||||
if (roi_retval == 0) {
|
||||
// Check that the segment map got set.
|
||||
const int mapcompare = memcmp(roi_map, cpi.segmentation_map, mbs);
|
||||
EXPECT_EQ(0, mapcompare) << "segment map error";
|
||||
|
||||
// Check the q deltas (note the need to translate into
|
||||
// the interanl range of 0-127.
|
||||
for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
|
||||
const int transq = internalq_trans[abs(delta_q[i])];
|
||||
if (abs(cpi.segment_feature_data[MB_LVL_ALT_Q][i]) != transq) {
|
||||
EXPECT_EQ(transq, cpi.segment_feature_data[MB_LVL_ALT_Q][i])
|
||||
<< "segment delta_q error";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the loop filter deltas
|
||||
for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
|
||||
if (cpi.segment_feature_data[MB_LVL_ALT_LF][i] != delta_lf[i]) {
|
||||
EXPECT_EQ(delta_lf[i], cpi.segment_feature_data[MB_LVL_ALT_LF][i])
|
||||
<< "segment delta_lf error";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the breakout thresholds
|
||||
for (int i = 0; i < MAX_MB_SEGMENTS; ++i) {
|
||||
unsigned int breakout =
|
||||
static_cast<unsigned int>(cpi.segment_encode_breakout[i]);
|
||||
|
||||
if (threshold[i] != breakout) {
|
||||
EXPECT_EQ(threshold[i], breakout) << "breakout threshold error";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Segmentation, and segmentation update flages should be set.
|
||||
EXPECT_EQ(1, cpi.mb.e_mbd.segmentation_enabled)
|
||||
<< "segmentation_enabled error";
|
||||
EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_map)
|
||||
<< "update_mb_segmentation_map error";
|
||||
EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data)
|
||||
<< "update_mb_segmentation_data error";
|
||||
|
||||
// Try a range of delta q and lf parameters (some legal, some not)
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
int rand_deltas[4];
|
||||
int deltas_valid;
|
||||
rand_deltas[0] = rnd(160) - 80;
|
||||
rand_deltas[1] = rnd(160) - 80;
|
||||
rand_deltas[2] = rnd(160) - 80;
|
||||
rand_deltas[3] = rnd(160) - 80;
|
||||
|
||||
deltas_valid =
|
||||
((abs(rand_deltas[0]) <= 63) && (abs(rand_deltas[1]) <= 63) &&
|
||||
(abs(rand_deltas[2]) <= 63) && (abs(rand_deltas[3]) <= 63))
|
||||
? 0
|
||||
: -1;
|
||||
|
||||
// Test with random delta q values.
|
||||
roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||
rand_deltas, delta_lf, threshold);
|
||||
EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error";
|
||||
|
||||
// One delta_q error shown at a time
|
||||
if (deltas_valid != roi_retval) break;
|
||||
|
||||
// Test with random loop filter values.
|
||||
roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||
delta_q, rand_deltas, threshold);
|
||||
EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error";
|
||||
|
||||
// One delta loop filter error shown at a time
|
||||
if (deltas_valid != roi_retval) break;
|
||||
}
|
||||
|
||||
// Test invalid number of rows or colums.
|
||||
roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
|
||||
cpi.common.mb_cols, delta_q, delta_lf, threshold);
|
||||
EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error";
|
||||
|
||||
roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
|
||||
cpi.common.mb_cols - 1, delta_q, delta_lf, threshold);
|
||||
EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error";
|
||||
}
|
||||
|
||||
// Free allocated memory
|
||||
if (cpi.segmentation_map) vpx_free(cpi.segmentation_map);
|
||||
if (roi_map) vpx_free(roi_map);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file tests the libvpx simple_decoder example code. To add new tests to
|
||||
## this file, do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to simple_decoder_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: Make sure input is available:
|
||||
# $VP8_IVF_FILE and $VP9_IVF_FILE are required.
|
||||
simple_decoder_verify_environment() {
|
||||
if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs simple_decoder using $1 as input file. $2 is the codec name, and is used
|
||||
# solely to name the output file.
|
||||
simple_decoder() {
|
||||
local decoder="${LIBVPX_BIN_PATH}/simple_decoder${VPX_TEST_EXE_SUFFIX}"
|
||||
local input_file="$1"
|
||||
local codec="$2"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/simple_decoder_${codec}.raw"
|
||||
|
||||
if [ ! -x "${decoder}" ]; then
|
||||
elog "${decoder} does not exist or is not executable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
|
||||
${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
}
|
||||
|
||||
simple_decoder_vp8() {
|
||||
if [ "$(vp8_decode_available)" = "yes" ]; then
|
||||
simple_decoder "${VP8_IVF_FILE}" vp8 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
simple_decoder_vp9() {
|
||||
if [ "$(vp9_decode_available)" = "yes" ]; then
|
||||
simple_decoder "${VP9_IVF_FILE}" vp9 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
simple_decoder_tests="simple_decoder_vp8
|
||||
simple_decoder_vp9"
|
||||
|
||||
run_tests simple_decoder_verify_environment "${simple_decoder_tests}"
|
||||
@@ -0,0 +1,172 @@
|
||||
#include <math.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "vp9/simple_encode.h"
|
||||
|
||||
namespace vp9 {
|
||||
namespace {
|
||||
|
||||
// TODO(angirbid): Find a better way to construct encode info
|
||||
const int w = 352;
|
||||
const int h = 288;
|
||||
const int frame_rate_num = 30;
|
||||
const int frame_rate_den = 1;
|
||||
const int target_bitrate = 1000;
|
||||
const int num_frames = 17;
|
||||
const char infile_path[] = "bus_352x288_420_f20_b8.yuv";
|
||||
|
||||
double GetBitrateInKbps(size_t bit_size, int num_frames, int frame_rate_num,
|
||||
int frame_rate_den) {
|
||||
return static_cast<double>(bit_size) / num_frames * frame_rate_num /
|
||||
frame_rate_den / 1000.0;
|
||||
}
|
||||
|
||||
TEST(SimpleEncode, ComputeFirstPassStats) {
|
||||
SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
|
||||
target_bitrate, num_frames, infile_path);
|
||||
simple_encode.ComputeFirstPassStats();
|
||||
std::vector<std::vector<double>> frame_stats =
|
||||
simple_encode.ObserveFirstPassStats();
|
||||
EXPECT_EQ(frame_stats.size(), static_cast<size_t>(num_frames));
|
||||
size_t data_num = frame_stats[0].size();
|
||||
// Read ObserveFirstPassStats before changing FIRSTPASS_STATS.
|
||||
EXPECT_EQ(data_num, static_cast<size_t>(25));
|
||||
for (size_t i = 0; i < frame_stats.size(); ++i) {
|
||||
EXPECT_EQ(frame_stats[i].size(), data_num);
|
||||
// FIRSTPASS_STATS's first element is frame
|
||||
EXPECT_EQ(frame_stats[i][0], i);
|
||||
// FIRSTPASS_STATS's last element is count, and the count is 1 for single
|
||||
// frame stats
|
||||
EXPECT_EQ(frame_stats[i][data_num - 1], 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SimpleEncode, GetCodingFrameNum) {
|
||||
SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
|
||||
target_bitrate, num_frames, infile_path);
|
||||
simple_encode.ComputeFirstPassStats();
|
||||
int num_coding_frames = simple_encode.GetCodingFrameNum();
|
||||
EXPECT_EQ(num_coding_frames, 19);
|
||||
}
|
||||
|
||||
TEST(SimpleEncode, EncodeFrame) {
|
||||
SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
|
||||
target_bitrate, num_frames, infile_path);
|
||||
simple_encode.ComputeFirstPassStats();
|
||||
int num_coding_frames = simple_encode.GetCodingFrameNum();
|
||||
EXPECT_GE(num_coding_frames, num_frames);
|
||||
// The coding frames include actual show frames and alternate reference
|
||||
// frames, i.e. no show frame.
|
||||
int ref_num_alternate_refereces = num_coding_frames - num_frames;
|
||||
int num_alternate_refereces = 0;
|
||||
simple_encode.StartEncode();
|
||||
size_t total_data_bit_size = 0;
|
||||
for (int i = 0; i < num_coding_frames; ++i) {
|
||||
EncodeFrameResult encode_frame_result;
|
||||
simple_encode.EncodeFrame(&encode_frame_result);
|
||||
if (i == 0) {
|
||||
EXPECT_EQ(encode_frame_result.show_idx, 0);
|
||||
EXPECT_EQ(encode_frame_result.frame_type, kKeyFrame)
|
||||
<< "The first coding frame should be key frame";
|
||||
}
|
||||
if (encode_frame_result.frame_type == kAlternateReference) {
|
||||
++num_alternate_refereces;
|
||||
}
|
||||
EXPECT_GE(encode_frame_result.show_idx, 0);
|
||||
EXPECT_LT(encode_frame_result.show_idx, num_frames);
|
||||
if (i == num_coding_frames - 1) {
|
||||
EXPECT_EQ(encode_frame_result.show_idx, num_frames - 1)
|
||||
<< "The last coding frame should be the last display order";
|
||||
}
|
||||
EXPECT_GE(encode_frame_result.psnr, 34)
|
||||
<< "The psnr is supposed to be greater than 34 given the "
|
||||
"target_bitrate 1000 kbps";
|
||||
total_data_bit_size += encode_frame_result.coding_data_bit_size;
|
||||
}
|
||||
EXPECT_EQ(num_alternate_refereces, ref_num_alternate_refereces);
|
||||
const double bitrate = GetBitrateInKbps(total_data_bit_size, num_frames,
|
||||
frame_rate_num, frame_rate_den);
|
||||
const double off_target_threshold = 150;
|
||||
EXPECT_LE(fabs(target_bitrate - bitrate), off_target_threshold);
|
||||
simple_encode.EndEncode();
|
||||
}
|
||||
|
||||
TEST(SimpleEncode, EncodeFrameWithQuantizeIndex) {
|
||||
SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
|
||||
target_bitrate, num_frames, infile_path);
|
||||
simple_encode.ComputeFirstPassStats();
|
||||
int num_coding_frames = simple_encode.GetCodingFrameNum();
|
||||
simple_encode.StartEncode();
|
||||
for (int i = 0; i < num_coding_frames; ++i) {
|
||||
const int assigned_quantize_index = 100 + i;
|
||||
EncodeFrameResult encode_frame_result;
|
||||
simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result,
|
||||
assigned_quantize_index);
|
||||
EXPECT_EQ(encode_frame_result.quantize_index, assigned_quantize_index);
|
||||
}
|
||||
simple_encode.EndEncode();
|
||||
}
|
||||
|
||||
TEST(SimpleEncode, EncodeConsistencyTest) {
|
||||
std::vector<int> quantize_index_list;
|
||||
std::vector<uint64_t> ref_sse_list;
|
||||
std::vector<double> ref_psnr_list;
|
||||
std::vector<size_t> ref_bit_size_list;
|
||||
{
|
||||
SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
|
||||
target_bitrate, num_frames, infile_path);
|
||||
simple_encode.ComputeFirstPassStats();
|
||||
const int num_coding_frames = simple_encode.GetCodingFrameNum();
|
||||
simple_encode.StartEncode();
|
||||
for (int i = 0; i < num_coding_frames; ++i) {
|
||||
EncodeFrameResult encode_frame_result;
|
||||
simple_encode.EncodeFrame(&encode_frame_result);
|
||||
quantize_index_list.push_back(encode_frame_result.quantize_index);
|
||||
ref_sse_list.push_back(encode_frame_result.sse);
|
||||
ref_psnr_list.push_back(encode_frame_result.psnr);
|
||||
ref_bit_size_list.push_back(encode_frame_result.coding_data_bit_size);
|
||||
}
|
||||
simple_encode.EndEncode();
|
||||
}
|
||||
{
|
||||
SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
|
||||
target_bitrate, num_frames, infile_path);
|
||||
simple_encode.ComputeFirstPassStats();
|
||||
const int num_coding_frames = simple_encode.GetCodingFrameNum();
|
||||
EXPECT_EQ(static_cast<size_t>(num_coding_frames),
|
||||
quantize_index_list.size());
|
||||
simple_encode.StartEncode();
|
||||
for (int i = 0; i < num_coding_frames; ++i) {
|
||||
EncodeFrameResult encode_frame_result;
|
||||
simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result,
|
||||
quantize_index_list[i]);
|
||||
EXPECT_EQ(encode_frame_result.quantize_index, quantize_index_list[i]);
|
||||
EXPECT_EQ(encode_frame_result.sse, ref_sse_list[i]);
|
||||
EXPECT_DOUBLE_EQ(encode_frame_result.psnr, ref_psnr_list[i]);
|
||||
EXPECT_EQ(encode_frame_result.coding_data_bit_size, ref_bit_size_list[i]);
|
||||
}
|
||||
simple_encode.EndEncode();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SimpleEncode, GetEncodeFrameInfo) {
|
||||
// Makes sure that the encode_frame_info obtained from GetEncodeFrameInfo()
|
||||
// matches the counterpart in encode_frame_result obtained from EncodeFrame()
|
||||
SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
|
||||
target_bitrate, num_frames, infile_path);
|
||||
simple_encode.ComputeFirstPassStats();
|
||||
const int num_coding_frames = simple_encode.GetCodingFrameNum();
|
||||
simple_encode.StartEncode();
|
||||
for (int i = 0; i < num_coding_frames; ++i) {
|
||||
EncodeFrameInfo encode_frame_info = simple_encode.GetNextEncodeFrameInfo();
|
||||
EncodeFrameResult encode_frame_result;
|
||||
simple_encode.EncodeFrame(&encode_frame_result);
|
||||
EXPECT_EQ(encode_frame_info.show_idx, encode_frame_result.show_idx);
|
||||
EXPECT_EQ(encode_frame_info.frame_type, encode_frame_result.frame_type);
|
||||
}
|
||||
simple_encode.EndEncode();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace vp9
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file tests the libvpx simple_encoder example. To add new tests to this
|
||||
## file, do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to simple_encoder_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: $YUV_RAW_INPUT is required.
|
||||
simple_encoder_verify_environment() {
|
||||
if [ ! -e "${YUV_RAW_INPUT}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs simple_encoder using the codec specified by $1 with a frame limit of 100.
|
||||
simple_encoder() {
|
||||
local encoder="${LIBVPX_BIN_PATH}/simple_encoder${VPX_TEST_EXE_SUFFIX}"
|
||||
local codec="$1"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/simple_encoder_${codec}.ivf"
|
||||
|
||||
if [ ! -x "${encoder}" ]; then
|
||||
elog "${encoder} does not exist or is not executable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 9999 0 100 \
|
||||
${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
}
|
||||
|
||||
simple_encoder_vp8() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
simple_encoder vp8 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
simple_encoder_vp9() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
simple_encoder vp9 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
simple_encoder_tests="simple_encoder_vp8
|
||||
simple_encoder_vp9"
|
||||
|
||||
run_tests simple_encoder_verify_environment "${simple_encoder_tests}"
|
||||
@@ -0,0 +1,183 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2016 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.
|
||||
##
|
||||
## This file performs a stress test. It runs (STRESS_ONEPASS_MAX_JOBS,
|
||||
## default=5) one, (STRESS_TWOPASS_MAX_JOBS, default=5) two pass &
|
||||
## (STRESS_RT_MAX_JOBS, default=5) encodes and (STRESS_<codec>_DECODE_MAX_JOBS,
|
||||
## default=30) decodes in parallel.
|
||||
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
YUV="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.yuv"
|
||||
VP8="${LIBVPX_TEST_DATA_PATH}/tos_vp8.webm"
|
||||
VP9="${LIBVPX_TEST_DATA_PATH}/vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm"
|
||||
DATA_URL="http://downloads.webmproject.org/test_data/libvpx/"
|
||||
SHA1_FILE="$(dirname $0)/test-data.sha1"
|
||||
|
||||
# Set sha1sum to proper sha program (sha1sum, shasum, sha1). This code is
|
||||
# cribbed from libs.mk.
|
||||
[ -x "$(which sha1sum)" ] && sha1sum=sha1sum
|
||||
[ -x "$(which shasum)" ] && sha1sum=shasum
|
||||
[ -x "$(which sha1)" ] && sha1sum=sha1
|
||||
|
||||
# Download a file from the url and check its sha1sum.
|
||||
download_and_check_file() {
|
||||
# Get the file from the file path.
|
||||
local root="${1#${LIBVPX_TEST_DATA_PATH}/}"
|
||||
|
||||
# Download the file using curl. Trap to insure non partial file.
|
||||
(trap "rm -f $1" INT TERM \
|
||||
&& eval "curl --retry 1 -L -o $1 ${DATA_URL}${root} ${devnull}")
|
||||
|
||||
# Check the sha1 sum of the file.
|
||||
if [ -n "${sha1sum}" ]; then
|
||||
set -e
|
||||
grep ${root} ${SHA1_FILE} \
|
||||
| (cd ${LIBVPX_TEST_DATA_PATH}; ${sha1sum} -c);
|
||||
fi
|
||||
}
|
||||
|
||||
# Environment check: Make sure input is available.
|
||||
stress_verify_environment() {
|
||||
if [ ! -e "${SHA1_FILE}" ] ; then
|
||||
echo "Missing ${SHA1_FILE}"
|
||||
return 1
|
||||
fi
|
||||
for file in "${YUV}" "${VP8}" "${VP9}"; do
|
||||
if [ ! -e "${file}" ] ; then
|
||||
download_and_check_file "${file}"
|
||||
fi
|
||||
done
|
||||
if [ ! -e "${YUV}" ] || [ ! -e "${VP8}" ] || [ ! -e "${VP9}" ] ; then
|
||||
elog "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$(vpx_tool_path vpxenc)" ]; then
|
||||
elog "vpxenc not found. It must exist in LIBVPX_BIN_PATH or its parent."
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$(vpx_tool_path vpxdec)" ]; then
|
||||
elog "vpxdec not found. It must exist in LIBVPX_BIN_PATH or its parent."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# This function runs tests on libvpx that run multiple encodes and decodes
|
||||
# in parallel in hopes of catching synchronization and/or threading issues.
|
||||
stress() {
|
||||
local decoder="$(vpx_tool_path vpxdec)"
|
||||
local encoder="$(vpx_tool_path vpxenc)"
|
||||
local codec="$1"
|
||||
local webm="$2"
|
||||
local decode_count="$3"
|
||||
local threads="$4"
|
||||
local enc_args="$5"
|
||||
local pids=""
|
||||
local rt_max_jobs=${STRESS_RT_MAX_JOBS:-5}
|
||||
local onepass_max_jobs=${STRESS_ONEPASS_MAX_JOBS:-5}
|
||||
local twopass_max_jobs=${STRESS_TWOPASS_MAX_JOBS:-5}
|
||||
|
||||
# Enable job control, so we can run multiple processes.
|
||||
set -m
|
||||
|
||||
# Start $onepass_max_jobs encode jobs in parallel.
|
||||
for i in $(seq ${onepass_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal --passes=1" \
|
||||
"--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.1pass.webm" \
|
||||
"${enc_args}" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Start $twopass_max_jobs encode jobs in parallel.
|
||||
for i in $(seq ${twopass_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal --passes=2" \
|
||||
"--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.2pass.webm" \
|
||||
"${enc_args}" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Start $rt_max_jobs rt encode jobs in parallel.
|
||||
for i in $(seq ${rt_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal " \
|
||||
"--target-bitrate=${bitrate} --lag-in-frames=0 --error-resilient=1" \
|
||||
"--kf-min-dist=3000 --kf-max-dist=3000 --cpu-used=-6 --static-thresh=1" \
|
||||
"--end-usage=cbr --min-q=2 --max-q=56 --undershoot-pct=100" \
|
||||
"--overshoot-pct=15 --buf-sz=1000 --buf-initial-sz=500" \
|
||||
"--buf-optimal-sz=600 --max-intra-rate=900 --resize-allowed=0" \
|
||||
"--drop-frame=0 --passes=1 --rt --noise-sensitivity=4" \
|
||||
"-o ${VPX_TEST_OUTPUT_DIR}/${i}.rt.webm" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Start $decode_count decode jobs in parallel.
|
||||
for i in $(seq "${decode_count}"); do
|
||||
eval "${decoder}" "-t ${threads}" "${webm}" "--noblit" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Wait for all parallel jobs to finish.
|
||||
fail=0
|
||||
for job in "${pids}"; do
|
||||
wait $job || fail=$(($fail + 1))
|
||||
done
|
||||
return $fail
|
||||
}
|
||||
|
||||
vp8_stress_test() {
|
||||
local vp8_max_jobs=${STRESS_VP8_DECODE_MAX_JOBS:-40}
|
||||
if [ "$(vp8_decode_available)" = "yes" -a \
|
||||
"$(vp8_encode_available)" = "yes" ]; then
|
||||
stress vp8 "${VP8}" "${vp8_max_jobs}" 4
|
||||
fi
|
||||
}
|
||||
|
||||
vp8_stress_test_token_parititions() {
|
||||
local vp8_max_jobs=${STRESS_VP8_DECODE_MAX_JOBS:-40}
|
||||
if [ "$(vp8_decode_available)" = "yes" -a \
|
||||
"$(vp8_encode_available)" = "yes" ]; then
|
||||
for threads in 2 4 8; do
|
||||
for token_partitions in 1 2 3; do
|
||||
stress vp8 "${VP8}" "${vp8_max_jobs}" ${threads} \
|
||||
"--token-parts=$token_partitions"
|
||||
done
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
vp9_stress() {
|
||||
local vp9_max_jobs=${STRESS_VP9_DECODE_MAX_JOBS:-25}
|
||||
|
||||
if [ "$(vp9_decode_available)" = "yes" -a \
|
||||
"$(vp9_encode_available)" = "yes" ]; then
|
||||
stress vp9 "${VP9}" "${vp9_max_jobs}" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
vp9_stress_test() {
|
||||
for threads in 4 8 64; do
|
||||
vp9_stress "$threads" "--row-mt=0"
|
||||
done
|
||||
}
|
||||
|
||||
vp9_stress_test_row_mt() {
|
||||
for threads in 4 8 64; do
|
||||
vp9_stress "$threads" "--row-mt=1"
|
||||
done
|
||||
}
|
||||
|
||||
run_tests stress_verify_environment \
|
||||
"vp8_stress_test vp8_stress_test_token_parititions
|
||||
vp9_stress_test vp9_stress_test_row_mt"
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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 <cmath>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
const int kNumIterations = 10000;
|
||||
|
||||
typedef uint64_t (*SSI16Func)(const int16_t *src, int stride, int size);
|
||||
typedef std::tuple<SSI16Func, SSI16Func> SumSquaresParam;
|
||||
|
||||
class SumSquaresTest : public ::testing::TestWithParam<SumSquaresParam> {
|
||||
public:
|
||||
virtual ~SumSquaresTest() {}
|
||||
virtual void SetUp() {
|
||||
ref_func_ = GET_PARAM(0);
|
||||
tst_func_ = GET_PARAM(1);
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
SSI16Func ref_func_;
|
||||
SSI16Func tst_func_;
|
||||
};
|
||||
|
||||
TEST_P(SumSquaresTest, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, int16_t, src[256 * 256]);
|
||||
const int msb = 11; // Up to 12 bit input
|
||||
const int limit = 1 << (msb + 1);
|
||||
|
||||
for (int k = 0; k < kNumIterations; k++) {
|
||||
const int size = 4 << rnd(6); // Up to 128x128
|
||||
int stride = 4 << rnd(7); // Up to 256 stride
|
||||
while (stride < size) { // Make sure it's valid
|
||||
stride = 4 << rnd(7);
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (int j = 0; j < size; ++j) {
|
||||
src[i * stride + j] = rnd(2) ? rnd(limit) : -rnd(limit);
|
||||
}
|
||||
}
|
||||
|
||||
const uint64_t res_ref = ref_func_(src, stride, size);
|
||||
uint64_t res_tst;
|
||||
ASM_REGISTER_STATE_CHECK(res_tst = tst_func_(src, stride, size));
|
||||
|
||||
ASSERT_EQ(res_ref, res_tst) << "Error: Sum Squares Test"
|
||||
<< " C output does not match optimized output.";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(SumSquaresTest, ExtremeValues) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, int16_t, src[256 * 256]);
|
||||
const int msb = 11; // Up to 12 bit input
|
||||
const int limit = 1 << (msb + 1);
|
||||
|
||||
for (int k = 0; k < kNumIterations; k++) {
|
||||
const int size = 4 << rnd(6); // Up to 128x128
|
||||
int stride = 4 << rnd(7); // Up to 256 stride
|
||||
while (stride < size) { // Make sure it's valid
|
||||
stride = 4 << rnd(7);
|
||||
}
|
||||
|
||||
const int val = rnd(2) ? limit - 1 : -(limit - 1);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (int j = 0; j < size; ++j) {
|
||||
src[i * stride + j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
const uint64_t res_ref = ref_func_(src, stride, size);
|
||||
uint64_t res_tst;
|
||||
ASM_REGISTER_STATE_CHECK(res_tst = tst_func_(src, stride, size));
|
||||
|
||||
ASSERT_EQ(res_ref, res_tst) << "Error: Sum Squares Test"
|
||||
<< " C output does not match optimized output.";
|
||||
}
|
||||
}
|
||||
|
||||
using std::make_tuple;
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, SumSquaresTest,
|
||||
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
||||
&vpx_sum_squares_2d_i16_neon)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, SumSquaresTest,
|
||||
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
||||
&vpx_sum_squares_2d_i16_sse2)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, SumSquaresTest,
|
||||
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
||||
&vpx_sum_squares_2d_i16_msa)));
|
||||
#endif // HAVE_MSA
|
||||
} // namespace
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 <tuple>
|
||||
|
||||
#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 {
|
||||
|
||||
const int kTestMode = 0;
|
||||
|
||||
typedef std::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
|
||||
|
||||
class SuperframeTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<SuperframeTestParam> {
|
||||
protected:
|
||||
SuperframeTest()
|
||||
: EncoderTest(GET_PARAM(0)), modified_buf_(NULL), last_sf_pts_(0) {}
|
||||
virtual ~SuperframeTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
const SuperframeTestParam input = GET_PARAM(1);
|
||||
const libvpx_test::TestMode mode = std::get<kTestMode>(input);
|
||||
SetMode(mode);
|
||||
sf_count_ = 0;
|
||||
sf_count_max_ = INT_MAX;
|
||||
}
|
||||
|
||||
virtual void TearDown() { delete[] modified_buf_; }
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
}
|
||||
}
|
||||
|
||||
virtual const vpx_codec_cx_pkt_t *MutateEncoderOutputHook(
|
||||
const vpx_codec_cx_pkt_t *pkt) {
|
||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return pkt;
|
||||
|
||||
const uint8_t *buffer = reinterpret_cast<uint8_t *>(pkt->data.frame.buf);
|
||||
const uint8_t marker = buffer[pkt->data.frame.sz - 1];
|
||||
const int frames = (marker & 0x7) + 1;
|
||||
const int mag = ((marker >> 3) & 3) + 1;
|
||||
const unsigned int index_sz = 2 + mag * frames;
|
||||
if ((marker & 0xe0) == 0xc0 && pkt->data.frame.sz >= index_sz &&
|
||||
buffer[pkt->data.frame.sz - index_sz] == marker) {
|
||||
// frame is a superframe. strip off the index.
|
||||
if (modified_buf_) delete[] modified_buf_;
|
||||
modified_buf_ = new uint8_t[pkt->data.frame.sz - index_sz];
|
||||
memcpy(modified_buf_, pkt->data.frame.buf, pkt->data.frame.sz - index_sz);
|
||||
modified_pkt_ = *pkt;
|
||||
modified_pkt_.data.frame.buf = modified_buf_;
|
||||
modified_pkt_.data.frame.sz -= index_sz;
|
||||
|
||||
sf_count_++;
|
||||
last_sf_pts_ = pkt->data.frame.pts;
|
||||
return &modified_pkt_;
|
||||
}
|
||||
|
||||
// Make sure we do a few frames after the last SF
|
||||
abort_ |=
|
||||
sf_count_ > sf_count_max_ && pkt->data.frame.pts - last_sf_pts_ >= 5;
|
||||
return pkt;
|
||||
}
|
||||
|
||||
int sf_count_;
|
||||
int sf_count_max_;
|
||||
vpx_codec_cx_pkt_t modified_pkt_;
|
||||
uint8_t *modified_buf_;
|
||||
vpx_codec_pts_t last_sf_pts_;
|
||||
};
|
||||
|
||||
TEST_P(SuperframeTest, TestSuperframeIndexIsOptional) {
|
||||
sf_count_max_ = 0; // early exit on successful test.
|
||||
cfg_.g_lag_in_frames = 25;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 40);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
EXPECT_EQ(sf_count_, 1);
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
SuperframeTest,
|
||||
::testing::Combine(::testing::Values(::libvpx_test::kTwoPassGood),
|
||||
::testing::Values(0)));
|
||||
} // namespace
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 "./vpx_config.h"
|
||||
#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/svc_test.h"
|
||||
#include "test/util.h"
|
||||
#include "test/y4m_video_source.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx_ports/bitops.h"
|
||||
|
||||
namespace svc_test {
|
||||
namespace {
|
||||
|
||||
typedef enum {
|
||||
// Inter-layer prediction is on on all frames.
|
||||
INTER_LAYER_PRED_ON,
|
||||
// Inter-layer prediction is off on all frames.
|
||||
INTER_LAYER_PRED_OFF,
|
||||
// Inter-layer prediction is off on non-key frames and non-sync frames.
|
||||
INTER_LAYER_PRED_OFF_NONKEY,
|
||||
// Inter-layer prediction is on on all frames, but constrained such
|
||||
// that any layer S (> 0) can only predict from previous spatial
|
||||
// layer S-1, from the same superframe.
|
||||
INTER_LAYER_PRED_ON_CONSTRAINED
|
||||
} INTER_LAYER_PRED;
|
||||
|
||||
class ScalePartitionOnePassCbrSvc
|
||||
: public OnePassCbrSvc,
|
||||
public ::testing::TestWithParam<const ::libvpx_test::CodecFactory *> {
|
||||
public:
|
||||
ScalePartitionOnePassCbrSvc()
|
||||
: OnePassCbrSvc(GetParam()), mismatch_nframes_(0), num_nonref_frames_(0) {
|
||||
SetMode(::libvpx_test::kRealTime);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~ScalePartitionOnePassCbrSvc() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
speed_setting_ = 7;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
PreEncodeFrameHookSetup(video, encoder);
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
// Keep track of number of non-reference frames, needed for mismatch check.
|
||||
// Non-reference frames are top spatial and temporal layer frames,
|
||||
// for TL > 0.
|
||||
if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
|
||||
temporal_layer_id_ > 0 &&
|
||||
pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1])
|
||||
num_nonref_frames_++;
|
||||
}
|
||||
|
||||
virtual void MismatchHook(const vpx_image_t * /*img1*/,
|
||||
const vpx_image_t * /*img2*/) {
|
||||
++mismatch_nframes_;
|
||||
}
|
||||
|
||||
virtual void SetConfig(const int /*num_temporal_layer*/) {}
|
||||
|
||||
unsigned int GetMismatchFrames() const { return mismatch_nframes_; }
|
||||
unsigned int GetNonRefFrames() const { return num_nonref_frames_; }
|
||||
|
||||
private:
|
||||
unsigned int mismatch_nframes_;
|
||||
unsigned int num_nonref_frames_;
|
||||
};
|
||||
|
||||
TEST_P(ScalePartitionOnePassCbrSvc, OnePassCbrSvc3SL3TL1080P) {
|
||||
SetSvcConfig(3, 3);
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.g_threads = 1;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
cfg_.temporal_layering_mode = 3;
|
||||
::libvpx_test::I420VideoSource video(
|
||||
"slides_code_term_web_plot.1920_1080.yuv", 1920, 1080, 30, 1, 0, 100);
|
||||
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
|
||||
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Params: Inter layer prediction modes.
|
||||
class SyncFrameOnePassCbrSvc : public OnePassCbrSvc,
|
||||
public ::libvpx_test::CodecTestWithParam<int> {
|
||||
public:
|
||||
SyncFrameOnePassCbrSvc()
|
||||
: OnePassCbrSvc(GET_PARAM(0)), current_video_frame_(0),
|
||||
frame_to_start_decode_(0), frame_to_sync_(0),
|
||||
inter_layer_pred_mode_(GET_PARAM(1)), decode_to_layer_before_sync_(-1),
|
||||
decode_to_layer_after_sync_(-1), denoiser_on_(0),
|
||||
intra_only_test_(false), mismatch_nframes_(0), num_nonref_frames_(0) {
|
||||
SetMode(::libvpx_test::kRealTime);
|
||||
memset(&svc_layer_sync_, 0, sizeof(svc_layer_sync_));
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~SyncFrameOnePassCbrSvc() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
speed_setting_ = 7;
|
||||
}
|
||||
|
||||
virtual bool DoDecode() const {
|
||||
return current_video_frame_ >= frame_to_start_decode_;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
current_video_frame_ = video->frame();
|
||||
PreEncodeFrameHookSetup(video, encoder);
|
||||
if (video->frame() == 0) {
|
||||
// Do not turn off inter-layer pred completely because simulcast mode
|
||||
// fails.
|
||||
if (inter_layer_pred_mode_ != INTER_LAYER_PRED_OFF)
|
||||
encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, inter_layer_pred_mode_);
|
||||
encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
if (intra_only_test_)
|
||||
// Decoder sets the color_space for Intra-only frames
|
||||
// to BT_601 (see line 1810 in vp9_decodeframe.c).
|
||||
// So set it here in these tess to avoid encoder-decoder
|
||||
// mismatch check on color space setting.
|
||||
encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601);
|
||||
}
|
||||
if (video->frame() == frame_to_sync_) {
|
||||
encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync_);
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
virtual void PreDecodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Decoder *decoder) {
|
||||
if (video->frame() < frame_to_sync_) {
|
||||
if (decode_to_layer_before_sync_ >= 0)
|
||||
decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER,
|
||||
decode_to_layer_before_sync_);
|
||||
} else {
|
||||
if (decode_to_layer_after_sync_ >= 0)
|
||||
decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER,
|
||||
decode_to_layer_after_sync_);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
// Keep track of number of non-reference frames, needed for mismatch check.
|
||||
// Non-reference frames are top spatial and temporal layer frames,
|
||||
// for TL > 0.
|
||||
if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
|
||||
temporal_layer_id_ > 0 &&
|
||||
pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1] &&
|
||||
current_video_frame_ >= frame_to_sync_)
|
||||
num_nonref_frames_++;
|
||||
|
||||
if (intra_only_test_ && current_video_frame_ == frame_to_sync_) {
|
||||
// Intra-only frame is only generated for spatial layers > 1 and <= 3,
|
||||
// among other conditions (see constraint in set_intra_only_frame(). If
|
||||
// intra-only is no allowed then encoder will insert key frame instead.
|
||||
const bool key_frame =
|
||||
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
|
||||
if (number_spatial_layers_ == 1 || number_spatial_layers_ > 3)
|
||||
ASSERT_TRUE(key_frame);
|
||||
else
|
||||
ASSERT_FALSE(key_frame);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MismatchHook(const vpx_image_t * /*img1*/,
|
||||
const vpx_image_t * /*img2*/) {
|
||||
if (current_video_frame_ >= frame_to_sync_) ++mismatch_nframes_;
|
||||
}
|
||||
|
||||
unsigned int GetMismatchFrames() const { return mismatch_nframes_; }
|
||||
unsigned int GetNonRefFrames() const { return num_nonref_frames_; }
|
||||
|
||||
unsigned int current_video_frame_;
|
||||
unsigned int frame_to_start_decode_;
|
||||
unsigned int frame_to_sync_;
|
||||
int inter_layer_pred_mode_;
|
||||
int decode_to_layer_before_sync_;
|
||||
int decode_to_layer_after_sync_;
|
||||
int denoiser_on_;
|
||||
bool intra_only_test_;
|
||||
vpx_svc_spatial_layer_sync_t svc_layer_sync_;
|
||||
|
||||
private:
|
||||
virtual void SetConfig(const int num_temporal_layer) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.g_threads = 1;
|
||||
cfg_.rc_dropframe_thresh = 30;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
if (num_temporal_layer == 3) {
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
cfg_.temporal_layering_mode = 3;
|
||||
} else if (num_temporal_layer == 2) {
|
||||
cfg_.ts_rate_decimator[0] = 2;
|
||||
cfg_.ts_rate_decimator[1] = 1;
|
||||
cfg_.temporal_layering_mode = 2;
|
||||
} else if (num_temporal_layer == 1) {
|
||||
cfg_.ts_rate_decimator[0] = 1;
|
||||
cfg_.temporal_layering_mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int mismatch_nframes_;
|
||||
unsigned int num_nonref_frames_;
|
||||
};
|
||||
|
||||
// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
|
||||
// 3 temporal layers. Only start decoding on the sync layer.
|
||||
// Full sync: insert key frame on base layer.
|
||||
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLFullSync) {
|
||||
SetSvcConfig(3, 3);
|
||||
// Sync is on base layer so the frame to sync and the frame to start decoding
|
||||
// is the same.
|
||||
frame_to_start_decode_ = 20;
|
||||
frame_to_sync_ = 20;
|
||||
decode_to_layer_before_sync_ = -1;
|
||||
decode_to_layer_after_sync_ = 2;
|
||||
|
||||
// Set up svc layer sync structure.
|
||||
svc_layer_sync_.base_layer_intra_only = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[0] = 1;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
|
||||
|
||||
cfg_.rc_target_bitrate = 600;
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test for sync layer for 1 pass CBR SVC: 2 spatial layers and
|
||||
// 3 temporal layers. Decoding QVGA before sync frame and decode up to
|
||||
// VGA on and after sync.
|
||||
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncToVGA) {
|
||||
SetSvcConfig(2, 3);
|
||||
frame_to_start_decode_ = 0;
|
||||
frame_to_sync_ = 100;
|
||||
decode_to_layer_before_sync_ = 0;
|
||||
decode_to_layer_after_sync_ = 1;
|
||||
|
||||
// Set up svc layer sync structure.
|
||||
svc_layer_sync_.base_layer_intra_only = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[0] = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[1] = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
|
||||
0, 400);
|
||||
cfg_.rc_target_bitrate = 400;
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
|
||||
// 3 temporal layers. Decoding QVGA and VGA before sync frame and decode up to
|
||||
// HD on and after sync.
|
||||
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToHD) {
|
||||
SetSvcConfig(3, 3);
|
||||
frame_to_start_decode_ = 0;
|
||||
frame_to_sync_ = 20;
|
||||
decode_to_layer_before_sync_ = 1;
|
||||
decode_to_layer_after_sync_ = 2;
|
||||
|
||||
// Set up svc layer sync structure.
|
||||
svc_layer_sync_.base_layer_intra_only = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[0] = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[1] = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[2] = 1;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
|
||||
cfg_.rc_target_bitrate = 600;
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
|
||||
// 3 temporal layers. Decoding QVGA before sync frame and decode up to
|
||||
// HD on and after sync.
|
||||
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToVGAHD) {
|
||||
SetSvcConfig(3, 3);
|
||||
frame_to_start_decode_ = 0;
|
||||
frame_to_sync_ = 20;
|
||||
decode_to_layer_before_sync_ = 0;
|
||||
decode_to_layer_after_sync_ = 2;
|
||||
|
||||
// Set up svc layer sync structure.
|
||||
svc_layer_sync_.base_layer_intra_only = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[0] = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[1] = 1;
|
||||
svc_layer_sync_.spatial_layer_sync[2] = 1;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
|
||||
cfg_.rc_target_bitrate = 600;
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
// Test for sync layer for 1 pass CBR SVC: 2 spatial layers and
|
||||
// 3 temporal layers. Decoding QVGA before sync frame and decode up to
|
||||
// VGA on and after sync.
|
||||
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncFrameVGADenoise) {
|
||||
SetSvcConfig(2, 3);
|
||||
frame_to_start_decode_ = 0;
|
||||
frame_to_sync_ = 100;
|
||||
decode_to_layer_before_sync_ = 0;
|
||||
decode_to_layer_after_sync_ = 1;
|
||||
|
||||
denoiser_on_ = 1;
|
||||
// Set up svc layer sync structure.
|
||||
svc_layer_sync_.base_layer_intra_only = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[0] = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[1] = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
|
||||
0, 400);
|
||||
cfg_.rc_target_bitrate = 400;
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Start decoding from beginning of sequence, during sequence insert intra-only
|
||||
// on base/qvga layer. Decode all layers.
|
||||
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyQVGA) {
|
||||
SetSvcConfig(3, 3);
|
||||
frame_to_start_decode_ = 0;
|
||||
frame_to_sync_ = 20;
|
||||
decode_to_layer_before_sync_ = 2;
|
||||
// The superframe containing intra-only layer will have 4 frames. Thus set the
|
||||
// layer to decode after sync frame to 3.
|
||||
decode_to_layer_after_sync_ = 3;
|
||||
intra_only_test_ = true;
|
||||
|
||||
// Set up svc layer sync structure.
|
||||
svc_layer_sync_.base_layer_intra_only = 1;
|
||||
svc_layer_sync_.spatial_layer_sync[0] = 1;
|
||||
svc_layer_sync_.spatial_layer_sync[1] = 0;
|
||||
svc_layer_sync_.spatial_layer_sync[2] = 0;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
|
||||
cfg_.rc_target_bitrate = 600;
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Start decoding from beginning of sequence, during sequence insert intra-only
|
||||
// on base/qvga layer and sync_layer on middle/VGA layer. Decode all layers.
|
||||
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyVGA) {
|
||||
SetSvcConfig(3, 3);
|
||||
frame_to_start_decode_ = 0;
|
||||
frame_to_sync_ = 20;
|
||||
decode_to_layer_before_sync_ = 2;
|
||||
// The superframe containing intra-only layer will have 4 frames. Thus set the
|
||||
// layer to decode after sync frame to 3.
|
||||
decode_to_layer_after_sync_ = 3;
|
||||
intra_only_test_ = true;
|
||||
|
||||
// Set up svc layer sync structure.
|
||||
svc_layer_sync_.base_layer_intra_only = 1;
|
||||
svc_layer_sync_.spatial_layer_sync[0] = 1;
|
||||
svc_layer_sync_.spatial_layer_sync[1] = 1;
|
||||
svc_layer_sync_.spatial_layer_sync[2] = 0;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
|
||||
cfg_.rc_target_bitrate = 600;
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Start decoding from sync frame, insert intra-only on base/qvga layer. Decode
|
||||
// all layers. For 1 spatial layer, it inserts a key frame.
|
||||
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc1SL3TLSyncFrameIntraOnlyQVGA) {
|
||||
SetSvcConfig(1, 3);
|
||||
frame_to_start_decode_ = 20;
|
||||
frame_to_sync_ = 20;
|
||||
decode_to_layer_before_sync_ = 0;
|
||||
decode_to_layer_after_sync_ = 0;
|
||||
intra_only_test_ = true;
|
||||
|
||||
// Set up svc layer sync structure.
|
||||
svc_layer_sync_.base_layer_intra_only = 1;
|
||||
svc_layer_sync_.spatial_layer_sync[0] = 1;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
|
||||
cfg_.rc_target_bitrate = 600;
|
||||
AssignLayerBitrates();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
#if CONFIG_VP9_DECODER
|
||||
// The non-reference frames are expected to be mismatched frames as the
|
||||
// encoder will avoid loopfilter on these frames.
|
||||
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(SyncFrameOnePassCbrSvc, ::testing::Range(0, 3));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9, ScalePartitionOnePassCbrSvc,
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)));
|
||||
|
||||
} // namespace
|
||||
} // namespace svc_test
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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/svc_test.h"
|
||||
|
||||
namespace svc_test {
|
||||
void OnePassCbrSvc::SetSvcConfig(const int num_spatial_layer,
|
||||
const int num_temporal_layer) {
|
||||
SetConfig(num_temporal_layer);
|
||||
cfg_.ss_number_layers = num_spatial_layer;
|
||||
cfg_.ts_number_layers = num_temporal_layer;
|
||||
if (num_spatial_layer == 1) {
|
||||
svc_params_.scaling_factor_num[0] = 288;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
} else if (num_spatial_layer == 2) {
|
||||
svc_params_.scaling_factor_num[0] = 144;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
} else if (num_spatial_layer == 3) {
|
||||
svc_params_.scaling_factor_num[0] = 72;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 144;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
svc_params_.scaling_factor_num[2] = 288;
|
||||
svc_params_.scaling_factor_den[2] = 288;
|
||||
}
|
||||
number_spatial_layers_ = cfg_.ss_number_layers;
|
||||
number_temporal_layers_ = cfg_.ts_number_layers;
|
||||
}
|
||||
|
||||
void OnePassCbrSvc::PreEncodeFrameHookSetup(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
for (int i = 0; i < VPX_MAX_LAYERS; ++i) {
|
||||
svc_params_.max_quantizers[i] = 63;
|
||||
svc_params_.min_quantizers[i] = 0;
|
||||
}
|
||||
svc_params_.speed_per_layer[0] = base_speed_setting_;
|
||||
for (int i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
|
||||
svc_params_.speed_per_layer[i] = speed_setting_;
|
||||
}
|
||||
|
||||
encoder->Control(VP9E_SET_SVC, 1);
|
||||
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
|
||||
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads));
|
||||
encoder->Control(VP9E_SET_ROW_MT, 1);
|
||||
encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
}
|
||||
|
||||
superframe_count_++;
|
||||
temporal_layer_id_ = 0;
|
||||
if (number_temporal_layers_ == 2) {
|
||||
temporal_layer_id_ = (superframe_count_ % 2 != 0);
|
||||
} else if (number_temporal_layers_ == 3) {
|
||||
if (superframe_count_ % 2 != 0) temporal_layer_id_ = 2;
|
||||
if (superframe_count_ > 1) {
|
||||
if ((superframe_count_ - 2) % 4 == 0) temporal_layer_id_ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
frame_flags_ = 0;
|
||||
}
|
||||
|
||||
void OnePassCbrSvc::PostEncodeFrameHook(::libvpx_test::Encoder *encoder) {
|
||||
vpx_svc_layer_id_t layer_id;
|
||||
encoder->Control(VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
temporal_layer_id_ = layer_id.temporal_layer_id;
|
||||
for (int sl = 0; sl < number_spatial_layers_; ++sl) {
|
||||
for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) {
|
||||
const int layer = sl * number_temporal_layers_ + tl;
|
||||
bits_in_buffer_model_[layer] +=
|
||||
static_cast<int64_t>(layer_target_avg_bandwidth_[layer]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnePassCbrSvc::AssignLayerBitrates() {
|
||||
int sl, spatial_layer_target;
|
||||
int spatial_layers = cfg_.ss_number_layers;
|
||||
int temporal_layers = cfg_.ts_number_layers;
|
||||
float total = 0;
|
||||
float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
|
||||
float framerate = 30.0;
|
||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||
if (svc_params_.scaling_factor_den[sl] > 0) {
|
||||
alloc_ratio[sl] =
|
||||
static_cast<float>((svc_params_.scaling_factor_num[sl] * 1.0 /
|
||||
svc_params_.scaling_factor_den[sl]));
|
||||
total += alloc_ratio[sl];
|
||||
}
|
||||
}
|
||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||
cfg_.ss_target_bitrate[sl] = spatial_layer_target =
|
||||
static_cast<unsigned int>(cfg_.rc_target_bitrate * alloc_ratio[sl] /
|
||||
total);
|
||||
const int index = sl * temporal_layers;
|
||||
if (cfg_.temporal_layering_mode == 3) {
|
||||
cfg_.layer_target_bitrate[index] = spatial_layer_target >> 1;
|
||||
cfg_.layer_target_bitrate[index + 1] =
|
||||
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
|
||||
cfg_.layer_target_bitrate[index + 2] = spatial_layer_target;
|
||||
} else if (cfg_.temporal_layering_mode == 2) {
|
||||
cfg_.layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
|
||||
cfg_.layer_target_bitrate[index + 1] = spatial_layer_target;
|
||||
} else if (cfg_.temporal_layering_mode <= 1) {
|
||||
cfg_.layer_target_bitrate[index] = spatial_layer_target;
|
||||
}
|
||||
}
|
||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||
for (int tl = 0; tl < temporal_layers; ++tl) {
|
||||
const int layer = sl * temporal_layers + tl;
|
||||
float layer_framerate = framerate;
|
||||
if (temporal_layers == 2 && tl == 0) layer_framerate = framerate / 2;
|
||||
if (temporal_layers == 3 && tl == 0) layer_framerate = framerate / 4;
|
||||
if (temporal_layers == 3 && tl == 1) layer_framerate = framerate / 2;
|
||||
layer_target_avg_bandwidth_[layer] = static_cast<int>(
|
||||
cfg_.layer_target_bitrate[layer] * 1000.0 / layer_framerate);
|
||||
bits_in_buffer_model_[layer] =
|
||||
cfg_.layer_target_bitrate[layer] * cfg_.rc_buf_initial_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace svc_test
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 VPX_TEST_SVC_TEST_H_
|
||||
#define VPX_TEST_SVC_TEST_H_
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#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"
|
||||
#include "test/y4m_video_source.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx_ports/bitops.h"
|
||||
|
||||
namespace svc_test {
|
||||
class OnePassCbrSvc : public ::libvpx_test::EncoderTest {
|
||||
public:
|
||||
explicit OnePassCbrSvc(const ::libvpx_test::CodecFactory *codec)
|
||||
: EncoderTest(codec), base_speed_setting_(0), speed_setting_(0),
|
||||
superframe_count_(0), temporal_layer_id_(0), number_temporal_layers_(0),
|
||||
number_spatial_layers_(0) {
|
||||
memset(&svc_params_, 0, sizeof(svc_params_));
|
||||
memset(bits_in_buffer_model_, 0,
|
||||
sizeof(bits_in_buffer_model_[0]) * VPX_MAX_LAYERS);
|
||||
memset(layer_target_avg_bandwidth_, 0,
|
||||
sizeof(layer_target_avg_bandwidth_[0]) * VPX_MAX_LAYERS);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~OnePassCbrSvc() {}
|
||||
|
||||
virtual void SetConfig(const int num_temporal_layer) = 0;
|
||||
|
||||
virtual void SetSvcConfig(const int num_spatial_layer,
|
||||
const int num_temporal_layer);
|
||||
|
||||
virtual void PreEncodeFrameHookSetup(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder);
|
||||
|
||||
virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder);
|
||||
|
||||
virtual void AssignLayerBitrates();
|
||||
|
||||
virtual void MismatchHook(const vpx_image_t *, const vpx_image_t *) {}
|
||||
|
||||
vpx_svc_extra_cfg_t svc_params_;
|
||||
int64_t bits_in_buffer_model_[VPX_MAX_LAYERS];
|
||||
int layer_target_avg_bandwidth_[VPX_MAX_LAYERS];
|
||||
int base_speed_setting_;
|
||||
int speed_setting_;
|
||||
int superframe_count_;
|
||||
int temporal_layer_id_;
|
||||
int number_temporal_layers_;
|
||||
int number_spatial_layers_;
|
||||
};
|
||||
} // namespace svc_test
|
||||
|
||||
#endif // VPX_TEST_SVC_TEST_H_
|
||||
@@ -0,0 +1,894 @@
|
||||
LIBVPX_TEST_SRCS-yes += test-data.mk
|
||||
|
||||
# Encoder test source
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_collage_w352h288.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_odd.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += desktop_office1.1280_720-020.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += slides_code_term_web_plot.1920_1080.yuv
|
||||
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_440.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_440.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420_a10-1.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_422.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_444.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_440.yuv
|
||||
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += desktop_credits.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += noisy_clip_640_360.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_RATE_CTRL) += bus_352x288_420_f20_b8.yuv
|
||||
|
||||
# Test vectors
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-002.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-002.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-003.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-003.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-004.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-004.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-005.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-005.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-006.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-006.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-007.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-007.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-008.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-008.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-009.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-009.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-010.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-010.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-011.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-011.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-012.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-012.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-013.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-013.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-014.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-014.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-015.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-015.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-016.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-016.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-017.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-017.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-018.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-018.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1400.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1400.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1411.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1411.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1416.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1416.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1417.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1417.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1402.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1402.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1412.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1412.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1418.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1418.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1424.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1424.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-01.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-01.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-02.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-02.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-03.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-03.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-04.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-04.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1401.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1401.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1403.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1403.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1407.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1407.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1408.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1408.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1409.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1409.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1410.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1410.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1413.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1413.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1414.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1414.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1415.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1415.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1425.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1425.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1426.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1426.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1427.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1427.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1432.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1432.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1435.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1435.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1436.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1436.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1437.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1437.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1441.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1441.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1442.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1442.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1404.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1404.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1405.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1405.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1406.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1406.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1428.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1428.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1429.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1429.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1430.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1430.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1431.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1431.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1433.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1433.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1434.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1434.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1438.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1438.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1439.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1439.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1440.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1440.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1443.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1443.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-06-smallsize.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-06-smallsize.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-00.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-00.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-01.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-01.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-02.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-02.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-03.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-03.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-04.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-04.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-05.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-05.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-06.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-06.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-07.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-07.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-09.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-09.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-11.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-11.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-12.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-12.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-13.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-13.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-14.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-14.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-15.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-15.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-17.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-17.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-19.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-19.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-20.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-20.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-21.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-21.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-22.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-22.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-23.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-23.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-24.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-24.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-25.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-25.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-26.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-26.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-27.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-27.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-28.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-28.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-29.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-29.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-30.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-30.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-31.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-31.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-33.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-33.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-35.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-35.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-36.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-36.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-37.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-37.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-38.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-38.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-39.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-39.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-40.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-40.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-41.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-41.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-42.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-42.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-43.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-43.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-44.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-44.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-45.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-45.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-46.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-46.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-47.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-47.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-48.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-48.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-49.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-49.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-50.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-50.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-51.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-51.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-52.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-52.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-53.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-53.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-54.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-54.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-55.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-55.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-56.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-56.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-57.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-57.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-58.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-58.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-59.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-59.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-60.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-60.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-61.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-61.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-62.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-62.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-63.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-63.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-3.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-3.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-5.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-5.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-6.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-6.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-7.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-7.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x64.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x64.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x66.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x66.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x64.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x64.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x66.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x66.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x64.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x64.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x66.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x66.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x64.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x64.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x66.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x66.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x64.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x64.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x66.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x66.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x64.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x64.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x66.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x66.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x64.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x64.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x66.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x66.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x08.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x08.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x10.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x10.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x18.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x18.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x32.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x32.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x34.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x34.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x64.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x64.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x66.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x66.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-130x132.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-130x132.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x130.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x130.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x132.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x132.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-178x180.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-178x180.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x178.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x178.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x180.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x180.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-lf-1920x1080.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-lf-1920x1080.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-deltaq.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-deltaq.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x196.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x196.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x198.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x198.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x200.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x200.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x202.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x202.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x208.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x208.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x210.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x210.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x224.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x224.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x226.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x226.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x196.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x196.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x198.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x198.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x200.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x200.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x202.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x202.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x208.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x208.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x210.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x210.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x224.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x224.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x226.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x226.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x196.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x196.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x198.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x198.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x200.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x200.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x202.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x202.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x208.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x208.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x210.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x210.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x224.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x224.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x226.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x226.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x196.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x196.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x198.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x198.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x200.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x200.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x202.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x202.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x208.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x208.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x210.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x210.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x224.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x224.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x226.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x226.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x196.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x196.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x198.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x198.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x200.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x200.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x202.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x202.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x208.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x208.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x210.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x210.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x224.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x224.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x226.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x226.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x196.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x196.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x198.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x198.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x200.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x200.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x202.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x202.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x208.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x208.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x210.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x210.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x224.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x224.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x226.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x226.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x196.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x196.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x198.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x198.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x200.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x200.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x202.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x202.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x208.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x208.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x210.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x210.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x224.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x224.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x226.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x226.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x196.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x196.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x198.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x198.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x200.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x200.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x202.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x202.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x208.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x208.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x210.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x210.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x224.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x224.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x226.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x226.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-352x288.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-352x288.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-05-resize.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-05-resize.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-06-bilinear.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-06-bilinear.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x2_frame_parallel.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x2_frame_parallel.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x4_frame_parallel.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x4_frame_parallel.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x8_frame_parallel.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x8_frame_parallel.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-aq2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-aq2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-lf_deltas.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-lf_deltas.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-subpixel-00.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-subpixel-00.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-10-show-existing-frame.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-10-show-existing-frame.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-10-show-existing-frame2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-10-show-existing-frame2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-351x287.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-351x287.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-351x288.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-351x288.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-352x287.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-352x287.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_1.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_1.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_2.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_2.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_3.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_3.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-13-largescaling.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-13-largescaling.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-16.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-16.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-8.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-8.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey_adpq.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey_adpq.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-16-intra-only.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-16-intra-only.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-17-show-existing-frame.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-17-show-existing-frame.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-18-resize.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-18-resize.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-01.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-01.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-02.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-02.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv422.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv422.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv440.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv440.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-01.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-01.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-02.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-02.webm.md5
|
||||
ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes)
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-10bit-yuv420.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-10bit-yuv420.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-12bit-yuv420.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-12bit-yuv420.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv422.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv422.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv422.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv422.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv440.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv440.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv440.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv440.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv444.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv444.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm.md5
|
||||
endif # CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
# Invalid files for testing libvpx error checking.
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-token-partition.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-token-partition.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v3.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v3.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-3.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1558.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1558.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1562.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1562.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += crbug-1539.rawfile
|
||||
|
||||
ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
|
||||
# Encode / Decode test
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv
|
||||
# BBB VP9 streams
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_426x240_tile_1x1_180kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_640x360_tile_1x2_337kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_854x480_tile_1x2_651kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_1280x720_tile_1x4_1310kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_1920x1080_tile_1x1_2581kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_1920x1080_tile_1x4_2586kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_1920x1080_tile_1x4_fpm_2304kbps.webm
|
||||
# Sintel VP9 streams
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_426x182_tile_1x1_171kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_640x272_tile_1x2_318kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_854x364_tile_1x2_621kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_1280x546_tile_1x4_1257kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm
|
||||
# TOS VP9 streams
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_426x178_tile_1x1_181kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_640x266_tile_1x2_336kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_854x356_tile_1x2_656kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_854x356_tile_1x2_fpm_546kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_1280x534_tile_1x4_1306kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_1280x534_tile_1x4_fpm_952kbps.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_1920x800_tile_1x4_fpm_2335kbps.webm
|
||||
endif # CONFIG_DECODE_PERF_TESTS
|
||||
|
||||
ifeq ($(CONFIG_ENCODE_PERF_TESTS),yes)
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += desktop_640_360_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += kirland_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcomoving_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcostationary_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomanarrows_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomasmallcameramovement_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += thaloundeskmtg_640_480_30.yuv
|
||||
endif # CONFIG_ENCODE_PERF_TESTS
|
||||
|
||||
# sort and remove duplicates
|
||||
LIBVPX_TEST_DATA-yes := $(sort $(LIBVPX_TEST_DATA-yes))
|
||||
|
||||
# VP9 dynamic resizing test (decoder)
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_1-2.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_1-2.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_3.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_3.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_1.webm.md5
|
||||
@@ -0,0 +1,868 @@
|
||||
3eaf216d9fc8b4b9bb8c3956311f49a85974806c *bus_352x288_420_f20_b8.yuv
|
||||
d5dfb0151c9051f8c85999255645d7a23916d3c0 *hantro_collage_w352h288.yuv
|
||||
b87815bf86020c592ccc7a846ba2e28ec8043902 *hantro_odd.yuv
|
||||
76024eb753cdac6a5e5703aaea189d35c3c30ac7 *invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf
|
||||
7448d8798a4380162d4b56f9b452e2f6f9e24e7a *invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf.res
|
||||
83f50908c8dc0ef8760595447a2ff7727489542e *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf
|
||||
456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
|
||||
c123d1f9f02fb4143abb5e271916e3a3080de8f6 *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
|
||||
456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
|
||||
efafb92b7567bc04c3f1432ea6c268c1c31affd5 *invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf.res
|
||||
fe346136b9b8c1e6f6084cc106485706915795e4 *invalid-vp90-01-v3.webm
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-01-v3.webm.res
|
||||
d78e2fceba5ac942246503ec8366f879c4775ca5 *invalid-vp90-02-v2.webm
|
||||
8e2eff4af87d2b561cce2365713269e301457ef3 *invalid-vp90-02-v2.webm.res
|
||||
df1a1453feb3c00d7d89746c7003b4163523bff3 *invalid-vp90-03-v3.webm
|
||||
4935c62becc68c13642a03db1e6d3e2331c1c612 *invalid-vp90-03-v3.webm.res
|
||||
d637297561dd904eb2c97a9015deeb31c4a1e8d2 *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
|
||||
3a204bdbeaa3c6458b77bcebb8366d107267f55d *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
|
||||
9aa21d8b2cb9d39abe8a7bb6032dc66955fb4342 *noisy_clip_640_360.y4m
|
||||
0936b837708ae68c034719f8e07596021c2c214f *park_joy_90p_10_420_20f.y4m
|
||||
5727a853c083c1099f837d27967bc1322d50ed4f *park_joy_90p_10_422_20f.y4m
|
||||
e13489470ef8e8b2a871a5640d795a42a39be58d *park_joy_90p_10_444_20f.y4m
|
||||
c934da6fb8cc54ee2a8c17c54cf6076dac37ead0 *park_joy_90p_10_440.yuv
|
||||
79b0dc1784635a7f291e21c4e8d66a29c496ab99 *park_joy_90p_12_420_20f.y4m
|
||||
9cf22b0f809f7464c8b9058f0cfa9d905921cbd1 *park_joy_90p_12_422_20f.y4m
|
||||
22b2a4abaecc4a9ade6bb503d25fb82367947e85 *park_joy_90p_12_444_20f.y4m
|
||||
82c1bfcca368c2f22bad7d693d690d5499ecdd11 *park_joy_90p_12_440.yuv
|
||||
b9e1e90aece2be6e2c90d89e6ab2372d5f8c792d *park_joy_90p_8_420_a10-1.y4m
|
||||
4e0eb61e76f0684188d9bc9f3ce61f6b6b77bb2c *park_joy_90p_8_420.y4m
|
||||
7a193ff7dfeb96ba5f82b2afd7afa9e1fe83d947 *park_joy_90p_8_422.y4m
|
||||
bdb7856e6bc93599bdda05c2e773a9f22b6c6d03 *park_joy_90p_8_444.y4m
|
||||
81e1f3843748438b8f2e71db484eb22daf72e939 *park_joy_90p_8_440.yuv
|
||||
b1f1c3ec79114b9a0651af24ce634afb44a9a419 *rush_hour_444.y4m
|
||||
5184c46ddca8b1fadd16742e8500115bc8f749da *vp80-00-comprehensive-001.ivf
|
||||
65bf1bbbced81b97bd030f376d1b7f61a224793f *vp80-00-comprehensive-002.ivf
|
||||
906b4c1e99eb734504c504b3f1ad8052137ce672 *vp80-00-comprehensive-003.ivf
|
||||
ec144b1af53af895db78355785650b96dd3f0ade *vp80-00-comprehensive-004.ivf
|
||||
afc7091785c62f1c121c4554a2830c30704587d9 *vp80-00-comprehensive-005.ivf
|
||||
42ea9d55c818145d06a9b633b8e85c6a6164fd3e *vp80-00-comprehensive-006.ivf
|
||||
e5b3a73ab79fe024c14309d653d6bed92902ee3b *vp80-00-comprehensive-007.ivf
|
||||
f3c50a58875930adfb84525c0ef59d7e4c08540c *vp80-00-comprehensive-008.ivf
|
||||
4b2841fdb83db51ae322096ae468bbb9dc2c8362 *vp80-00-comprehensive-009.ivf
|
||||
efbff736e3a91ab6a98c5bc2dce65d645944c7b1 *vp80-00-comprehensive-010.ivf
|
||||
6b315102cae008d22a3d2c231be92cb704a222f8 *vp80-00-comprehensive-011.ivf
|
||||
f3214a4fea14c2d5ec689936c1613f274c859ee8 *vp80-00-comprehensive-012.ivf
|
||||
e4094e96d308c8a35b74c480a43d853c5294cd34 *vp80-00-comprehensive-013.ivf
|
||||
5b0adfaf60a69e0aaf3ec021a39d0a68fc0e1b5a *vp80-00-comprehensive-014.ivf
|
||||
e8467688ddf26b5000664f904faf0d70506aa653 *vp80-00-comprehensive-015.ivf
|
||||
aab55582337dfd2a39ff54fb2576a91910d49337 *vp80-00-comprehensive-016.ivf
|
||||
1ba24724f80203c9bae4f1d0f99d534721980016 *vp80-00-comprehensive-017.ivf
|
||||
143a15512b46f436280ddb4d0e6411eb4af434f2 *vp80-00-comprehensive-018.ivf
|
||||
c5baeaf5714fdfb3a8bc960a8e33ac438e83b16b *vp80-01-intra-1400.ivf
|
||||
f383955229afe3408453e316d11553d923ca60d5 *vp80-01-intra-1411.ivf
|
||||
84e1f4343f174c9f3c83f834bac3196fb325bf2c *vp80-01-intra-1416.ivf
|
||||
fb6e712a47dd57a28a3727d2ae2c97a8b7c7ca51 *vp80-01-intra-1417.ivf
|
||||
71ea772d3e9d315b8cbecf41207b8a237c34853b *vp80-02-inter-1402.ivf
|
||||
d85dbc4271525dcd128c503f936fe69091d1f8d0 *vp80-02-inter-1412.ivf
|
||||
d4e5d3ad56511867d025f93724d090f92ba6ec3d *vp80-02-inter-1418.ivf
|
||||
91791cbcc37c60f35dbd8090bacb54e5ec6dd4fa *vp80-02-inter-1424.ivf
|
||||
17fbfe2fea70f6e2f3fa6ca4efaae6c0b03b5f02 *vp80-03-segmentation-01.ivf
|
||||
3c3600dbbcde08e20d54c66fe3b7eadd4f09bdbb *vp80-03-segmentation-02.ivf
|
||||
c156778d5340967d4b369c490848076e92f1f875 *vp80-03-segmentation-03.ivf
|
||||
d25dcff6c60e87a1af70945b8911b6b4998533b0 *vp80-03-segmentation-04.ivf
|
||||
362baba2ce454c9db21218f35e81c27a5ed0b730 *vp80-03-segmentation-1401.ivf
|
||||
d223ae7ee748ce07e74c4679bfd219e84aa9f4b0 *vp80-03-segmentation-1403.ivf
|
||||
033adf7f3a13836a3f1cffcb87c1972900f2b5c6 *vp80-03-segmentation-1407.ivf
|
||||
4d51dfbf9f3e2c590ec99d1d6f59dd731d04375f *vp80-03-segmentation-1408.ivf
|
||||
f37a62b197c2600d75e0ccfbb31b60efdedac251 *vp80-03-segmentation-1409.ivf
|
||||
eb25bd7bfba5b2f6935018a930f42d123b1e7fcd *vp80-03-segmentation-1410.ivf
|
||||
b9d5c436663a30c27cfff84b53a002e501258843 *vp80-03-segmentation-1413.ivf
|
||||
6da92b9d1a180cc3a8afe348ab12258f5a37be1a *vp80-03-segmentation-1414.ivf
|
||||
a4f5842602886bd669f115f93d8a35c035cb0948 *vp80-03-segmentation-1415.ivf
|
||||
f295dceb8ef278b77251b3f9df8aee22e161d547 *vp80-03-segmentation-1425.ivf
|
||||
198dbf9f36f733200e432664cc8c5752d59779de *vp80-03-segmentation-1426.ivf
|
||||
7704804e32f5de976803929934a7fafe101ac7b0 *vp80-03-segmentation-1427.ivf
|
||||
831ccd862ea95ca025d2f3bd8b88678752f5416d *vp80-03-segmentation-1432.ivf
|
||||
b3c11978529289f9109f2766fcaba3ebc40e11ef *vp80-03-segmentation-1435.ivf
|
||||
a835a731f5520ebfc1002c40121264d0020559ac *vp80-03-segmentation-1436.ivf
|
||||
1d1732942f773bb2a5775fcb9689b1579ce28eab *vp80-03-segmentation-1437.ivf
|
||||
db04799adfe089dfdf74dbd43cc05ede7161f99e *vp80-03-segmentation-1441.ivf
|
||||
7caf39b3f20cfd52b998210878062e52a5edf1e6 *vp80-03-segmentation-1442.ivf
|
||||
3607f6bb4ee106c38fa1ea370dc4ff8b8cde2261 *vp80-04-partitions-1404.ivf
|
||||
93cc323b6b6867f1b12dd48773424549c6960a6b *vp80-04-partitions-1405.ivf
|
||||
047eedb14b865bdac8a3538e63801054e0295e9c *vp80-04-partitions-1406.ivf
|
||||
0f1233bd2bc33f56ce5e495dbd455d122339f384 *vp80-05-sharpness-1428.ivf
|
||||
51767fc136488a9535c2a4c38067c542ee2048df *vp80-05-sharpness-1429.ivf
|
||||
9805aa107672de25d6fb8c35e20d06deca5efe18 *vp80-05-sharpness-1430.ivf
|
||||
61db6b965f9c27aebe71b85bf2d5877e58e4bbdf *vp80-05-sharpness-1431.ivf
|
||||
10420d266290d2923555f84af38eeb96edbd3ae8 *vp80-05-sharpness-1433.ivf
|
||||
3ed24f9a80cddfdf75824ba95cdb4ff9286cb443 *vp80-05-sharpness-1434.ivf
|
||||
c87599cbecd72d4cd4f7ace3313b7a6bc6eb8163 *vp80-05-sharpness-1438.ivf
|
||||
aff51d865c2621b60510459244ea83e958e4baed *vp80-05-sharpness-1439.ivf
|
||||
da386e72b19b5485a6af199c5eb60ef25e510dd1 *vp80-05-sharpness-1440.ivf
|
||||
6759a095203d96ccd267ce09b1b050b8cc4c2f1f *vp80-05-sharpness-1443.ivf
|
||||
b95d3cc1d0df991e63e150a801710a72f20d9ba0 *vp80-06-smallsize.ivf
|
||||
db55ec7fd02c864ba996ff060b25b1e08611330b *vp80-00-comprehensive-001.ivf.md5
|
||||
29db0ad011cba1e45f856d5623cd38dac3e3bf19 *vp80-00-comprehensive-002.ivf.md5
|
||||
e84f258f69e173e7d68f8f8c037a0a3766902182 *vp80-00-comprehensive-003.ivf.md5
|
||||
eb7912eaf69559a16fd82bc3f5fb1524cf4a4466 *vp80-00-comprehensive-004.ivf.md5
|
||||
4206f71c94894bd5b5b376f6c09b3817dbc65206 *vp80-00-comprehensive-005.ivf.md5
|
||||
4f89b356f6f2fecb928f330a10f804f00f5325f5 *vp80-00-comprehensive-006.ivf.md5
|
||||
2813236a32964dd8007e17648bcf035a20fcda6c *vp80-00-comprehensive-007.ivf.md5
|
||||
10746c72098f872803c900e17c5680e451f5f498 *vp80-00-comprehensive-008.ivf.md5
|
||||
39a23d0692ce64421a7bb7cdf6ccec5928d37fff *vp80-00-comprehensive-009.ivf.md5
|
||||
f6e3de8931a0cc659bda8fbc14050346955e72d4 *vp80-00-comprehensive-010.ivf.md5
|
||||
101683ec195b6e944f7cd1e468fc8921439363e6 *vp80-00-comprehensive-011.ivf.md5
|
||||
1f592751ce46d8688998fa0fa4fbdcda0fd4058c *vp80-00-comprehensive-012.ivf.md5
|
||||
6066176f90ca790251e795fca1a5797d59999841 *vp80-00-comprehensive-013.ivf.md5
|
||||
2656da94ba93691f23edc4d60b3a09e2be46c217 *vp80-00-comprehensive-014.ivf.md5
|
||||
c6e0d5f5d61460c8ac8edfa4e701f10312c03133 *vp80-00-comprehensive-015.ivf.md5
|
||||
ee60fee501d8493e34e8d6a1fe315b51ed09b24a *vp80-00-comprehensive-016.ivf.md5
|
||||
9f1914ceffcad4546c0a29de3ef591d8bea304dc *vp80-00-comprehensive-017.ivf.md5
|
||||
e0305178fe288a9fd8082b39e2d03181edb19054 *vp80-00-comprehensive-018.ivf.md5
|
||||
612494da2fa799cc9d76dcdd835ae6c7cb2e5c05 *vp80-01-intra-1400.ivf.md5
|
||||
48ea06097ac8269c5e8c2131d3d0639f431fcf0e *vp80-01-intra-1411.ivf.md5
|
||||
6e2ab4e7677ad0ba868083ca6bc387ee922b400c *vp80-01-intra-1416.ivf.md5
|
||||
eca0a90348959ce3854142f8d8641b13050e8349 *vp80-01-intra-1417.ivf.md5
|
||||
920feea203145d5c2258a91c4e6991934a79a99e *vp80-02-inter-1402.ivf.md5
|
||||
f71d97909fe2b3dd65be7e1f56c72237f0cef200 *vp80-02-inter-1412.ivf.md5
|
||||
e911254569a30bbb2a237ff8b79f69ed9da0672d *vp80-02-inter-1418.ivf.md5
|
||||
58c789c50c9bb9cc90580bed291164a0939d28ba *vp80-02-inter-1424.ivf.md5
|
||||
ff3e2f441327b9c20a0b37c524e0f5a48a36de7b *vp80-03-segmentation-01.ivf.md5
|
||||
0791f417f076a542ae66fbc3426ab4d94cbd6c75 *vp80-03-segmentation-02.ivf.md5
|
||||
722e50f1a6a91c34302d68681faffc1c26d1cc57 *vp80-03-segmentation-03.ivf.md5
|
||||
c701f1885bcfb27fb8e70cc65606b289172ef889 *vp80-03-segmentation-04.ivf.md5
|
||||
f79bc9ec189a2b4807632a3d0c5bf04a178b5300 *vp80-03-segmentation-1401.ivf.md5
|
||||
b9aa4c74c0219b639811c44760d0b24cd8bb436a *vp80-03-segmentation-1403.ivf.md5
|
||||
70d5a2207ca1891bcaebd5cf6dd88ce8d57b4334 *vp80-03-segmentation-1407.ivf.md5
|
||||
265f962ee781531f9a93b9309461316fd32b2a1d *vp80-03-segmentation-1408.ivf.md5
|
||||
0c4ecbbd6dc042d30e626d951b65f460dd6cd563 *vp80-03-segmentation-1409.ivf.md5
|
||||
cf779af36a937f06570a0fca9db64ba133451dee *vp80-03-segmentation-1410.ivf.md5
|
||||
0e6c5036d51ab078842f133934926c598a9cff02 *vp80-03-segmentation-1413.ivf.md5
|
||||
eb3930aaf229116c80d507516c34759c3f6cdf69 *vp80-03-segmentation-1414.ivf.md5
|
||||
123d6c0f72ee87911c4ae7538e87b7d163b22d6c *vp80-03-segmentation-1415.ivf.md5
|
||||
e70551d1a38920e097a5d8782390b79ecaeb7505 *vp80-03-segmentation-1425.ivf.md5
|
||||
44e8f4117e46dbb302b2cfd81171cc1a1846e431 *vp80-03-segmentation-1426.ivf.md5
|
||||
52636e54aee5f95bbace37021bd67de5db767e9a *vp80-03-segmentation-1427.ivf.md5
|
||||
b1ad3eff20215c28e295b15ef3636ed926d59cba *vp80-03-segmentation-1432.ivf.md5
|
||||
24c22a552fa28a90e5978f67f57181cc2d7546d7 *vp80-03-segmentation-1435.ivf.md5
|
||||
96c49c390abfced18a7a8c9b9ea10af778e10edb *vp80-03-segmentation-1436.ivf.md5
|
||||
f95eb6214571434f1f73ab7833b9ccdf47588020 *vp80-03-segmentation-1437.ivf.md5
|
||||
1c0700ca27c9b0090a7747a4b0b4dc21d1843181 *vp80-03-segmentation-1441.ivf.md5
|
||||
81d4f23ca32667ee958bae579c8f5e97ba72eb97 *vp80-03-segmentation-1442.ivf.md5
|
||||
272efcef07a3a30fbca51bfd566063d8258ec0be *vp80-04-partitions-1404.ivf.md5
|
||||
66ed219ab812ac801b256d35cf495d193d4cf478 *vp80-04-partitions-1405.ivf.md5
|
||||
36083f37f56f502bd60ec5e07502ee9e6b8699b0 *vp80-04-partitions-1406.ivf.md5
|
||||
6ca909bf168a64c09415626294665dc1be3d1973 *vp80-05-sharpness-1428.ivf.md5
|
||||
1667d2ee2334e5fdea8a8a866f4ccf3cf76f033a *vp80-05-sharpness-1429.ivf.md5
|
||||
71bcbe5357d36a19df5b07fbe3e27bffa8893f0a *vp80-05-sharpness-1430.ivf.md5
|
||||
89a09b1dffce2d55770a89e58d9925c70ef79bf8 *vp80-05-sharpness-1431.ivf.md5
|
||||
08444a18b4e6ba3450c0796dd728d48c399a2dc9 *vp80-05-sharpness-1433.ivf.md5
|
||||
6d6223719a90c13e848aa2a8a6642098cdb5977a *vp80-05-sharpness-1434.ivf.md5
|
||||
41d70bb5fa45bc88da1604a0af466930b8dd77b5 *vp80-05-sharpness-1438.ivf.md5
|
||||
086c56378df81b6cee264d7540a7b8f2b405c7a4 *vp80-05-sharpness-1439.ivf.md5
|
||||
d32dc2c4165eb266ea4c23c14a45459b363def32 *vp80-05-sharpness-1440.ivf.md5
|
||||
8c69dc3d8e563f56ffab5ad1e400d9e689dd23df *vp80-05-sharpness-1443.ivf.md5
|
||||
d6f246df012c241b5fa6c1345019a3703d85c419 *vp80-06-smallsize.ivf.md5
|
||||
ce881e567fe1d0fbcb2d3e9e6281a1a8d74d82e0 *vp90-2-00-quantizer-00.webm
|
||||
ac5eda33407d0521c7afca43a63fd305c0cd9d13 *vp90-2-00-quantizer-00.webm.md5
|
||||
2ca0463f2cfb93d25d7dded174db70b7cb87cb48 *vp90-2-00-quantizer-01.webm
|
||||
10d98884fc6d9a5f47a2057922b8e25dd48d7786 *vp90-2-00-quantizer-01.webm.md5
|
||||
d80a2920a5e0819d69dcba8fe260c01f820f8982 *vp90-2-00-quantizer-02.webm
|
||||
c964c8e5e04165fabbf1c6ee8ee5121d35921965 *vp90-2-00-quantizer-02.webm.md5
|
||||
fdef046777b5b75c962b715d809dbe2ea331afb9 *vp90-2-00-quantizer-03.webm
|
||||
f270bee0b0c7aa2bf4c5afe098556b4f3f890faf *vp90-2-00-quantizer-03.webm.md5
|
||||
66d98609e809394a6ac730787e6724e3badc075a *vp90-2-00-quantizer-04.webm
|
||||
427433bfe121c4aea1095ec3124fdc174d200e3a *vp90-2-00-quantizer-04.webm.md5
|
||||
e6e42626d8cadf0b5be16313f69212981b96fee5 *vp90-2-00-quantizer-05.webm
|
||||
c98f6a9a1af4cfd71416792827304266aad4bd46 *vp90-2-00-quantizer-05.webm.md5
|
||||
413ef09b721f5dcec1a96e937a97e5873c2e6db6 *vp90-2-00-quantizer-06.webm
|
||||
5080e940a23805c82e578e21b57fc2c511e76376 *vp90-2-00-quantizer-06.webm.md5
|
||||
4a50a5f4ac717c30dfaae8bb46702e3542e867de *vp90-2-00-quantizer-07.webm
|
||||
76c429a02b56762e10ee4db88729d8834b3a70f4 *vp90-2-00-quantizer-07.webm.md5
|
||||
d2f4e464780bf8b7e647efa18ac777a930e62bc0 *vp90-2-00-quantizer-08.webm
|
||||
ab94aabf9316111b52d7c531962ed4123313b6ba *vp90-2-00-quantizer-08.webm.md5
|
||||
174bc58433936dd79550398d744f1072ce7f5693 *vp90-2-00-quantizer-09.webm
|
||||
e1f7690cd83ccc56d045e17cce552544a5f03810 *vp90-2-00-quantizer-09.webm.md5
|
||||
52bc1dfd3a97b24d922eb8a31d07527891561f2a *vp90-2-00-quantizer-10.webm
|
||||
9b37bed893b5f6a4e12f2aa40f02dd40f944d0f8 *vp90-2-00-quantizer-10.webm.md5
|
||||
10031eecafde1e1d8e6323fe2b2a1d7e77a66869 *vp90-2-00-quantizer-11.webm
|
||||
fe4620a4bb0e4f5cb9bbfedc4039a22b81b0f5c0 *vp90-2-00-quantizer-11.webm.md5
|
||||
78e9f7bb77e8e348155bbdfa12790789d1d50c34 *vp90-2-00-quantizer-12.webm
|
||||
0961d060cc8dd469c6dac8d7d75f927c0bb971b8 *vp90-2-00-quantizer-12.webm.md5
|
||||
133b77a3bbcef652552d74ffc46afbfe3b8a1cba *vp90-2-00-quantizer-13.webm
|
||||
df29e5e0f95772af482f540d776f6b9dea4bfa29 *vp90-2-00-quantizer-13.webm.md5
|
||||
27323afdaf8987e025c27129c74c86502315a206 *vp90-2-00-quantizer-14.webm
|
||||
ce96a2cc312942f0427a463f15a392870dd69764 *vp90-2-00-quantizer-14.webm.md5
|
||||
ab58d0b41037829f6bc993910999f4af0212aafd *vp90-2-00-quantizer-15.webm
|
||||
40f700db606501aa7cb49049624cbdde6409b122 *vp90-2-00-quantizer-15.webm.md5
|
||||
cd948e66448aafb65998815ce37241f95d7c9ee7 *vp90-2-00-quantizer-16.webm
|
||||
039b742d149c945ed79c7b9a6384352852a1c116 *vp90-2-00-quantizer-16.webm.md5
|
||||
62f56e663e13c576764e491cf08f19bd46a71999 *vp90-2-00-quantizer-17.webm
|
||||
90c5a39bf76e6b3e0a1c0d3e9b68a9fd78be963e *vp90-2-00-quantizer-17.webm.md5
|
||||
f26ecad7263cd66a614e53ba5d7c00df181affeb *vp90-2-00-quantizer-18.webm
|
||||
cda0a1c0fca2ec2976ae55124a8a67305508bae6 *vp90-2-00-quantizer-18.webm.md5
|
||||
94bfc4c04fcfe139a63b98c569e8c14ba98c401f *vp90-2-00-quantizer-19.webm
|
||||
5b8ec169ccf67d8a0a8e46a62eb173f5a1dbaf4f *vp90-2-00-quantizer-19.webm.md5
|
||||
0ee88e9318985e1e245de78c2c4a665885ab76a7 *vp90-2-00-quantizer-20.webm
|
||||
4b26f7edb4fcd3a1b4cce9ba3cb8650e3ee6e063 *vp90-2-00-quantizer-20.webm.md5
|
||||
6a995cb2b1db33da8087321df1e646f95c3e32d1 *vp90-2-00-quantizer-21.webm
|
||||
e216b4a1eceac03efcc433759be54ab8ea87b24b *vp90-2-00-quantizer-21.webm.md5
|
||||
aa7722fc427e7180115f3c9cd96bb6b2768e7296 *vp90-2-00-quantizer-22.webm
|
||||
1aa813bd45ae831bf5e79ace4d73dfd25989a07d *vp90-2-00-quantizer-22.webm.md5
|
||||
7677e5b929ed6d142041f19b8a9cd5822ee1504a *vp90-2-00-quantizer-23.webm
|
||||
0de0af34abd843d5b37e58baf3ed96a6104b64c3 *vp90-2-00-quantizer-23.webm.md5
|
||||
b2995cbe1128b2d4926f1b28d01c501ecb6be8c8 *vp90-2-00-quantizer-24.webm
|
||||
db6033af2ba2f2bca62468fb4b8808e474f93923 *vp90-2-00-quantizer-24.webm.md5
|
||||
8135ba35587fd92cd4667be7896323d9b634401c *vp90-2-00-quantizer-25.webm
|
||||
3499e00c2cc15876f61f07e3d3cfca54ebcd98fd *vp90-2-00-quantizer-25.webm.md5
|
||||
af0fa2907746db82d345f6d831fcc1b2862a29fb *vp90-2-00-quantizer-26.webm
|
||||
cd6fe3d14dab48886ebf65be00e6ed9616ebe5a7 *vp90-2-00-quantizer-26.webm.md5
|
||||
bd0002e91323776beb5ff11e06edcf19fc08e9b9 *vp90-2-00-quantizer-27.webm
|
||||
fe72154ef196067d6c272521012dd79706496cac *vp90-2-00-quantizer-27.webm.md5
|
||||
fc15eb606f81455ff03df16bf3432296b002c43c *vp90-2-00-quantizer-28.webm
|
||||
40b2e24b542206a6bfd746ef199e49ccea07678a *vp90-2-00-quantizer-28.webm.md5
|
||||
3090bbf913cad0b2eddca7228f5ed51a58378b8d *vp90-2-00-quantizer-29.webm
|
||||
eb59745e0912d8ed6c928268bcf265237c9ba93f *vp90-2-00-quantizer-29.webm.md5
|
||||
c615abdca9c25e1cb110d908edbedfb3b7c92b91 *vp90-2-00-quantizer-30.webm
|
||||
ad0f4fe6733e4e7cdfe8ef8722bb341dcc7538c0 *vp90-2-00-quantizer-30.webm.md5
|
||||
037d9f242086cfb085518f6416259defa82d5fc2 *vp90-2-00-quantizer-31.webm
|
||||
4654b40792572f0a790874c6347ef9196d86c1a7 *vp90-2-00-quantizer-31.webm.md5
|
||||
505899f3f3515044c5c8b3213d9b9d16f614619d *vp90-2-00-quantizer-32.webm
|
||||
659a2e6dd02df323f62600626859006640b445df *vp90-2-00-quantizer-32.webm.md5
|
||||
8b32ec9c3b7e5ca8ddc6b8aea1c1cb7ca996bccc *vp90-2-00-quantizer-33.webm
|
||||
5b175ef1120ddeba4feae1247bf381bbc4e816ce *vp90-2-00-quantizer-33.webm.md5
|
||||
4d283755d17e287b1d099a80604398f60d7fb6ea *vp90-2-00-quantizer-34.webm
|
||||
22a739de95acfeb27524e3700b8f678a9ad744d8 *vp90-2-00-quantizer-34.webm.md5
|
||||
4296f56a892a412d3d4f64824718dd566c4e6459 *vp90-2-00-quantizer-35.webm
|
||||
c532c9c8dc7b3506fc6a51e5c20c17ef0ac039e7 *vp90-2-00-quantizer-35.webm.md5
|
||||
6f54e11da461e4410dd9075b015e2d9bc1d07dfb *vp90-2-00-quantizer-36.webm
|
||||
0b3573f5addea4e3eb11a0b85f068299d5bdad78 *vp90-2-00-quantizer-36.webm.md5
|
||||
210581682a26c2c4375efc785c36e07539888bc2 *vp90-2-00-quantizer-37.webm
|
||||
2b4fb6f8ba975237858e61cc8f560bcfc87cb38e *vp90-2-00-quantizer-37.webm.md5
|
||||
a15ef31283dfc4860f837fe200eb32a445f59629 *vp90-2-00-quantizer-38.webm
|
||||
fb76771f3a795054b9936f70da7505c3ac585284 *vp90-2-00-quantizer-38.webm.md5
|
||||
1df8433a441412831daae6726df89fa70d21b14d *vp90-2-00-quantizer-39.webm
|
||||
39e162c09a20e7e684868097766347014371fee6 *vp90-2-00-quantizer-39.webm.md5
|
||||
5330e4788ab9129dbb25a7a7d5411104521248b6 *vp90-2-00-quantizer-40.webm
|
||||
872cc0f2cc9dbf000f89eadb4d8f9940e48e00b1 *vp90-2-00-quantizer-40.webm.md5
|
||||
d88d03b982889e399a78d7a06eeb1cf30e6c2da2 *vp90-2-00-quantizer-41.webm
|
||||
5b4f7217e57fa2a221011d0b32f8d0409496b7b6 *vp90-2-00-quantizer-41.webm.md5
|
||||
9e16406e3e26955a6e17d455ef1ef64bbfa26e53 *vp90-2-00-quantizer-42.webm
|
||||
0219d090cf37daabe19256ba8e932ba4874b92e4 *vp90-2-00-quantizer-42.webm.md5
|
||||
a9b15843486fb05f8cd15437ef279782a42b75db *vp90-2-00-quantizer-43.webm
|
||||
3c9b0b4c607f9579a31726bfcf56729334ddc686 *vp90-2-00-quantizer-43.webm.md5
|
||||
1dbc931ac446c91eabe7213efff55b596cccf07c *vp90-2-00-quantizer-44.webm
|
||||
73bc8f675103abaef3d9f73a2742b3bffd726d23 *vp90-2-00-quantizer-44.webm.md5
|
||||
7c6c1be15beb9d6201204b018966c8c4f9777efc *vp90-2-00-quantizer-45.webm
|
||||
c907b29da821f790c6748de61f592689312e4e36 *vp90-2-00-quantizer-45.webm.md5
|
||||
07b434da1a467580f73b32177ee11b3e00f65a0d *vp90-2-00-quantizer-46.webm
|
||||
7b2b7ce60c50bc970bc0ada46d7a7ce440148da3 *vp90-2-00-quantizer-46.webm.md5
|
||||
233d0465fb1a6fa36e9f89bd2193ac79bd4d2809 *vp90-2-00-quantizer-47.webm
|
||||
527e0a9fb932efe915027ffe077f9e8d3a4fb139 *vp90-2-00-quantizer-47.webm.md5
|
||||
719613df7307e205c3fdb6acfb373849c5ab23c7 *vp90-2-00-quantizer-48.webm
|
||||
65ab6c9d1b682c183b201c7ff42b90343ce3e304 *vp90-2-00-quantizer-48.webm.md5
|
||||
3bf04a598325ed0eabae1598ec7f718f715ec672 *vp90-2-00-quantizer-49.webm
|
||||
ac68c4387ce11fcc998d8ba455ab9b2bb361d240 *vp90-2-00-quantizer-49.webm.md5
|
||||
d59238fb3a654931c9b65a11e7321b40d1f702e9 *vp90-2-00-quantizer-50.webm
|
||||
d0576bfede46fd55659f028f2fd28554ceb3e6cc *vp90-2-00-quantizer-50.webm.md5
|
||||
3f579785101d4209360dd96f8c2ffe9beddf3bee *vp90-2-00-quantizer-51.webm
|
||||
89fcfe04f4457a7f02ab4a2f94aacbb88aee5789 *vp90-2-00-quantizer-51.webm.md5
|
||||
28be5836e2fedefe4babf12fc9b79e460ab0a0f4 *vp90-2-00-quantizer-52.webm
|
||||
f3dd52b70c18345fee740220f35da9c4def2017a *vp90-2-00-quantizer-52.webm.md5
|
||||
488ad4058c17170665b6acd1021fade9a02771e4 *vp90-2-00-quantizer-53.webm
|
||||
1cdcb1d4f3a37cf83ad235eb27ec62ed2a01afc7 *vp90-2-00-quantizer-53.webm.md5
|
||||
682978289cb28cc8c9d39bc797300e45d6039de7 *vp90-2-00-quantizer-54.webm
|
||||
36c35353f2c03cb099bd710d9994de7d9ed88834 *vp90-2-00-quantizer-54.webm.md5
|
||||
c398ce49af762a48f10cc4da9fae0769aae5f226 *vp90-2-00-quantizer-55.webm
|
||||
2cf3570542d984f167ab087f59493c7fb47e0ed2 *vp90-2-00-quantizer-55.webm.md5
|
||||
3071f18b2fce261aa82d61f81a7ae4ca9a75d0e3 *vp90-2-00-quantizer-56.webm
|
||||
d3f93f8272b6de31cffb011a26f11abb514efb12 *vp90-2-00-quantizer-56.webm.md5
|
||||
f4e8e14b1f278801a7eb6f11734780a01b1668e9 *vp90-2-00-quantizer-57.webm
|
||||
6478fdf1d7faf6db5f19dffc5e1363af358699ee *vp90-2-00-quantizer-57.webm.md5
|
||||
307dc264f57cc618fff211fa44d7f52767ed9660 *vp90-2-00-quantizer-58.webm
|
||||
cf231d4a52d492fa692ea4194ec5eb7511fec54e *vp90-2-00-quantizer-58.webm.md5
|
||||
1fd7cd596170afce2de0b1441b7674bda5723440 *vp90-2-00-quantizer-59.webm
|
||||
4681f7ef96f63e085c41bb1a964b0df7e67e0b38 *vp90-2-00-quantizer-59.webm.md5
|
||||
34cdcc81c0ba7085aefbb22d7b4aa9bca3dd7c62 *vp90-2-00-quantizer-60.webm
|
||||
58691ef53b6b623810e2c57ded374c77535df935 *vp90-2-00-quantizer-60.webm.md5
|
||||
e6e812406aab81021bb16e772c1db03f75906cb6 *vp90-2-00-quantizer-61.webm
|
||||
76436eace62f08ff92b61a0845e66667a027db1b *vp90-2-00-quantizer-61.webm.md5
|
||||
84d811bceed70c950a6a08e572a6e274866e72b1 *vp90-2-00-quantizer-62.webm
|
||||
2d937cc011eeddd95222b960982da5cd18db580f *vp90-2-00-quantizer-62.webm.md5
|
||||
0912b295ba0ea09359315315ffd67d22d046f883 *vp90-2-00-quantizer-63.webm
|
||||
5a829031055d70565f57dbcd47a6ac33619952b3 *vp90-2-00-quantizer-63.webm.md5
|
||||
0cf9e5ebe0112bdb47b5887ee5d58eb9d4727c00 *vp90-2-01-sharpness-1.webm
|
||||
5a0476be4448bae8f8ca17ea236c98793a755948 *vp90-2-01-sharpness-1.webm.md5
|
||||
51e02d7911810cdf5be8b68ac40aedab479a3179 *vp90-2-01-sharpness-2.webm
|
||||
a0ca5bc87a5ed7c7051f59078daa0d03be1b45b6 *vp90-2-01-sharpness-2.webm.md5
|
||||
0603f8ad239c07a531d948187f4dafcaf51eda8d *vp90-2-01-sharpness-3.webm
|
||||
3af8000a69c72fe77881e3176f026c2affb78cc7 *vp90-2-01-sharpness-3.webm.md5
|
||||
4ca4839f48146252fb261ed88838d80211804841 *vp90-2-01-sharpness-4.webm
|
||||
08832a1494f84fa9edd40e080bcf2c0e80100c76 *vp90-2-01-sharpness-4.webm.md5
|
||||
95099dc8f9cbaf9b9a7dd65311923e441ff70731 *vp90-2-01-sharpness-5.webm
|
||||
93ceee30c140f0b406726c0d896b9db6031c4c7f *vp90-2-01-sharpness-5.webm.md5
|
||||
ceb4116fb7b078d266d153233b6d62a255a34e4c *vp90-2-01-sharpness-6.webm
|
||||
da83efe59e537ce538e8b03a6eac63cf25849c9a *vp90-2-01-sharpness-6.webm.md5
|
||||
b5f7cd19aece3880f9d616a778e5cc24c6b9b505 *vp90-2-01-sharpness-7.webm
|
||||
2957408d20deac8633941a2169f801bae6f086e1 *vp90-2-01-sharpness-7.webm.md5
|
||||
ffc096c2ce1050450ad462b5fabd2a5220846319 *vp90-2-02-size-08x08.webm
|
||||
e36d2ed6fa2746347710b750586aafa6a01ff3ae *vp90-2-02-size-08x08.webm.md5
|
||||
895b986f9fd55cd879472b31c6a06b82094418c8 *vp90-2-02-size-08x10.webm
|
||||
079157a19137ccaebba606f2871f45a397347150 *vp90-2-02-size-08x10.webm.md5
|
||||
1c5992203e62a2b83040ccbecd748b604e19f4c0 *vp90-2-02-size-08x16.webm
|
||||
9aa45ffdf2078f883bbed01450031b691819c144 *vp90-2-02-size-08x16.webm.md5
|
||||
d0a8953da1f85f484487408fee5da9e2a8391901 *vp90-2-02-size-08x18.webm
|
||||
59a5cc17d354c6a23e5e959d666b1456a5d49c56 *vp90-2-02-size-08x18.webm.md5
|
||||
1b13461a9fc65cb041bacfe4ea6f02d363397d61 *vp90-2-02-size-08x32.webm
|
||||
2bdddd6878f05d37d84cde056a3f5e7f926ba3d6 *vp90-2-02-size-08x32.webm.md5
|
||||
2861f0a0daadb62295b0504a1fbe5b50c79a8f59 *vp90-2-02-size-08x34.webm
|
||||
6b5812cfb8a82d378ea2913bf009e93668020147 *vp90-2-02-size-08x34.webm.md5
|
||||
02f948216d4246579dc53c47fe55d8fb264ba251 *vp90-2-02-size-08x64.webm
|
||||
84b55fdee6d9aa820c7a8c62822446184b191767 *vp90-2-02-size-08x64.webm.md5
|
||||
4b011242cbf42516efd2b197baebb61dd34562c9 *vp90-2-02-size-08x66.webm
|
||||
6b1fa0a885947b3cc0fe58f75f838e662bd9bb8b *vp90-2-02-size-08x66.webm.md5
|
||||
4057796be9dd12df48ab607f502ae6aa70eeeab6 *vp90-2-02-size-10x08.webm
|
||||
71c752c51aec9f48de286b93f4c20e9c11cad7d0 *vp90-2-02-size-10x08.webm.md5
|
||||
6583c853fa43fc53d51743eac5f3a43a359d45d0 *vp90-2-02-size-10x10.webm
|
||||
1da524d24af1944b671d4d3f2b398d6e336584c3 *vp90-2-02-size-10x10.webm.md5
|
||||
ba442fc03ccd3a705c64c83b36f5ada67d198874 *vp90-2-02-size-10x16.webm
|
||||
7cfd960f232c34c641a4a2a9411b6fd0efb2fc50 *vp90-2-02-size-10x16.webm.md5
|
||||
cc92ed40eef14f52e4d080cb2c57939dd8326374 *vp90-2-02-size-10x18.webm
|
||||
db5626275cc55ce970b91c995e74f6838d943aca *vp90-2-02-size-10x18.webm.md5
|
||||
3a93d501d22325e9fd4c9d8b82e2a432de33c351 *vp90-2-02-size-10x32.webm
|
||||
5cae51b0c71cfc131651f345f87583eb2903afaf *vp90-2-02-size-10x32.webm.md5
|
||||
50d2f2b15a9a5178153db44a9e03aaf32b227f67 *vp90-2-02-size-10x34.webm
|
||||
bb0efe058122641e7f73e94497dda2b9e6c21efd *vp90-2-02-size-10x34.webm.md5
|
||||
01624ec173e533e0b33fd9bdb91eb7360c7c9175 *vp90-2-02-size-10x64.webm
|
||||
b9c0e3b054463546356acf5157f9be92fd34732f *vp90-2-02-size-10x64.webm.md5
|
||||
2942879baf1c09e96b14d0fc84806abfe129c706 *vp90-2-02-size-10x66.webm
|
||||
bab5f539c2f91952e187456b4beafbb4c01e25ee *vp90-2-02-size-10x66.webm.md5
|
||||
88d2b63ca5e9ee163d8f20e8886f3df3ff301a66 *vp90-2-02-size-16x08.webm
|
||||
7f48a0fcf8c25963f3057d7f6669c5f2415834b8 *vp90-2-02-size-16x08.webm.md5
|
||||
59261eb34c15ea9b5ddd2d416215c1a8b9e6dc1f *vp90-2-02-size-16x10.webm
|
||||
73a7c209a46dd051c9f7339b6e02ccd5b3b9fc81 *vp90-2-02-size-16x10.webm.md5
|
||||
066834fef9cf5b9a72932cf4dea5f253e14a976d *vp90-2-02-size-16x16.webm
|
||||
faec542f52f37601cb9c480d887ae9355be99372 *vp90-2-02-size-16x16.webm.md5
|
||||
195307b4eb3192271ee4a935b0e48deef0c54cc2 *vp90-2-02-size-16x18.webm
|
||||
5a92e19e624c0376321d4d0e22c0c91995bc23e1 *vp90-2-02-size-16x18.webm.md5
|
||||
14f3f884216d7ae16ec521f024a2f2d31bbf9c1a *vp90-2-02-size-16x32.webm
|
||||
ea622d1c817dd174556f7ee7ccfe4942b34d4845 *vp90-2-02-size-16x32.webm.md5
|
||||
2e0501100578a5da9dd47e4beea160f945bdd1ba *vp90-2-02-size-16x34.webm
|
||||
1b8645ef64239334921c5f56b24ce815e6070b05 *vp90-2-02-size-16x34.webm.md5
|
||||
89a6797fbebebe93215f367229a9152277f5dcfe *vp90-2-02-size-16x64.webm
|
||||
a03d8c1179ca626a8856fb416d635dbf377979cd *vp90-2-02-size-16x64.webm.md5
|
||||
0f3a182e0750fcbae0b9eae80c7a53aabafdd18d *vp90-2-02-size-16x66.webm
|
||||
8cb6736dc2d897c1283919a32068af377d66c59c *vp90-2-02-size-16x66.webm.md5
|
||||
68fe70dc7914cc1d8d6dcd97388b79196ba3e7f1 *vp90-2-02-size-18x08.webm
|
||||
874c7fb505be9db3160c57cb405c4dbd5b990dc2 *vp90-2-02-size-18x08.webm.md5
|
||||
0546352dd78496d4dd86c3727ac2ff36c9e72032 *vp90-2-02-size-18x10.webm
|
||||
1d80eb36557ea5f25a386495a36f93da0f25316b *vp90-2-02-size-18x10.webm.md5
|
||||
60fe99e5f5cc99706efa3e0b894e45cbcf0d6330 *vp90-2-02-size-18x16.webm
|
||||
1ab6cdd89a53662995d103546e6611c84f9292ab *vp90-2-02-size-18x16.webm.md5
|
||||
f9a8f5fb749d69fd555db6ca093b7f77800c7b4f *vp90-2-02-size-18x18.webm
|
||||
ace8a66328f7802b15f9989c2720c029c6abd279 *vp90-2-02-size-18x18.webm.md5
|
||||
a197123a527ec25913a9bf52dc8c347749e00045 *vp90-2-02-size-18x32.webm
|
||||
34fbd7036752232d1663e70d7f7cdc93f7129202 *vp90-2-02-size-18x32.webm.md5
|
||||
f219655a639a774a2c9c0a9f45c28dc0b5e75e24 *vp90-2-02-size-18x34.webm
|
||||
2c4d622a9ea548791c1a07903d3702e9774388bb *vp90-2-02-size-18x34.webm.md5
|
||||
5308578da48c677d477a5404e19391d1303033c9 *vp90-2-02-size-18x64.webm
|
||||
e7fd4462527bac38559518ba80e41847db880f15 *vp90-2-02-size-18x64.webm.md5
|
||||
e109a7e013bd179f97e378542e1e81689ed06802 *vp90-2-02-size-18x66.webm
|
||||
45c04e422fb383c1f3be04beefaa4490e83bdb1a *vp90-2-02-size-18x66.webm.md5
|
||||
38844cae5d99caf445f7de33c3ae78494ce36c01 *vp90-2-02-size-32x08.webm
|
||||
ad018be39e493ca2405225034b1a5b7a42af6f3a *vp90-2-02-size-32x08.webm.md5
|
||||
7b57eaad55906f9de9903c8657a3fcb2aaf792ea *vp90-2-02-size-32x10.webm
|
||||
2294425d4e55d275af5e25a0beac9738a1b4ee73 *vp90-2-02-size-32x10.webm.md5
|
||||
f47ca2ced0d47f761bb0a5fdcd911d3f450fdcc1 *vp90-2-02-size-32x16.webm
|
||||
ae10981d93913f0ab1f28c1146255e01769aa8c0 *vp90-2-02-size-32x16.webm.md5
|
||||
08b23ad838b6cf1fbfe3ad7e7775d95573e815fc *vp90-2-02-size-32x18.webm
|
||||
1ba76f4c4a4ac7aabfa3ce195c1b473535eb7cc8 *vp90-2-02-size-32x18.webm.md5
|
||||
d5b88ae6c8c25c53dee74d9f1e6ca64244349a57 *vp90-2-02-size-32x32.webm
|
||||
e39c067a8ee2da52a51641eb1cb7f8eba935eb6b *vp90-2-02-size-32x32.webm.md5
|
||||
529429920dc36bd899059fa75a767f02c8c60874 *vp90-2-02-size-32x34.webm
|
||||
56888e7834f52b106e8911e3a7fc0f473b609995 *vp90-2-02-size-32x34.webm.md5
|
||||
38e848e160391c2b1a55040aadde613b9f4bf15e *vp90-2-02-size-32x64.webm
|
||||
8950485fb3f68b0e8be234db860e4ec5f5490fd0 *vp90-2-02-size-32x64.webm.md5
|
||||
5e8670f0b8ec9cefa8795b8959ffbe1a8e1aea94 *vp90-2-02-size-32x66.webm
|
||||
225df9d7d72ec711b0b60f4aeb65311c97db054a *vp90-2-02-size-32x66.webm.md5
|
||||
695f929e2ce6fb11a1f180322d46c5cb1c97fa61 *vp90-2-02-size-34x08.webm
|
||||
5bb4262030018dd01883965c6aa6070185924ef6 *vp90-2-02-size-34x08.webm.md5
|
||||
5adf74ec906d2ad3f7526e06bd29f5ad7d966a90 *vp90-2-02-size-34x10.webm
|
||||
71c100b437d3e8701632ae8d65c3555339b1c68f *vp90-2-02-size-34x10.webm.md5
|
||||
d0918923c987fba2d00193d83797b21289fe54aa *vp90-2-02-size-34x16.webm
|
||||
5d5a52f3535b4d2698dd3d87f4a13fdc9b57163d *vp90-2-02-size-34x16.webm.md5
|
||||
553ab0042cf87f5e668ec31b2e4b2a4b6ec196fd *vp90-2-02-size-34x18.webm
|
||||
a164c7f3c424987df2340496e6a8cf76e973f0f1 *vp90-2-02-size-34x18.webm.md5
|
||||
baf3e233634f150de81c18ba5d8848068e1c3c54 *vp90-2-02-size-34x32.webm
|
||||
22a79d3bd1c9b85dfe8c70bb2e19f08a92a8be03 *vp90-2-02-size-34x32.webm.md5
|
||||
6d50a533774a7167350e4a7ef43c94a5622179a2 *vp90-2-02-size-34x34.webm
|
||||
0c099638e79c273546523e06704553e42eb00b00 *vp90-2-02-size-34x34.webm.md5
|
||||
698cdd0a5e895cc202c488675e682a8c537ede4f *vp90-2-02-size-34x64.webm
|
||||
9317b63987cddab8389510a27b86f9f3d46e3fa5 *vp90-2-02-size-34x64.webm.md5
|
||||
4b5335ca06f082b6b69f584eb8e7886bdcafefd3 *vp90-2-02-size-34x66.webm
|
||||
e18d68b35428f46a84a947c646804a51ef1d7cec *vp90-2-02-size-34x66.webm.md5
|
||||
a54ae7b494906ec928a876e8290e5574f2f9f6a2 *vp90-2-02-size-64x08.webm
|
||||
87f9f7087b6489d45e9e4b38ede2c5aef4a4928f *vp90-2-02-size-64x08.webm.md5
|
||||
24522c70804a3c23d937df2d829ae63965b23f38 *vp90-2-02-size-64x10.webm
|
||||
447ce03938ab53bffcb4a841ee0bfaa90462dcb9 *vp90-2-02-size-64x10.webm.md5
|
||||
2a5035d035d214ae614af8051930690ef623989b *vp90-2-02-size-64x16.webm
|
||||
84e355761dd2e0361b904c84c52a0dd0384d89cf *vp90-2-02-size-64x16.webm.md5
|
||||
3a293ef4e270a19438e59b817fbe5f43eed4d36b *vp90-2-02-size-64x18.webm
|
||||
666824e5ba746779eb46079e0631853dcc86d48b *vp90-2-02-size-64x18.webm.md5
|
||||
ed32fae837095c9e8fc95d223ec68101812932c2 *vp90-2-02-size-64x32.webm
|
||||
97086eadedce1d0d9c072b585ba7b49aec69b1e7 *vp90-2-02-size-64x32.webm.md5
|
||||
696c7a7250bdfff594f4dfd88af34239092ecd00 *vp90-2-02-size-64x34.webm
|
||||
253a1d38d452e7826b086846c6f872f829c276bb *vp90-2-02-size-64x34.webm.md5
|
||||
fc508e0e3c2e6872c60919a60b812c5232e9c2b0 *vp90-2-02-size-64x64.webm
|
||||
2cd6ebeca0f82e9f505616825c07950371b905ab *vp90-2-02-size-64x64.webm.md5
|
||||
0f8a4fc1d6521187660425c283f08dff8c66e476 *vp90-2-02-size-64x66.webm
|
||||
5806be11a1d346be235f88d3683e69f73746166c *vp90-2-02-size-64x66.webm.md5
|
||||
273b0c36e3658685cde250408a478116d7ae92f1 *vp90-2-02-size-66x08.webm
|
||||
23c3cd0dca20a2f71f036e77ea92025ff4e7a298 *vp90-2-02-size-66x08.webm.md5
|
||||
4844c59c3306d1e671bb0568f00e344bf797e66e *vp90-2-02-size-66x10.webm
|
||||
e041eaf6841d775f8fde8bbb4949d2733fdaab7f *vp90-2-02-size-66x10.webm.md5
|
||||
bdf3f1582b234fcd2805ffec59f9d716a2345302 *vp90-2-02-size-66x16.webm
|
||||
2ec85ee18119e6798968571ea6e1b93ca386e3af *vp90-2-02-size-66x16.webm.md5
|
||||
0acce9af12b13b025d5274013da7ef6f568f075f *vp90-2-02-size-66x18.webm
|
||||
77c4d53e2a5c96b70af9d575fe6811e0f5ee627b *vp90-2-02-size-66x18.webm.md5
|
||||
682b36a25774bbdedcd603f504d18eb63f0167d4 *vp90-2-02-size-66x32.webm
|
||||
53728fae2a428f16d376a29f341a64ddca97996a *vp90-2-02-size-66x32.webm.md5
|
||||
e71b70e901e29eaa6672a6aa4f37f6f5faa02bd6 *vp90-2-02-size-66x34.webm
|
||||
f69a6a555e3f614b0a35f9bfc313d8ebb35bc725 *vp90-2-02-size-66x34.webm.md5
|
||||
4151b8c29452d5c2266397a7b9bf688899a2937b *vp90-2-02-size-66x64.webm
|
||||
69486e7fd9e380b6c97a03d3e167affc79f73840 *vp90-2-02-size-66x64.webm.md5
|
||||
68784a1ecac776fe2a3f230345af32f06f123536 *vp90-2-02-size-66x66.webm
|
||||
7f008c7f48d55e652fbd6bac405b51e0015c94f2 *vp90-2-02-size-66x66.webm.md5
|
||||
7e1bc449231ac1c5c2a11c9a6333b3e828763798 *vp90-2-03-size-196x196.webm
|
||||
6788a561466dace32d500194bf042e19cccc35e1 *vp90-2-03-size-196x196.webm.md5
|
||||
a170c9a88ec1dd854c7a471ff55fb2a97ac31870 *vp90-2-03-size-196x198.webm
|
||||
6bf9d6a8e2bdc5bf4f8a78071a3fed5ca02ad6f2 *vp90-2-03-size-196x198.webm.md5
|
||||
68f861d21c4c8b03d572c3d3fcd9f4fbf1f4503f *vp90-2-03-size-196x200.webm
|
||||
bbfc260b2bfd872cc6054272bb6b7f959a9e1c6e *vp90-2-03-size-196x200.webm.md5
|
||||
fc34889feeca2b7e5b27b4f1ce22d2e2b8e3e4b1 *vp90-2-03-size-196x202.webm
|
||||
158ee72af578f39aad0c3b8f4cbed2fc78b57e0f *vp90-2-03-size-196x202.webm.md5
|
||||
dd28fb7247af534bdf5e6795a3ac429610489a0b *vp90-2-03-size-196x208.webm
|
||||
7546be847efce2d1c0a23f807bfb03f91b764e1e *vp90-2-03-size-196x208.webm.md5
|
||||
41d5cf5ed65b722a1b6dc035e67f978ea8ffecf8 *vp90-2-03-size-196x210.webm
|
||||
9444fdf632d6a1b6143f4cb10fed8f63c1d67ec1 *vp90-2-03-size-196x210.webm.md5
|
||||
5007bc618143437c009d6dde5fc2e86f72d37dc2 *vp90-2-03-size-196x224.webm
|
||||
858361d8f79b44df5545feabbc9754ec9ede632f *vp90-2-03-size-196x224.webm.md5
|
||||
0bcbe357fbc776c3fa68e7117179574ed7564a44 *vp90-2-03-size-196x226.webm
|
||||
72006a5f42031a43d70a2cd9fc1958962a86628f *vp90-2-03-size-196x226.webm.md5
|
||||
000239f048cceaac055558e97ef07078ebf65502 *vp90-2-03-size-198x196.webm
|
||||
2d6841901b72000c5340f30be602853438c1b787 *vp90-2-03-size-198x196.webm.md5
|
||||
ae75b766306a6404c3b3b35a6b6d53633c14fbdb *vp90-2-03-size-198x198.webm
|
||||
3f2544b4f3b4b643a98f2c3b15ea5826fc702fa1 *vp90-2-03-size-198x198.webm.md5
|
||||
95ffd573fa84ccef1cd59e1583e6054f56a5c83d *vp90-2-03-size-198x200.webm
|
||||
5d537e3c9b9c54418c79677543454c4cda3de1af *vp90-2-03-size-198x200.webm.md5
|
||||
ecc845bf574375f469bc91bf5c75c79dc00073d6 *vp90-2-03-size-198x202.webm
|
||||
1b59f5e111265615a7a459eeda8cc9045178d228 *vp90-2-03-size-198x202.webm.md5
|
||||
432fb27144fe421b9f51cf44d2750a26133ed585 *vp90-2-03-size-198x208.webm
|
||||
a58a67f4fb357c73ca078aeecbc0f782975630b1 *vp90-2-03-size-198x208.webm.md5
|
||||
ff5058e7e6a47435046612afc8536f2040989e6f *vp90-2-03-size-198x210.webm
|
||||
18d3be7935e52217e2e9400b6f2c681a9e45dc89 *vp90-2-03-size-198x210.webm.md5
|
||||
a0d55263c1ed2c03817454dd4ec4090d36dbc864 *vp90-2-03-size-198x224.webm
|
||||
efa366a299817e2da51c00623b165aab9fbb8d91 *vp90-2-03-size-198x224.webm.md5
|
||||
ccd142fa2920fc85bb753f049160c1c353ad1574 *vp90-2-03-size-198x226.webm
|
||||
534524a0b2dbff852e0b92ef09939db072f83243 *vp90-2-03-size-198x226.webm.md5
|
||||
0d483b94ed40abc8ab6e49f960432ee54ad9c7f1 *vp90-2-03-size-200x196.webm
|
||||
41795f548181717906e7a504ba551f06c32102ae *vp90-2-03-size-200x196.webm.md5
|
||||
f6c2dc54e0989d50f01333fe40c91661fcbf849a *vp90-2-03-size-200x198.webm
|
||||
43df5d8c46a40089441392e6d096c588c1079a68 *vp90-2-03-size-200x198.webm.md5
|
||||
2f6e9df82e44fc145f0d9212dcccbed3de605e23 *vp90-2-03-size-200x200.webm
|
||||
757b2ef96b82093255725bab9690bbafe27f3caf *vp90-2-03-size-200x200.webm.md5
|
||||
40c5ea60415642a4a2e75c0d127b06309baadfab *vp90-2-03-size-200x202.webm
|
||||
3022c4a1c625b5dc04fdb1052d17d45b4171cfba *vp90-2-03-size-200x202.webm.md5
|
||||
6942ed5b27476bb8506d10e600d6ff60887780ca *vp90-2-03-size-200x208.webm
|
||||
c4ab8c66f3cf2dc8e8dd7abae9ac21f4d32cd6be *vp90-2-03-size-200x208.webm.md5
|
||||
71dbc99b83c49d1da45589b91eabb98e2f4a7b1e *vp90-2-03-size-200x210.webm
|
||||
3f0b40da7eef7974b9bc326562f251feb67d9c7c *vp90-2-03-size-200x210.webm.md5
|
||||
6b6b8489081cfefb377cc5f18eb754ec2383f655 *vp90-2-03-size-200x224.webm
|
||||
a259df2ac0e294492e3f9d4315baa34cab044f04 *vp90-2-03-size-200x224.webm.md5
|
||||
c9adc1c9bb07559349a0b054df4af56f7a6edbb9 *vp90-2-03-size-200x226.webm
|
||||
714cec61e3575581e4f1a0e3921f4dfdbbd316c5 *vp90-2-03-size-200x226.webm.md5
|
||||
f9bdc936bdf53f8be9ce78fecd41a21d31ff3943 *vp90-2-03-size-202x196.webm
|
||||
5b8e2e50fcea2c43b12fc067b8a9cc117af77bda *vp90-2-03-size-202x196.webm.md5
|
||||
c7b66ea3da87613deb47ff24a111247d3c384fec *vp90-2-03-size-202x198.webm
|
||||
517e91204b25586da943556f4adc5951c9be8bee *vp90-2-03-size-202x198.webm.md5
|
||||
935ef56b01cfdb4265a7e24696645209ccb20970 *vp90-2-03-size-202x200.webm
|
||||
55b8ec4a2513183144a8e27564596c06c7576fce *vp90-2-03-size-202x200.webm.md5
|
||||
849acf75e4f1d8d90046704e1103a18c64f30e35 *vp90-2-03-size-202x202.webm
|
||||
c79afc6660df2824e7df314e5bfd71f0d8acf76b *vp90-2-03-size-202x202.webm.md5
|
||||
17b3a4d55576b770626ccb856b9f1a6c8f6ae476 *vp90-2-03-size-202x208.webm
|
||||
0b887ff30409c58f2ccdc3bfacd6be7c69f8997a *vp90-2-03-size-202x208.webm.md5
|
||||
032d0ade4230fb2eef6d19915a7a1c9aa4a52617 *vp90-2-03-size-202x210.webm
|
||||
f78f8e79533c0c88dd2bfdcec9b1c07848568ece *vp90-2-03-size-202x210.webm.md5
|
||||
915a38c31fe425d5b93c837121cfa8082f5ea5bc *vp90-2-03-size-202x224.webm
|
||||
bf52a104074d0c5942aa7a5b31e11db47e43d48e *vp90-2-03-size-202x224.webm.md5
|
||||
be5cfde35666fa435e47d544d9258215beb1cf29 *vp90-2-03-size-202x226.webm
|
||||
2fa2f87502fda756b319389c8975204e130a2e3f *vp90-2-03-size-202x226.webm.md5
|
||||
15d908e97862b5b4bf295610df011fb9aa09909b *vp90-2-03-size-208x196.webm
|
||||
50c60792305d6a99be376dd596a6ff979325e6cc *vp90-2-03-size-208x196.webm.md5
|
||||
a367c7bc9fde56d6f4848cc573c7d4c1ce75e348 *vp90-2-03-size-208x198.webm
|
||||
be85fb2c8d435a75484231356f07d06ebddd13cd *vp90-2-03-size-208x198.webm.md5
|
||||
05fd46deb7288e7253742091f56e54a9a441a187 *vp90-2-03-size-208x200.webm
|
||||
74f8ec3b3a2fe81767ed1ab36a47bc0062d6223c *vp90-2-03-size-208x200.webm.md5
|
||||
d8985c4b386513a7385a4b3639bf91e469f1378b *vp90-2-03-size-208x202.webm
|
||||
0614a1e8d92048852adcf605a51333f5fabc7f03 *vp90-2-03-size-208x202.webm.md5
|
||||
28b002242238479165ba4fb87ee6b442c64b32e4 *vp90-2-03-size-208x208.webm
|
||||
37de5aca59bb900228400b0e115d3229edb9dcc0 *vp90-2-03-size-208x208.webm.md5
|
||||
c545be0050c2fad7c68427dbf86c62a739e94ab3 *vp90-2-03-size-208x210.webm
|
||||
d646eccb3cd578f94b54777e32b88898bef6e17a *vp90-2-03-size-208x210.webm.md5
|
||||
63a0cfe295b661026dd7b1bebb67acace1db766f *vp90-2-03-size-208x224.webm
|
||||
85c0361d93bf85a335248fef2767ff43eeef23db *vp90-2-03-size-208x224.webm.md5
|
||||
f911cc718d66e4fe8a865226088939c9eb1b7825 *vp90-2-03-size-208x226.webm
|
||||
a6d583a57876e7b7ec48625b2b2cdbcf70cab837 *vp90-2-03-size-208x226.webm.md5
|
||||
5bbb0f36da9a4683cf04e724124d8696332911bf *vp90-2-03-size-210x196.webm
|
||||
a3580fc7816d7fbcfb54fdba501cabbd06ba2f1d *vp90-2-03-size-210x196.webm.md5
|
||||
8db64d6f9ce36dd382013b42ae4e292deba697bc *vp90-2-03-size-210x198.webm
|
||||
eda20f8268c7f4147bead4059e9c4897e09140a9 *vp90-2-03-size-210x198.webm.md5
|
||||
ce391505eeaf1d12406563101cd6b2dbbbb44bfc *vp90-2-03-size-210x200.webm
|
||||
79d73b7f623082d2a00aa33e95c79d11c7d9c3a8 *vp90-2-03-size-210x200.webm.md5
|
||||
852db6fdc206e72391fc69b807f1954934679949 *vp90-2-03-size-210x202.webm
|
||||
f69414c5677ed2f2b8b37ae76429e509a92276a5 *vp90-2-03-size-210x202.webm.md5
|
||||
c424cc3edd2308da7d33f27acb36b54db5bf2595 *vp90-2-03-size-210x208.webm
|
||||
27b18562faa1b3184256f4eae8114b539b3e9d3e *vp90-2-03-size-210x208.webm.md5
|
||||
dd029eba719d50a2851592fa8b9b2efe88904930 *vp90-2-03-size-210x210.webm
|
||||
c853a1670465eaa04ca31b3511995f1b6ed4f58f *vp90-2-03-size-210x210.webm.md5
|
||||
d962e8ae676c54d0c3ea04ec7c04b37ae6a786e3 *vp90-2-03-size-210x224.webm
|
||||
93b793e79d987065b39ad8e2e71244368435fc25 *vp90-2-03-size-210x224.webm.md5
|
||||
3d0825fe83bcc125be1f78145ff43ca6d7588784 *vp90-2-03-size-210x226.webm
|
||||
5230f31a57ca3b5311698a12035d2644533b3ec4 *vp90-2-03-size-210x226.webm.md5
|
||||
6622f8bd9279e1ce45509a58a31a990052d45e14 *vp90-2-03-size-224x196.webm
|
||||
65411da07f60113f2be05c807879072b161d561e *vp90-2-03-size-224x196.webm.md5
|
||||
6744ff2ee2c41eb08c62ff30880833b6d77b585b *vp90-2-03-size-224x198.webm
|
||||
46ea3641d41acd4bff347b224646c060d5620385 *vp90-2-03-size-224x198.webm.md5
|
||||
8eb91f3416a1404705f370caecd74b2b458351b1 *vp90-2-03-size-224x200.webm
|
||||
196aefb854c8b95b9330263d6690b7ee15693ecf *vp90-2-03-size-224x200.webm.md5
|
||||
256a5a23ef4e6d5ef2871af5afb8cd13d28cec00 *vp90-2-03-size-224x202.webm
|
||||
840ad8455dcf2be378c14b007e66fa642fc8196d *vp90-2-03-size-224x202.webm.md5
|
||||
db4606480ab48b96c9a6ff5e639f1f1aea2a12e4 *vp90-2-03-size-224x208.webm
|
||||
40b9801d5620467499ac70fa6b7c40aaa5e1c331 *vp90-2-03-size-224x208.webm.md5
|
||||
e37159e687fe1cb24cffddfae059301adbaf4212 *vp90-2-03-size-224x210.webm
|
||||
1e4acd4b6334ae260c3eed08652d0ba8122073f2 *vp90-2-03-size-224x210.webm.md5
|
||||
0de1eb4bb6285ae621e4f2b613d2aa4a8c95a130 *vp90-2-03-size-224x224.webm
|
||||
37db449ad86fb286c2c02d94aa8fe0379c05044a *vp90-2-03-size-224x224.webm.md5
|
||||
32ebbf903a7d7881bcfe59639f1d472371f3bf27 *vp90-2-03-size-224x226.webm
|
||||
5cc3ac5dc9f6912491aa2ddac863f8187f34c569 *vp90-2-03-size-224x226.webm.md5
|
||||
9480ff5c2c32b1870ac760c87514912616e6cf01 *vp90-2-03-size-226x196.webm
|
||||
fe83655c0f1888f0af7b047785f01ba7ca9f1324 *vp90-2-03-size-226x196.webm.md5
|
||||
09cad4221996315cdddad4e502dbfabf53ca1d6a *vp90-2-03-size-226x198.webm
|
||||
e3ddfdc650acb95adb45abd9b634e1f09ea8ac96 *vp90-2-03-size-226x198.webm.md5
|
||||
c34f49d55fe39e3f0b607e3cc95e30244225cecb *vp90-2-03-size-226x200.webm
|
||||
abb83edc868a3523ccd4e5523fac2efbe7c3df1f *vp90-2-03-size-226x200.webm.md5
|
||||
d17bc08eedfc60c4c23d576a6c964a21bf854d1f *vp90-2-03-size-226x202.webm
|
||||
1d22d2d0f375251c2d5a1acb4714bc35d963865b *vp90-2-03-size-226x202.webm.md5
|
||||
9bd537c4f92a25596ccd29fedfe181feac948b92 *vp90-2-03-size-226x208.webm
|
||||
6feb0e7325386275719f3511ada9e248a2ae7df4 *vp90-2-03-size-226x208.webm.md5
|
||||
4487067f6cedd495b93696b44b37fe0a3e7eda14 *vp90-2-03-size-226x210.webm
|
||||
49a8fa87945f47208168d541c068e78d878075d5 *vp90-2-03-size-226x210.webm.md5
|
||||
559fea2f8da42b33c1aa1dbc34d1d6781009847a *vp90-2-03-size-226x224.webm
|
||||
83c6d8f2969b759e10e5c6542baca1265c874c29 *vp90-2-03-size-226x224.webm.md5
|
||||
fe0af2ee47b1e5f6a66db369e2d7e9d870b38dce *vp90-2-03-size-226x226.webm
|
||||
94ad19b8b699cea105e2ff18f0df2afd7242bcf7 *vp90-2-03-size-226x226.webm.md5
|
||||
52bc1dfd3a97b24d922eb8a31d07527891561f2a *vp90-2-03-size-352x288.webm
|
||||
3084d6d0a1eec22e85a394422fbc8faae58930a5 *vp90-2-03-size-352x288.webm.md5
|
||||
b6524e4084d15b5d0caaa3d3d1368db30cbee69c *vp90-2-03-deltaq.webm
|
||||
65f45ec9a55537aac76104818278e0978f94a678 *vp90-2-03-deltaq.webm.md5
|
||||
4dbb87494c7f565ffc266c98d17d0d8c7a5c5aba *vp90-2-05-resize.ivf
|
||||
7f6d8879336239a43dbb6c9f13178cb11cf7ed09 *vp90-2-05-resize.ivf.md5
|
||||
bf61ddc1f716eba58d4c9837d4e91031d9ce4ffe *vp90-2-06-bilinear.webm
|
||||
f6235f937552e11d8eb331ec55da6b3aa596b9ac *vp90-2-06-bilinear.webm.md5
|
||||
0c83a1e414fde3bccd6dc451bbaee68e59974c76 *vp90-2-07-frame_parallel.webm
|
||||
e5c2c9fb383e5bf3b563480adaeba5b7e3475ecd *vp90-2-07-frame_parallel.webm.md5
|
||||
086c7edcffd699ae7d99d710fd7e53b18910ca5b *vp90-2-08-tile_1x2_frame_parallel.webm
|
||||
e981ecaabb29a80e0cbc1f4002384965ce8e95bb *vp90-2-08-tile_1x2_frame_parallel.webm.md5
|
||||
ed79be026a6f28646c5825da1c12d1fbc70f96a4 *vp90-2-08-tile_1x2.webm
|
||||
45b404e025841c9750895fc1a9f6bd384fe6a315 *vp90-2-08-tile_1x2.webm.md5
|
||||
cf8ea970c776797aae71dac8317ea926d9431cab *vp90-2-08-tile_1x4_frame_parallel.webm
|
||||
a481fbea465010b57af5a19ebf6d4a5cfe5b9278 *vp90-2-08-tile_1x4_frame_parallel.webm.md5
|
||||
0203ec456277a01aec401e7fb6c72c9a7e5e3f9d *vp90-2-08-tile_1x4.webm
|
||||
c9b237dfcc01c1b414fbcaa481d014a906ef7998 *vp90-2-08-tile_1x4.webm.md5
|
||||
20c75157e91ab41f82f70ffa73d5d01df8469287 *vp90-2-08-tile-4x4.webm
|
||||
ae7451810247fd13975cc257aa0301ff17102255 *vp90-2-08-tile-4x4.webm.md5
|
||||
2ec6e15422ac7a61af072dc5f27fcaf1942ce116 *vp90-2-08-tile-4x1.webm
|
||||
0094f5ee5e46345017c30e0aa4835b550212d853 *vp90-2-08-tile-4x1.webm.md5
|
||||
edea45dac4a3c2e5372339f8851d24c9bef803d6 *vp90-2-09-subpixel-00.ivf
|
||||
5428efc4bf92191faedf4a727fcd1d94966a7abc *vp90-2-09-subpixel-00.ivf.md5
|
||||
8cdd435d89029987ee196896e21520e5f879f04d *vp90-2-bbb_1280x720_tile_1x4_1310kbps.webm
|
||||
091b373aa2ecb59aa5c647affd5bcafcc7547364 *vp90-2-bbb_1920x1080_tile_1x1_2581kbps.webm
|
||||
87ee28032b0963a44b73a850fcc816a6dc83efbb *vp90-2-bbb_1920x1080_tile_1x4_2586kbps.webm
|
||||
c6ce25c4bfd4bdfc2932b70428e3dfe11210ec4f *vp90-2-bbb_1920x1080_tile_1x4_fpm_2304kbps.webm
|
||||
2064bdb22aa71c2691e0469fb62e8087a43f08f8 *vp90-2-bbb_426x240_tile_1x1_180kbps.webm
|
||||
8080eda22694910162f0996e8a962612f381a57f *vp90-2-bbb_640x360_tile_1x2_337kbps.webm
|
||||
a484b335c27ea189c0f0d77babea4a510ce12d50 *vp90-2-bbb_854x480_tile_1x2_651kbps.webm
|
||||
3eacf1f006250be4cc5c92a7ef146e385ee62653 *vp90-2-sintel_1280x546_tile_1x4_1257kbps.webm
|
||||
217f089a16447490823127b36ce0d945522accfd *vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm
|
||||
eedb3c641e60dacbe082491a16df529a5c9187df *vp90-2-sintel_426x182_tile_1x1_171kbps.webm
|
||||
cb7e4955af183dff33bcba0c837f0922ab066400 *vp90-2-sintel_640x272_tile_1x2_318kbps.webm
|
||||
48613f9380e2580002f8a09d6e412ea4e89a52b9 *vp90-2-sintel_854x364_tile_1x2_621kbps.webm
|
||||
990a91f24dd284562d21d714ae773dff5452cad8 *vp90-2-tos_1280x534_tile_1x4_1306kbps.webm
|
||||
aa402217577a659cfc670157735b4b8e9aa670fe *vp90-2-tos_1280x534_tile_1x4_fpm_952kbps.webm
|
||||
b6dd558c90bca466b4bcbd03b3371648186465a7 *vp90-2-tos_1920x800_tile_1x4_fpm_2335kbps.webm
|
||||
1a9c2914ba932a38f0a143efc1ad0e318e78888b *vp90-2-tos_426x178_tile_1x1_181kbps.webm
|
||||
a3d2b09f24debad4747a1b3066f572be4273bced *vp90-2-tos_640x266_tile_1x2_336kbps.webm
|
||||
c64b03b5c090e6888cb39685c31f00a6b79fa45c *vp90-2-tos_854x356_tile_1x2_656kbps.webm
|
||||
94b533dbcf94292001e27cc51fec87f9e8c90c0b *vp90-2-tos_854x356_tile_1x2_fpm_546kbps.webm
|
||||
0e7cd4135b231c9cea8d76c19f9e84b6fd77acec *vp90-2-08-tile_1x8_frame_parallel.webm
|
||||
c9b6850af28579b031791066457f4cb40df6e1c7 *vp90-2-08-tile_1x8_frame_parallel.webm.md5
|
||||
e448b6e83490bca0f8d58b4f4b1126a17baf4b0c *vp90-2-08-tile_1x8.webm
|
||||
5e524165f0397e6141d914f4f0a66267d7658376 *vp90-2-08-tile_1x8.webm.md5
|
||||
a34e14923d6d17b1144254d8187d7f85b700a63c *vp90-2-02-size-lf-1920x1080.webm
|
||||
e3b28ddcfaeb37fb4d132b93f92642a9ad17c22d *vp90-2-02-size-lf-1920x1080.webm.md5
|
||||
d48c5db1b0f8e60521a7c749696b8067886033a3 *vp90-2-09-aq2.webm
|
||||
84c1599298aac78f2fc05ae2274575d10569dfa0 *vp90-2-09-aq2.webm.md5
|
||||
55fc55ed73d578ed60fad05692579873f8bad758 *vp90-2-09-lf_deltas.webm
|
||||
54638c38009198c38c8f3b25c182b709b6c1fd2e *vp90-2-09-lf_deltas.webm.md5
|
||||
510d95f3beb3b51c572611fdaeeece12277dac30 *vp90-2-10-show-existing-frame.webm
|
||||
14d631096f4bfa2d71f7f739aec1448fb3c33bad *vp90-2-10-show-existing-frame.webm.md5
|
||||
d2feea7728e8d2c615981d0f47427a4a5a45d881 *vp90-2-10-show-existing-frame2.webm
|
||||
5f7c7811baa3e4f03be1dd78c33971b727846821 *vp90-2-10-show-existing-frame2.webm.md5
|
||||
b4318e75f73a6a08992c7326de2fb589c2a794c7 *vp90-2-11-size-351x287.webm
|
||||
b3c48382cf7d0454e83a02497c229d27720f9e20 *vp90-2-11-size-351x287.webm.md5
|
||||
8e0096475ea2535bac71d3e2fc09e0c451c444df *vp90-2-11-size-351x288.webm
|
||||
19e003804ec1dfc5464813b32339a15d5ba7b42f *vp90-2-11-size-351x288.webm.md5
|
||||
40cd1d6a188d7a88b21ebac1e573d3f270ab261e *vp90-2-11-size-352x287.webm
|
||||
68f515abe3858fc1eded46c8e6b2f727d43b5331 *vp90-2-11-size-352x287.webm.md5
|
||||
9a510769ff23db410880ec3029d433e87d17f7fc *vp90-2-12-droppable_1.ivf
|
||||
952eaac6eefa6f62179ed1db3e922fd42fecc624 *vp90-2-12-droppable_1.ivf.md5
|
||||
9a510769ff23db410880ec3029d433e87d17f7fc *vp90-2-12-droppable_2.ivf
|
||||
92a756469fa438220524e7fa6ac1d38c89514d17 *vp90-2-12-droppable_2.ivf.md5
|
||||
c21e97e4ba486520118d78b01a5cb6e6dc33e190 *vp90-2-12-droppable_3.ivf
|
||||
601abc9e4176c70f82ac0381365e9b151fdd24cd *vp90-2-12-droppable_3.ivf.md5
|
||||
61c640dad23cd4f7ad811b867e7b7e3521f4e3ba *vp90-2-13-largescaling.webm
|
||||
bca1b02eebdb088fa3f389fe0e7571e75a71f523 *vp90-2-13-largescaling.webm.md5
|
||||
c740708fa390806eebaf669909c1285ab464f886 *vp90-2-14-resize-fp-tiles-1-2.webm
|
||||
c7b85ffd8e11500f73f52e7dc5a47f57c393d47f *vp90-2-14-resize-fp-tiles-1-2.webm.md5
|
||||
ec8faa352a08f7033c60f29f80d505e2d7daa103 *vp90-2-14-resize-fp-tiles-1-4.webm
|
||||
6852c783fb421bda5ded3d4c5a3ffc46de03fbc1 *vp90-2-14-resize-fp-tiles-1-4.webm.md5
|
||||
8af61853ac0d07c4cb5bf7c2016661ba350b3497 *vp90-2-14-resize-fp-tiles-1-8.webm
|
||||
571353bac89fea60b5706073409aa3c0d42aefe9 *vp90-2-14-resize-fp-tiles-1-8.webm.md5
|
||||
b1c187ed69931496b82ec194017a79831bafceef *vp90-2-14-resize-fp-tiles-1-16.webm
|
||||
1c199a41afe42ce303944d70089eaaa2263b4a09 *vp90-2-14-resize-fp-tiles-1-16.webm.md5
|
||||
8eaae5a6f2dff934610b0c7a917d7f583ba74aa5 *vp90-2-14-resize-fp-tiles-2-1.webm
|
||||
db18fcf915f7ffaea6c39feab8bda6c1688af011 *vp90-2-14-resize-fp-tiles-2-1.webm.md5
|
||||
bc3046d138941e2a20e9ceec0ff6d25c25d12af3 *vp90-2-14-resize-fp-tiles-4-1.webm
|
||||
393211b808030d09a79927b17a4374b2f68a60ae *vp90-2-14-resize-fp-tiles-4-1.webm.md5
|
||||
6e8f8e31721a0f7f68a2964e36e0e698c2e276b1 *vp90-2-14-resize-fp-tiles-8-1.webm
|
||||
491fd3cd78fb0577bfe905bb64bbf64bd7d29140 *vp90-2-14-resize-fp-tiles-8-1.webm.md5
|
||||
cc5958da2a7edf739cd2cfeb18bd05e77903087e *vp90-2-14-resize-fp-tiles-16-1.webm
|
||||
0b58daf55aaf9063bf5b4fb33393d18b417dc428 *vp90-2-14-resize-fp-tiles-16-1.webm.md5
|
||||
821eeecc9d8c6a316134dd42d1ff057787d8047b *vp90-2-14-resize-fp-tiles-2-4.webm
|
||||
374c549f2839a3d0b732c4e3650700144037e76c *vp90-2-14-resize-fp-tiles-2-4.webm.md5
|
||||
dff8c8e49aacea9f4c7f22cb882da984e2a1b405 *vp90-2-14-resize-fp-tiles-2-8.webm
|
||||
e5b8820a7c823b21297d6e889e57ec401882c210 *vp90-2-14-resize-fp-tiles-2-8.webm.md5
|
||||
77629e4b23e32896aadf6e994c78bd4ffa1c7797 *vp90-2-14-resize-fp-tiles-2-16.webm
|
||||
1937f5df032664ac345d4613ad4417b4967b1230 *vp90-2-14-resize-fp-tiles-2-16.webm.md5
|
||||
380ba5702bb1ec7947697314ab0300b5c56a1665 *vp90-2-14-resize-fp-tiles-4-2.webm
|
||||
fde7b30d2aa64c1e851a4852f655d79fc542cf66 *vp90-2-14-resize-fp-tiles-4-2.webm.md5
|
||||
dc784b258ffa2abc2ae693d11792acf0bb9cb74f *vp90-2-14-resize-fp-tiles-8-2.webm
|
||||
edf26f0130aeee8342d49c2c8f0793ad008782d9 *vp90-2-14-resize-fp-tiles-8-2.webm.md5
|
||||
8e575789fd63ebf69e8eff1b9a4351a249a73bee *vp90-2-14-resize-fp-tiles-16-2.webm
|
||||
b6415318c1c589a1f64b9d569ce3cabbec2e0d52 *vp90-2-14-resize-fp-tiles-16-2.webm.md5
|
||||
e3adc944a11c4c5517e63664c84ebb0847b64d81 *vp90-2-14-resize-fp-tiles-4-8.webm
|
||||
03cba0532bc90a05b1990db830bf5701e24e7982 *vp90-2-14-resize-fp-tiles-4-8.webm.md5
|
||||
3b27a991eb6d78dce38efab35b7db682e8cbbee3 *vp90-2-14-resize-fp-tiles-4-16.webm
|
||||
5d16b7f82bf59f802724ddfd97abb487150b1c9d *vp90-2-14-resize-fp-tiles-4-16.webm.md5
|
||||
d5fed8c28c1d4c7e232ebbd25cf758757313ed96 *vp90-2-14-resize-fp-tiles-8-4.webm
|
||||
5a8ff8a52cbbde7bfab569beb6d971c5f8b904f7 *vp90-2-14-resize-fp-tiles-8-4.webm.md5
|
||||
17a5faa023d77ee9dad423a4e0d3145796bbc500 *vp90-2-14-resize-fp-tiles-16-4.webm
|
||||
2ef8daa3c3e750fd745130d0a76a39fe86f0448f *vp90-2-14-resize-fp-tiles-16-4.webm.md5
|
||||
9361e031f5cc990d8740863e310abb5167ae351e *vp90-2-14-resize-fp-tiles-8-16.webm
|
||||
57f13a2197486584f4e1a4f82ad969f3abc5a1a2 *vp90-2-14-resize-fp-tiles-8-16.webm.md5
|
||||
5803fc6fcbfb47b7661f3fcc6499158a32b56675 *vp90-2-14-resize-fp-tiles-16-8.webm
|
||||
be0fe64a1a4933696ff92d93f9bdecdbd886dc13 *vp90-2-14-resize-fp-tiles-16-8.webm.md5
|
||||
0ac0f6d20a0afed77f742a3b9acb59fd7b9cb093 *vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm
|
||||
1765315acccfe6cd12230e731369fcb15325ebfa *vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm.md5
|
||||
4a2b7a683576fe8e330c7d1c4f098ff4e70a43a8 *vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm
|
||||
1ef480392112b3509cb190afbb96f9a38dd9fbac *vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm.md5
|
||||
e615575ded499ea1d992f3b38e3baa434509cdcd *vp90-2-15-segkey.webm
|
||||
e3ab35d4316c5e81325c50f5236ceca4bc0d35df *vp90-2-15-segkey.webm.md5
|
||||
9b7ca2cac09d34c4a5d296c1900f93b1e2f69d0d *vp90-2-15-segkey_adpq.webm
|
||||
8f46ba5f785d0c2170591a153e0d0d146a7c8090 *vp90-2-15-segkey_adpq.webm.md5
|
||||
698a6910a97486b833073ef0c0b18d75dce57ee8 *vp90-2-16-intra-only.webm
|
||||
5661b0168752969f055eec37b05fa9fa947dc7eb *vp90-2-16-intra-only.webm.md5
|
||||
c01bb7938f9a9f25e0c37afdec2f2fb73b6cc7fa *vp90-2-17-show-existing-frame.webm
|
||||
cc75f351818b9a619818f5cc77b9bc013d0c1e11 *vp90-2-17-show-existing-frame.webm.md5
|
||||
013708bd043f0821a3e56fb8404d82e7a0c7af6c *vp91-2-04-yuv422.webm
|
||||
1e58a7d23adad830a672f1733c9d2ae17890d59c *vp91-2-04-yuv422.webm.md5
|
||||
25d78f28948789d159a9453ebc13048b818251b1 *vp91-2-04-yuv440.webm
|
||||
81b3870b27a7f695ef6a43e87ab04bbdb5aee2f5 *vp91-2-04-yuv440.webm.md5
|
||||
0321d507ce62dedc8a51b4e9011f7a19aed9c3dc *vp91-2-04-yuv444.webm
|
||||
367e423dd41fdb49aa028574a2cfec5c2f325c5c *vp91-2-04-yuv444.webm.md5
|
||||
f77673b566f686853adefe0c578ad251b7241281 *vp92-2-20-10bit-yuv420.webm
|
||||
abdedfaddacbbe1a15ac7a54e86360f03629fb7a *vp92-2-20-10bit-yuv420.webm.md5
|
||||
0c2c355a1b17b28537c5a3b19997c8783b69f1af *vp92-2-20-12bit-yuv420.webm
|
||||
afb2c2798703e039189b0a15c8ac5685aa51d33f *vp92-2-20-12bit-yuv420.webm.md5
|
||||
0d661bc6e83da33238981481efd1b1802d323d88 *vp93-2-20-10bit-yuv422.webm
|
||||
10318907063db22eb02fad332556edbbecd443cc *vp93-2-20-10bit-yuv422.webm.md5
|
||||
ebc6be2f7511a0bdeac0b18c67f84ba7168839c7 *vp93-2-20-12bit-yuv422.webm
|
||||
235232267c6a1dc8a11e45d600f1c99d2f8b42d4 *vp93-2-20-12bit-yuv422.webm.md5
|
||||
f76b11b26d4beaceac7a7e7729dd5054d095164f *vp93-2-20-10bit-yuv440.webm
|
||||
757b33b5ac969c5999999488a731a3d1e6d9fb88 *vp93-2-20-10bit-yuv440.webm.md5
|
||||
df8807dbd29bec795c2db9c3c18e511fbb988101 *vp93-2-20-12bit-yuv440.webm
|
||||
ea4100930c3f59a1c23fbb33ab0ea01151cae159 *vp93-2-20-12bit-yuv440.webm.md5
|
||||
189c1b5f404ff41a50a7fc96341085ad541314a9 *vp93-2-20-10bit-yuv444.webm
|
||||
2dd0177c2f9d970b6e698892634c653630f91f40 *vp93-2-20-10bit-yuv444.webm.md5
|
||||
bd44cf6e1c27343e3639df9ac21346aedd5d6973 *vp93-2-20-12bit-yuv444.webm
|
||||
f36e5bdf5ec3213f32c0ddc82f95d82c5133bf27 *vp93-2-20-12bit-yuv444.webm.md5
|
||||
eb438c6540eb429f74404eedfa3228d409c57874 *desktop_640_360_30.yuv
|
||||
89e70ebd22c27d275fe14dc2f1a41841a6d8b9ab *kirland_640_480_30.yuv
|
||||
33c533192759e5bb4f07abfbac389dc259db4686 *macmarcomoving_640_480_30.yuv
|
||||
8bfaab121080821b8f03b23467911e59ec59b8fe *macmarcostationary_640_480_30.yuv
|
||||
70894878d916a599842d9ad0dcd24e10c13e5467 *niklas_640_480_30.yuv
|
||||
8784b6df2d8cc946195a90ac00540500d2e522e4 *tacomanarrows_640_480_30.yuv
|
||||
edd86a1f5e62fd9da9a9d46078247759c2638009 *tacomasmallcameramovement_640_480_30.yuv
|
||||
9a70e8b7d14fba9234d0e51dce876635413ce444 *thaloundeskmtg_640_480_30.yuv
|
||||
e7d315dbf4f3928779e0dc624311196d44491d32 *niklas_1280_720_30.yuv
|
||||
c77e4a26616add298a05dd5d12397be22c0e40c5 *vp90-2-18-resize.ivf
|
||||
c12918cf0a716417fba2de35c3fc5ab90e52dfce *vp90-2-18-resize.ivf.md5
|
||||
717da707afcaa1f692ff1946f291054eb75a4f06 *screendata.y4m
|
||||
b7c1296630cdf1a7ef493d15ff4f9eb2999202f6 *invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf
|
||||
0a3884edb3fd8f9d9b500223e650f7de257b67d8 *invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf.res
|
||||
359e138dfb66863828397b77000ea7a83c844d02 *invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf
|
||||
bbd33de01c17b165b4ce00308e8a19a942023ab8 *invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf.res
|
||||
fac89b5735be8a86b0dc05159f996a5c3208ae32 *invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf
|
||||
0a3884edb3fd8f9d9b500223e650f7de257b67d8 *invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf.res
|
||||
4506dfdcdf8ee4250924b075a0dcf1f070f72e5a *invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf
|
||||
bcdedaf168ac225575468fda77502d2dc9fd5baa *invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf.res
|
||||
65e93f9653bcf65b022f7d225268d1a90a76e7bb *vp90-2-19-skip.webm
|
||||
368dccdde5288c13c25695d2eacdc7402cadf613 *vp90-2-19-skip.webm.md5
|
||||
ffe460282df2b0e7d4603c2158653ad96f574b02 *vp90-2-19-skip-01.webm
|
||||
bd21bc9eda4a4a36b221d71ede3a139fc3c7bd85 *vp90-2-19-skip-01.webm.md5
|
||||
178f5bd239e38cc1cc2657a7a5e1a9f52ad2d3fe *vp90-2-19-skip-02.webm
|
||||
9020d5e260bd7df08e2b3d4b86f8623cee3daea2 *vp90-2-19-skip-02.webm.md5
|
||||
b03c408cf23158638da18dbc3323b99a1635c68a *invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf
|
||||
0a3884edb3fd8f9d9b500223e650f7de257b67d8 *invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res
|
||||
5e67e24e7f53fd189e565513cef8519b1bd6c712 *invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf
|
||||
741158f67c0d9d23726624d06bdc482ad368afc9 *invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf.res
|
||||
8b1f7bf7e86c0976d277f60e8fcd9539e75a079a *invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf
|
||||
9c6bdf048fb2e66f07d4b4db5b32e6f303bd6109 *invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf.res
|
||||
552e372e9b78127389fb06b34545df2cec15ba6d *invalid-vp91-2-mixedrefcsp-444to420.ivf
|
||||
a61774cf03fc584bd9f0904fc145253bb8ea6c4c *invalid-vp91-2-mixedrefcsp-444to420.ivf.res
|
||||
812d05a64a0d83c1b504d0519927ddc5a2cdb273 *invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf
|
||||
1e472baaf5f6113459f0399a38a5a5e68d17799d *invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf.res
|
||||
f97088c7359fc8d3d5aa5eafe57bc7308b3ee124 *vp90-2-20-big_superframe-01.webm
|
||||
47d7d409785afa33b123376de0c907336e6c7bd7 *vp90-2-20-big_superframe-01.webm.md5
|
||||
65ade6d2786209582c50d34cfe22b3cdb033abaf *vp90-2-20-big_superframe-02.webm
|
||||
7c0ed8d04c4d06c5411dd2e5de2411d37f092db5 *vp90-2-20-big_superframe-02.webm.md5
|
||||
667ec8718c982aef6be07eb94f083c2efb9d2d16 *vp90-2-07-frame_parallel-1.webm
|
||||
bfc82bf848e9c05020d61e3ffc1e62f25df81d19 *vp90-2-07-frame_parallel-1.webm.md5
|
||||
efd5a51d175cfdacd169ed23477729dc558030dc *invalid-vp90-2-07-frame_parallel-1.webm
|
||||
9f912712ec418be69adb910e2ca886a63c4cec08 *invalid-vp90-2-07-frame_parallel-2.webm
|
||||
445f5a53ca9555341852997ccdd480a51540bd14 *invalid-vp90-2-07-frame_parallel-3.webm
|
||||
d18c90709a0d03c82beadf10898b27d88fff719c *invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf
|
||||
d06285d109ecbaef63b0cbcc44d70a129186f51c *invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf.res
|
||||
e60d859b0ef2b331b21740cf6cb83fabe469b079 *invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf
|
||||
0ae808dca4d3c1152a9576e14830b6faa39f1b4a *invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf.res
|
||||
9cfc855459e7549fd015c79e8eca512b2f2cb7e3 *niklas_1280_720_30.y4m
|
||||
5b5763b388b1b52a81bb82b39f7ec25c4bd3d0e1 *desktop_credits.y4m
|
||||
85771f6ab44e4a0226e206c0cde8351dd5918953 *vp90-2-02-size-130x132.webm
|
||||
512dad5eabbed37b4bbbc64ce153f1a5484427b8 *vp90-2-02-size-130x132.webm.md5
|
||||
01f7127d40360289db63b27f61cb9afcda350e95 *vp90-2-02-size-132x130.webm
|
||||
4a94275328ae076cf60f966c097a8721010fbf5a *vp90-2-02-size-132x130.webm.md5
|
||||
f41c0400b5716b4b70552c40dd03d44be131e1cc *vp90-2-02-size-132x132.webm
|
||||
1a69e989f697e424bfe3e3e8a77bb0c0992c8e47 *vp90-2-02-size-132x132.webm.md5
|
||||
94a5cbfacacba100e0c5f7861c72a1b417feca0f *vp90-2-02-size-178x180.webm
|
||||
dedfecf1d784bcf70629592fa5e6f01d5441ccc9 *vp90-2-02-size-178x180.webm.md5
|
||||
4828b62478c04014bba3095a83106911a71cf387 *vp90-2-02-size-180x178.webm
|
||||
423da2b861050c969d78ed8e8f8f14045d1d8199 *vp90-2-02-size-180x178.webm.md5
|
||||
338f7c9282f43e29940f5391118aadd17e4f9234 *vp90-2-02-size-180x180.webm
|
||||
6c2ef013392310778dca5dd5351160eca66b0a60 *vp90-2-02-size-180x180.webm.md5
|
||||
679fa7d6807e936ff937d7b282e7dbd8ac76447e *vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm
|
||||
fc7267ab8fc2bf5d6c234e34ee6c078a967b4888 *vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm.md5
|
||||
9d33a137c819792209c5ce4e4e1ee5da73d574fe *vp90-2-14-resize-10frames-fp-tiles-1-2.webm
|
||||
0c78a154956a8605d050bdd75e0dcc4d39c040a6 *vp90-2-14-resize-10frames-fp-tiles-1-2.webm.md5
|
||||
d6a8d8c57f66a91d23e8e7df480f9ae841e56c37 *vp90-2-14-resize-10frames-fp-tiles-1-4.webm
|
||||
e9b4e8c7b33b5fda745d340c3f47e6623ae40cf2 *vp90-2-14-resize-10frames-fp-tiles-1-4.webm.md5
|
||||
aa6fe043a0c4a42b49c87ebbe812d4afd9945bec *vp90-2-14-resize-10frames-fp-tiles-1-8.webm
|
||||
028520578994c2d013d4c0129033d4f2ff31bbe0 *vp90-2-14-resize-10frames-fp-tiles-1-8.webm.md5
|
||||
d1d5463c9ea7b5cc5f609ddedccddf656f348d1a *vp90-2-14-resize-10frames-fp-tiles-2-1.webm
|
||||
92d5872f5bdffbed721703b7e959b4f885e3d77a *vp90-2-14-resize-10frames-fp-tiles-2-1.webm.md5
|
||||
677cb29de1215d97346015af5807a9b1faad54cf *vp90-2-14-resize-10frames-fp-tiles-2-4.webm
|
||||
a5db19f977094ec3fd60b4f7671b3e6740225e12 *vp90-2-14-resize-10frames-fp-tiles-2-4.webm.md5
|
||||
cdd3c52ba21067efdbb2de917fe2a965bf27332e *vp90-2-14-resize-10frames-fp-tiles-2-8.webm
|
||||
db17ec5d894ea8b8d0b7f32206d0dd3d46dcfa6d *vp90-2-14-resize-10frames-fp-tiles-2-8.webm.md5
|
||||
0f6093c472125d05b764d7d1965c1d56771c0ea2 *vp90-2-14-resize-10frames-fp-tiles-4-1.webm
|
||||
bc7c79e1bee07926dd970462ce6f64fc30eec3e1 *vp90-2-14-resize-10frames-fp-tiles-4-1.webm.md5
|
||||
c5142e2bff4091338196c8ea8bc9266e64f548bc *vp90-2-14-resize-10frames-fp-tiles-4-2.webm
|
||||
22aa3dd430b69fd3d92f6561bac86deeed90486d *vp90-2-14-resize-10frames-fp-tiles-4-2.webm.md5
|
||||
ede8b1466d2f26e1b1bd9602addb9cd1017e1d8c *vp90-2-14-resize-10frames-fp-tiles-4-8.webm
|
||||
508d5ebb9c0eac2a4100281a3ee052ec2fc19217 *vp90-2-14-resize-10frames-fp-tiles-4-8.webm.md5
|
||||
2b292e3392854cd1d76ae597a6f53656cf741cfa *vp90-2-14-resize-10frames-fp-tiles-8-1.webm
|
||||
1c24e54fa19e94e1722f24676404444e941c3d31 *vp90-2-14-resize-10frames-fp-tiles-8-1.webm.md5
|
||||
61beda21064e09634564caa6697ab90bd53c9af7 *vp90-2-14-resize-10frames-fp-tiles-8-2.webm
|
||||
9c0657b4d9e1d0e4c9d28a90e5a8630a65519124 *vp90-2-14-resize-10frames-fp-tiles-8-2.webm.md5
|
||||
1758c50a11a7c92522749b4a251664705f1f0d4b *vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm
|
||||
4f454a06750614314ae15a44087b79016fe2db97 *vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm.md5
|
||||
3920c95ba94f1f048a731d9d9b416043b44aa4bd *vp90-2-14-resize-10frames-fp-tiles-8-4.webm
|
||||
4eb347a0456d2c49a1e1d8de5aa1c51acc39887e *vp90-2-14-resize-10frames-fp-tiles-8-4.webm.md5
|
||||
4b95a74c032a473b6683d7ad5754db1b0ec378e9 *vp90-2-21-resize_inter_1280x720_5_1-2.webm
|
||||
a7826dd386bedfe69d02736969bfb47fb6a40a5e *vp90-2-21-resize_inter_1280x720_5_1-2.webm.md5
|
||||
5cfff79e82c4d69964ccb8e75b4f0c53b9295167 *vp90-2-21-resize_inter_1280x720_5_3-4.webm
|
||||
a18f57db4a25e1f543a99f2ceb182e00db0ee22f *vp90-2-21-resize_inter_1280x720_5_3-4.webm.md5
|
||||
d26db0811bf30eb4131d928669713e2485f8e833 *vp90-2-21-resize_inter_1280x720_7_1-2.webm
|
||||
fd6f9f332cd5bea4c0f0d57be4297bea493cc5a1 *vp90-2-21-resize_inter_1280x720_7_1-2.webm.md5
|
||||
5c7d73d4d268e2ba9593b31cb091fd339505c7fd *vp90-2-21-resize_inter_1280x720_7_3-4.webm
|
||||
7bbb949cabc1e70dadcc74582739f63b833034e0 *vp90-2-21-resize_inter_1280x720_7_3-4.webm.md5
|
||||
f2d2a41a60eb894aff0c5854afca15931f1445a8 *vp90-2-21-resize_inter_1920x1080_5_1-2.webm
|
||||
66d7789992613ac9d678ff905ff1059daa1b89e4 *vp90-2-21-resize_inter_1920x1080_5_1-2.webm.md5
|
||||
764edb75fe7dd64e73a1b4f3b4b2b1bf237a4dea *vp90-2-21-resize_inter_1920x1080_5_3-4.webm
|
||||
f78bea1075983fd990e7f25d4f31438f9b5efa34 *vp90-2-21-resize_inter_1920x1080_5_3-4.webm.md5
|
||||
96496f2ade764a5de9f0c27917c7df1f120fb2ef *vp90-2-21-resize_inter_1920x1080_7_1-2.webm
|
||||
2632b635135ed5ecd67fd22dec7990d29c4f4cb5 *vp90-2-21-resize_inter_1920x1080_7_1-2.webm.md5
|
||||
74889ea42001bf41428cb742ca74e65129c886dc *vp90-2-21-resize_inter_1920x1080_7_3-4.webm
|
||||
d2cf3b25956415bb579d368e7098097e482dd73a *vp90-2-21-resize_inter_1920x1080_7_3-4.webm.md5
|
||||
4658986a8ce36ebfcc80a1903e446eaab3985336 *vp90-2-21-resize_inter_320x180_5_1-2.webm
|
||||
8a3d8cf325109ffa913cc9426c32eea8c202a09a *vp90-2-21-resize_inter_320x180_5_1-2.webm.md5
|
||||
16303aa45176520ee42c2c425247aadc1506b881 *vp90-2-21-resize_inter_320x180_5_3-4.webm
|
||||
41cab1ddf7715b680a4dbce42faa9bcd72af4e5c *vp90-2-21-resize_inter_320x180_5_3-4.webm.md5
|
||||
56648adcee66dd0e5cb6ac947f5ee1b9cc8ba129 *vp90-2-21-resize_inter_320x180_7_1-2.webm
|
||||
70047377787003cc03dda7b2394e6d7eaa666d9e *vp90-2-21-resize_inter_320x180_7_1-2.webm.md5
|
||||
d2ff99165488499cc55f75929f1ce5ca9c9e359b *vp90-2-21-resize_inter_320x180_7_3-4.webm
|
||||
e69019e378114a4643db283b66d1a7e304761a56 *vp90-2-21-resize_inter_320x180_7_3-4.webm.md5
|
||||
4834d129bed0f4289d3a88f2ae3a1736f77621b0 *vp90-2-21-resize_inter_320x240_5_1-2.webm
|
||||
a75653c53d22b623c1927fc0088da21dafef21f4 *vp90-2-21-resize_inter_320x240_5_1-2.webm.md5
|
||||
19818e1b7fd1c1e63d8873c31b0babe29dd33ba6 *vp90-2-21-resize_inter_320x240_5_3-4.webm
|
||||
8d89814ff469a186312111651b16601dfbce4336 *vp90-2-21-resize_inter_320x240_5_3-4.webm.md5
|
||||
ac8057bae52498f324ce92a074d5f8207cc4a4a7 *vp90-2-21-resize_inter_320x240_7_1-2.webm
|
||||
2643440898c83c08cc47bc744245af696b877c24 *vp90-2-21-resize_inter_320x240_7_1-2.webm.md5
|
||||
cf4a4cd38ac8b18c42d8c25a3daafdb39132256b *vp90-2-21-resize_inter_320x240_7_3-4.webm
|
||||
70ba8ec9120b26e9b0ffa2c79b432f16cbcb50ec *vp90-2-21-resize_inter_320x240_7_3-4.webm.md5
|
||||
669f10409fe1c4a054010162ca47773ea1fdbead *vp90-2-21-resize_inter_640x360_5_1-2.webm
|
||||
6355a04249004a35fb386dd1024214234f044383 *vp90-2-21-resize_inter_640x360_5_1-2.webm.md5
|
||||
c23763b950b8247c1775d1f8158d93716197676c *vp90-2-21-resize_inter_640x360_5_3-4.webm
|
||||
59e6fc381e3ec3b7bdaac586334e0bc944d18fb6 *vp90-2-21-resize_inter_640x360_5_3-4.webm.md5
|
||||
71b45cbfdd068baa1f679a69e5e6f421d256a85f *vp90-2-21-resize_inter_640x360_7_1-2.webm
|
||||
1416fc761b690c54a955c4cf017fa078520e8c18 *vp90-2-21-resize_inter_640x360_7_1-2.webm.md5
|
||||
6c409903279448a697e4db63bab1061784bcd8d2 *vp90-2-21-resize_inter_640x360_7_3-4.webm
|
||||
60de1299793433a630b71130cf76c9f5965758e2 *vp90-2-21-resize_inter_640x360_7_3-4.webm.md5
|
||||
852b597b8af096d90c80bf0ed6ed3b336b851f19 *vp90-2-21-resize_inter_640x480_5_1-2.webm
|
||||
f6856f19236ee46ed462bd0a2e7e72b9c3b9cea6 *vp90-2-21-resize_inter_640x480_5_1-2.webm.md5
|
||||
792a16c6f60043bd8dceb515f0b95b8891647858 *vp90-2-21-resize_inter_640x480_5_3-4.webm
|
||||
68ffe59877e9a7863805e1c0a3ce18ce037d7c9d *vp90-2-21-resize_inter_640x480_5_3-4.webm.md5
|
||||
61e044c4759972a35ea3db8c1478a988910a4ef4 *vp90-2-21-resize_inter_640x480_7_1-2.webm
|
||||
7739bfca167b1b43fea72f807f01e097b7cb98d8 *vp90-2-21-resize_inter_640x480_7_1-2.webm.md5
|
||||
7291af354b4418917eee00e3a7e366086a0b7a10 *vp90-2-21-resize_inter_640x480_7_3-4.webm
|
||||
4a18b09ccb36564193f0215f599d745d95bb558c *vp90-2-21-resize_inter_640x480_7_3-4.webm.md5
|
||||
a000d568431d07379dd5a8ec066061c07e560b47 *invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf
|
||||
1e75aad3433c5c21c194a7b53fc393970f0a8d7f *invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res
|
||||
235182f9a1c5c8841552510dd4288487447bfc40 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
|
||||
787f04f0483320d536894282f3358a4f8cac1cf9 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
|
||||
91d3cefd0deb98f3b0caf3a2d900ec7a7605e53a *invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf
|
||||
1e472baaf5f6113459f0399a38a5a5e68d17799d *invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf.res
|
||||
70057835bf29d14e66699ce5f022df2551fb6b37 *invalid-crbug-629481.webm
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-crbug-629481.webm.res
|
||||
7602e00378161ca36ae93cc6ee12dd30b5ba1e1d *vp90-2-22-svc_1280x720_3.ivf
|
||||
02e53e3eefbf25ec0929047fe50876acdeb040bd *vp90-2-22-svc_1280x720_3.ivf.md5
|
||||
6fa3d3ac306a3d9ce1d610b78441dc00d2c2d4b9 *tos_vp8.webm
|
||||
e402cbbf9e550ae017a1e9f1f73931c1d18474e8 *invalid-crbug-667044.webm
|
||||
d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-crbug-667044.webm.res
|
||||
fd9df7f3f6992af1d7a9dde975c9a0d6f28c053d *invalid-bug-1443.ivf
|
||||
fd3020fa6e9ca5966206738654c97dec313b0a95 *invalid-bug-1443.ivf.res
|
||||
1a0e405606939f2febab1a21b30c37cb8f2c8cb1 *invalid-token-partition.ivf
|
||||
90a8a95e7024f015b87f5483a65036609b3d1b74 *invalid-token-partition.ivf.res
|
||||
17696cd21e875f1d6e5d418cbf89feab02c8850a *vp90-2-22-svc_1280x720_1.webm
|
||||
e2f9e1e47a791b4e939a9bdc50bf7a25b3761f77 *vp90-2-22-svc_1280x720_1.webm.md5
|
||||
a0fbbbc5dd50fd452096f4455a58c1a8c9f66697 *invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf
|
||||
a61774cf03fc584bd9f0904fc145253bb8ea6c4c *invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf.res
|
||||
894fae3afee0290546590823974203ab4b8abd95 *crbug-1539.rawfile
|
||||
f1026c03efd5da21b381c8eb21f0d64e6d7e4ba3 *invalid-crbug-1558.ivf
|
||||
eb198c25f861c3fe2cbd310de11eb96843019345 *invalid-crbug-1558.ivf.res
|
||||
c62b005a9fd32c36a1b3f67de6840330f9915e34 *invalid-crbug-1562.ivf
|
||||
f0cd8389948ad16085714d96567612136f6a46c5 *invalid-crbug-1562.ivf.res
|
||||
bac455906360b45338a16dd626ac5f19bc36a307 *desktop_office1.1280_720-020.yuv
|
||||
094be4b80fa30bd227149ea16ab6476d549ea092 *slides_code_term_web_plot.1920_1080.yuv
|
||||
@@ -0,0 +1,208 @@
|
||||
LIBVPX_TEST_SRCS-yes += acm_random.h
|
||||
LIBVPX_TEST_SRCS-yes += bench.h
|
||||
LIBVPX_TEST_SRCS-yes += bench.cc
|
||||
LIBVPX_TEST_SRCS-yes += buffer.h
|
||||
LIBVPX_TEST_SRCS-yes += clear_system_state.h
|
||||
LIBVPX_TEST_SRCS-yes += codec_factory.h
|
||||
LIBVPX_TEST_SRCS-yes += md5_helper.h
|
||||
LIBVPX_TEST_SRCS-yes += register_state_check.h
|
||||
LIBVPX_TEST_SRCS-yes += test.mk
|
||||
LIBVPX_TEST_SRCS-yes += test_libvpx.cc
|
||||
LIBVPX_TEST_SRCS-yes += test_vectors.cc
|
||||
LIBVPX_TEST_SRCS-yes += test_vectors.h
|
||||
LIBVPX_TEST_SRCS-yes += util.h
|
||||
LIBVPX_TEST_SRCS-yes += video_source.h
|
||||
|
||||
##
|
||||
## BLACK BOX TESTS
|
||||
##
|
||||
## Black box tests only use the public API.
|
||||
##
|
||||
LIBVPX_TEST_SRCS-yes += ../md5_utils.h ../md5_utils.c
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ivf_video_source.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../y4minput.h ../y4minput.c
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += altref_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += aq_segment_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += alt_ref_aq_segment_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += vp8_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += vp9_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_api_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += i420_video_source.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += realtime_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += resize_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_video_source.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += yuv_video_source.h
|
||||
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += config_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc
|
||||
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += byte_alignment_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += decode_svc_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_refresh_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += cpu_speed_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += frame_size_tests.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_lossless_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_end_to_end_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += decode_corrupted.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ethread_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_motion_vector_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += level_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_end_to_end_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += timestamp_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_RATE_CTRL) += simple_encode_test.cc
|
||||
|
||||
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc
|
||||
LIBVPX_TEST_SRCS-yes += decode_test_driver.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_test_driver.cc
|
||||
LIBVPX_TEST_SRCS-yes += encode_test_driver.h
|
||||
|
||||
## IVF writing.
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../ivfenc.c ../ivfenc.h
|
||||
|
||||
## Y4m parsing.
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_test.cc ../y4menc.c ../y4menc.h
|
||||
|
||||
## WebM Parsing
|
||||
ifeq ($(CONFIG_WEBM_IO), yes)
|
||||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.cc
|
||||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.cc
|
||||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.h
|
||||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.h
|
||||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/common/webmids.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += $(LIBWEBM_PARSER_SRCS)
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../tools_common.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += webm_video_source.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_skip_loopfilter_test.cc
|
||||
endif
|
||||
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += decode_api_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += test_vector_test.cc
|
||||
|
||||
# Currently we only support decoder perf tests for vp9. Also they read from WebM
|
||||
# files, so WebM IO is required.
|
||||
ifeq ($(CONFIG_DECODE_PERF_TESTS)$(CONFIG_VP9_DECODER)$(CONFIG_WEBM_IO), \
|
||||
yesyesyes)
|
||||
LIBVPX_TEST_SRCS-yes += decode_perf_test.cc
|
||||
endif
|
||||
|
||||
# encode perf tests are vp9 only
|
||||
ifeq ($(CONFIG_ENCODE_PERF_TESTS)$(CONFIG_VP9_ENCODER), yesyes)
|
||||
LIBVPX_TEST_SRCS-yes += encode_perf_test.cc
|
||||
endif
|
||||
|
||||
## Multi-codec blackbox tests.
|
||||
ifeq ($(findstring yes,$(CONFIG_VP8_DECODER)$(CONFIG_VP9_DECODER)), yes)
|
||||
LIBVPX_TEST_SRCS-yes += invalid_file_test.cc
|
||||
endif
|
||||
|
||||
##
|
||||
## WHITE BOX TESTS
|
||||
##
|
||||
## Whitebox tests invoke functions not exposed via the public API. Certain
|
||||
## shared library builds don't make these functions accessible.
|
||||
##
|
||||
ifeq ($(CONFIG_SHARED),)
|
||||
|
||||
## VP8
|
||||
ifeq ($(CONFIG_VP8),yes)
|
||||
|
||||
# These tests require both the encoder and decoder to be built.
|
||||
ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),yesyes)
|
||||
LIBVPX_TEST_SRCS-yes += vp8_boolcoder_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vp8_fragments_test.cc
|
||||
endif
|
||||
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += add_noise_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += pp_filter_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_DECODER) += vp8_decrypt_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += quantize_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += set_roi.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += variance_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_fdct4x4_test.cc
|
||||
|
||||
LIBVPX_TEST_SRCS-yes += idct_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += predict_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vpx_scale_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vpx_scale_test.h
|
||||
|
||||
ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_TEMPORAL_DENOISING),yesyes)
|
||||
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp8_denoiser_sse2_test.cc
|
||||
endif
|
||||
|
||||
endif # VP8
|
||||
|
||||
## VP9
|
||||
ifeq ($(CONFIG_VP9),yes)
|
||||
|
||||
# These tests require both the encoder and decoder to be built.
|
||||
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_DECODER),yesyes)
|
||||
# IDCT test currently depends on FDCT function
|
||||
LIBVPX_TEST_SRCS-yes += idct8x8_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += partial_idct_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += superframe_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += tile_independence_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vp9_boolcoder_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vp9_encoder_parms_get_to_decoder.cc
|
||||
endif
|
||||
|
||||
LIBVPX_TEST_SRCS-yes += convolve_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += lpf_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vp9_intrapred_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_decrypt_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_thread_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += avg_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += comp_avg_pred_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct_partial_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct8x8_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += hadamard_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += minmax_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_scale_test.cc
|
||||
ifneq ($(CONFIG_REALTIME_ONLY),yes)
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += yuv_temporal_filter_test.cc
|
||||
endif
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc
|
||||
|
||||
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += blockiness_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += consistency_test.cc
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_NON_GREEDY_MV) += non_greedy_mv_test.cc
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes)
|
||||
LIBVPX_TEST_SRCS-yes += vp9_denoiser_test.cc
|
||||
endif
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc
|
||||
|
||||
endif # VP9
|
||||
|
||||
## Multi-codec / unconditional whitebox tests.
|
||||
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sad_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sum_squares_test.cc
|
||||
|
||||
TEST_INTRA_PRED_SPEED_SRCS-yes := test_intra_pred_speed.cc
|
||||
TEST_INTRA_PRED_SPEED_SRCS-yes += ../md5_utils.h ../md5_utils.c
|
||||
|
||||
endif # CONFIG_SHARED
|
||||
|
||||
include $(SRC_PATH_BARE)/test/test-data.mk
|
||||
@@ -0,0 +1,589 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
// Test and time VPX intra-predictor functions
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/md5_helper.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
|
||||
typedef void (*VpxPredFunc)(uint8_t *dst, ptrdiff_t y_stride,
|
||||
const uint8_t *above, const uint8_t *left);
|
||||
|
||||
const int kBPS = 32;
|
||||
const int kTotalPixels = 32 * kBPS;
|
||||
const int kNumVp9IntraPredFuncs = 13;
|
||||
const char *kVp9IntraPredNames[kNumVp9IntraPredFuncs] = {
|
||||
"DC_PRED", "DC_LEFT_PRED", "DC_TOP_PRED", "DC_128_PRED", "V_PRED",
|
||||
"H_PRED", "D45_PRED", "D135_PRED", "D117_PRED", "D153_PRED",
|
||||
"D207_PRED", "D63_PRED", "TM_PRED"
|
||||
};
|
||||
|
||||
template <typename Pixel>
|
||||
struct IntraPredTestMem {
|
||||
void Init(int block_size, int bd) {
|
||||
libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
|
||||
Pixel *const above = above_mem + 16;
|
||||
const int mask = (1 << bd) - 1;
|
||||
for (int i = 0; i < kTotalPixels; ++i) ref_src[i] = rnd.Rand16() & mask;
|
||||
for (int i = 0; i < kBPS; ++i) left[i] = rnd.Rand16() & mask;
|
||||
for (int i = -1; i < kBPS; ++i) above[i] = rnd.Rand16() & mask;
|
||||
|
||||
// some code assumes the top row has been extended:
|
||||
// d45/d63 C-code, for instance, but not the assembly.
|
||||
// TODO(jzern): this style of extension isn't strictly necessary.
|
||||
ASSERT_LE(block_size, kBPS);
|
||||
for (int i = block_size; i < 2 * kBPS; ++i) {
|
||||
above[i] = above[block_size - 1];
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_ALIGNED(16, Pixel, src[kTotalPixels]);
|
||||
DECLARE_ALIGNED(16, Pixel, ref_src[kTotalPixels]);
|
||||
DECLARE_ALIGNED(16, Pixel, left[kBPS]);
|
||||
DECLARE_ALIGNED(16, Pixel, above_mem[2 * kBPS + 16]);
|
||||
};
|
||||
|
||||
typedef IntraPredTestMem<uint8_t> Vp9IntraPredTestMem;
|
||||
|
||||
void CheckMd5Signature(const char name[], const char *const signatures[],
|
||||
const void *data, size_t data_size, int elapsed_time,
|
||||
int idx) {
|
||||
libvpx_test::MD5 md5;
|
||||
md5.Add(reinterpret_cast<const uint8_t *>(data), data_size);
|
||||
printf("Mode %s[%12s]: %5d ms MD5: %s\n", name, kVp9IntraPredNames[idx],
|
||||
elapsed_time, md5.Get());
|
||||
EXPECT_STREQ(signatures[idx], md5.Get());
|
||||
}
|
||||
|
||||
void TestIntraPred(const char name[], VpxPredFunc const *pred_funcs,
|
||||
const char *const signatures[], int block_size) {
|
||||
const int kNumTests = static_cast<int>(
|
||||
2.e10 / (block_size * block_size * kNumVp9IntraPredFuncs));
|
||||
Vp9IntraPredTestMem intra_pred_test_mem;
|
||||
const uint8_t *const above = intra_pred_test_mem.above_mem + 16;
|
||||
|
||||
intra_pred_test_mem.Init(block_size, 8);
|
||||
|
||||
for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) {
|
||||
if (pred_funcs[k] == NULL) continue;
|
||||
memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src,
|
||||
sizeof(intra_pred_test_mem.src));
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int num_tests = 0; num_tests < kNumTests; ++num_tests) {
|
||||
pred_funcs[k](intra_pred_test_mem.src, kBPS, above,
|
||||
intra_pred_test_mem.left);
|
||||
}
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||
CheckMd5Signature(name, signatures, intra_pred_test_mem.src,
|
||||
sizeof(intra_pred_test_mem.src), elapsed_time, k);
|
||||
}
|
||||
}
|
||||
|
||||
void TestIntraPred4(VpxPredFunc const *pred_funcs) {
|
||||
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||
"e7ed7353c3383fff942e500e9bfe82fe", "2a4a26fcc6ce005eadc08354d196c8a9",
|
||||
"269d92eff86f315d9c38fe7640d85b15", "ae2960eea9f71ee3dabe08b282ec1773",
|
||||
"6c1abcc44e90148998b51acd11144e9c", "f7bb3186e1ef8a2b326037ff898cad8e",
|
||||
"364c1f3fb2f445f935aec2a70a67eaa4", "141624072a4a56773f68fadbdd07c4a7",
|
||||
"7be49b08687a5f24df3a2c612fca3876", "459bb5d9fd5b238348179c9a22108cd6",
|
||||
"73edb8831bf1bdfce21ae8eaa43b1234", "2e2457f2009c701a355a8b25eb74fcda",
|
||||
"52ae4e8bdbe41494c1f43051d4dd7f0b"
|
||||
};
|
||||
TestIntraPred("Intra4", pred_funcs, kSignatures, 4);
|
||||
}
|
||||
|
||||
void TestIntraPred8(VpxPredFunc const *pred_funcs) {
|
||||
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||
"d8bbae5d6547cfc17e4f5f44c8730e88", "373bab6d931868d41a601d9d88ce9ac3",
|
||||
"6fdd5ff4ff79656c14747598ca9e3706", "d9661c2811d6a73674f40ffb2b841847",
|
||||
"7c722d10b19ccff0b8c171868e747385", "f81dd986eb2b50f750d3a7da716b7e27",
|
||||
"d500f2c8fc78f46a4c74e4dcf51f14fb", "0e3523f9cab2142dd37fd07ec0760bce",
|
||||
"79ac4efe907f0a0f1885d43066cfedee", "19ecf2432ac305057de3b6578474eec6",
|
||||
"4f985b61acc6dd5d2d2585fa89ea2e2d", "f1bb25a9060dd262f405f15a38f5f674",
|
||||
"209ea00801584829e9a0f7be7d4a74ba"
|
||||
};
|
||||
TestIntraPred("Intra8", pred_funcs, kSignatures, 8);
|
||||
}
|
||||
|
||||
void TestIntraPred16(VpxPredFunc const *pred_funcs) {
|
||||
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||
"50971c07ce26977d30298538fffec619", "527a6b9e0dc5b21b98cf276305432bef",
|
||||
"7eff2868f80ebc2c43a4f367281d80f7", "67cd60512b54964ef6aff1bd4816d922",
|
||||
"48371c87dc95c08a33b2048f89cf6468", "b0acf2872ee411d7530af6d2625a7084",
|
||||
"f32aafed4d8d3776ed58bcb6188756d5", "dae208f3dca583529cff49b73f7c4183",
|
||||
"7af66a2f4c8e0b4908e40f047e60c47c", "125e3ab6ab9bc961f183ec366a7afa88",
|
||||
"6b90f25b23983c35386b9fd704427622", "f8d6b11d710edc136a7c62c917435f93",
|
||||
"ed308f18614a362917f411c218aee532"
|
||||
};
|
||||
TestIntraPred("Intra16", pred_funcs, kSignatures, 16);
|
||||
}
|
||||
|
||||
void TestIntraPred32(VpxPredFunc const *pred_funcs) {
|
||||
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||
"a0a618c900e65ae521ccc8af789729f2", "985aaa7c72b4a6c2fb431d32100cf13a",
|
||||
"10662d09febc3ca13ee4e700120daeb5", "b3b01379ba08916ef6b1b35f7d9ad51c",
|
||||
"9f4261755795af97e34679c333ec7004", "bc2c9da91ad97ef0d1610fb0a9041657",
|
||||
"75c79b1362ad18abfcdb1aa0aacfc21d", "4039bb7da0f6860090d3c57b5c85468f",
|
||||
"b29fff7b61804e68383e3a609b33da58", "e1aa5e49067fd8dba66c2eb8d07b7a89",
|
||||
"4e042822909c1c06d3b10a88281df1eb", "72eb9d9e0e67c93f4c66b70348e9fef7",
|
||||
"a22d102bcb51ca798aac12ca4ae8f2e8"
|
||||
};
|
||||
TestIntraPred("Intra32", pred_funcs, kSignatures, 32);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Defines a test case for |arch| (e.g., C, SSE2, ...) passing the predictors
|
||||
// to |test_func|. The test name is 'arch.test_func', e.g., C.TestIntraPred4.
|
||||
#define INTRA_PRED_TEST(arch, test_func, dc, dc_left, dc_top, dc_128, v, h, \
|
||||
d45, d135, d117, d153, d207, d63, tm) \
|
||||
TEST(arch, test_func) { \
|
||||
static const VpxPredFunc vpx_intra_pred[] = { \
|
||||
dc, dc_left, dc_top, dc_128, v, h, d45, d135, d117, d153, d207, d63, tm \
|
||||
}; \
|
||||
test_func(vpx_intra_pred); \
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
INTRA_PRED_TEST(C, TestIntraPred4, vpx_dc_predictor_4x4_c,
|
||||
vpx_dc_left_predictor_4x4_c, vpx_dc_top_predictor_4x4_c,
|
||||
vpx_dc_128_predictor_4x4_c, vpx_v_predictor_4x4_c,
|
||||
vpx_h_predictor_4x4_c, vpx_d45_predictor_4x4_c,
|
||||
vpx_d135_predictor_4x4_c, vpx_d117_predictor_4x4_c,
|
||||
vpx_d153_predictor_4x4_c, vpx_d207_predictor_4x4_c,
|
||||
vpx_d63_predictor_4x4_c, vpx_tm_predictor_4x4_c)
|
||||
|
||||
INTRA_PRED_TEST(C, TestIntraPred8, vpx_dc_predictor_8x8_c,
|
||||
vpx_dc_left_predictor_8x8_c, vpx_dc_top_predictor_8x8_c,
|
||||
vpx_dc_128_predictor_8x8_c, vpx_v_predictor_8x8_c,
|
||||
vpx_h_predictor_8x8_c, vpx_d45_predictor_8x8_c,
|
||||
vpx_d135_predictor_8x8_c, vpx_d117_predictor_8x8_c,
|
||||
vpx_d153_predictor_8x8_c, vpx_d207_predictor_8x8_c,
|
||||
vpx_d63_predictor_8x8_c, vpx_tm_predictor_8x8_c)
|
||||
|
||||
INTRA_PRED_TEST(C, TestIntraPred16, vpx_dc_predictor_16x16_c,
|
||||
vpx_dc_left_predictor_16x16_c, vpx_dc_top_predictor_16x16_c,
|
||||
vpx_dc_128_predictor_16x16_c, vpx_v_predictor_16x16_c,
|
||||
vpx_h_predictor_16x16_c, vpx_d45_predictor_16x16_c,
|
||||
vpx_d135_predictor_16x16_c, vpx_d117_predictor_16x16_c,
|
||||
vpx_d153_predictor_16x16_c, vpx_d207_predictor_16x16_c,
|
||||
vpx_d63_predictor_16x16_c, vpx_tm_predictor_16x16_c)
|
||||
|
||||
INTRA_PRED_TEST(C, TestIntraPred32, vpx_dc_predictor_32x32_c,
|
||||
vpx_dc_left_predictor_32x32_c, vpx_dc_top_predictor_32x32_c,
|
||||
vpx_dc_128_predictor_32x32_c, vpx_v_predictor_32x32_c,
|
||||
vpx_h_predictor_32x32_c, vpx_d45_predictor_32x32_c,
|
||||
vpx_d135_predictor_32x32_c, vpx_d117_predictor_32x32_c,
|
||||
vpx_d153_predictor_32x32_c, vpx_d207_predictor_32x32_c,
|
||||
vpx_d63_predictor_32x32_c, vpx_tm_predictor_32x32_c)
|
||||
|
||||
#if HAVE_SSE2
|
||||
INTRA_PRED_TEST(SSE2, TestIntraPred4, vpx_dc_predictor_4x4_sse2,
|
||||
vpx_dc_left_predictor_4x4_sse2, vpx_dc_top_predictor_4x4_sse2,
|
||||
vpx_dc_128_predictor_4x4_sse2, vpx_v_predictor_4x4_sse2,
|
||||
vpx_h_predictor_4x4_sse2, vpx_d45_predictor_4x4_sse2, NULL,
|
||||
NULL, NULL, vpx_d207_predictor_4x4_sse2, NULL,
|
||||
vpx_tm_predictor_4x4_sse2)
|
||||
|
||||
INTRA_PRED_TEST(SSE2, TestIntraPred8, vpx_dc_predictor_8x8_sse2,
|
||||
vpx_dc_left_predictor_8x8_sse2, vpx_dc_top_predictor_8x8_sse2,
|
||||
vpx_dc_128_predictor_8x8_sse2, vpx_v_predictor_8x8_sse2,
|
||||
vpx_h_predictor_8x8_sse2, vpx_d45_predictor_8x8_sse2, NULL,
|
||||
NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_sse2)
|
||||
|
||||
INTRA_PRED_TEST(SSE2, TestIntraPred16, vpx_dc_predictor_16x16_sse2,
|
||||
vpx_dc_left_predictor_16x16_sse2,
|
||||
vpx_dc_top_predictor_16x16_sse2,
|
||||
vpx_dc_128_predictor_16x16_sse2, vpx_v_predictor_16x16_sse2,
|
||||
vpx_h_predictor_16x16_sse2, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_16x16_sse2)
|
||||
|
||||
INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2,
|
||||
vpx_dc_left_predictor_32x32_sse2,
|
||||
vpx_dc_top_predictor_32x32_sse2,
|
||||
vpx_dc_128_predictor_32x32_sse2, vpx_v_predictor_32x32_sse2,
|
||||
vpx_h_predictor_32x32_sse2, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_32x32_sse2)
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3
|
||||
INTRA_PRED_TEST(SSSE3, TestIntraPred4, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_d153_predictor_4x4_ssse3, NULL,
|
||||
vpx_d63_predictor_4x4_ssse3, NULL)
|
||||
INTRA_PRED_TEST(SSSE3, TestIntraPred8, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_d153_predictor_8x8_ssse3,
|
||||
vpx_d207_predictor_8x8_ssse3, vpx_d63_predictor_8x8_ssse3, NULL)
|
||||
INTRA_PRED_TEST(SSSE3, TestIntraPred16, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_d45_predictor_16x16_ssse3, NULL, NULL,
|
||||
vpx_d153_predictor_16x16_ssse3, vpx_d207_predictor_16x16_ssse3,
|
||||
vpx_d63_predictor_16x16_ssse3, NULL)
|
||||
INTRA_PRED_TEST(SSSE3, TestIntraPred32, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_d45_predictor_32x32_ssse3, NULL, NULL,
|
||||
vpx_d153_predictor_32x32_ssse3, vpx_d207_predictor_32x32_ssse3,
|
||||
vpx_d63_predictor_32x32_ssse3, NULL)
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_DSPR2
|
||||
INTRA_PRED_TEST(DSPR2, TestIntraPred4, vpx_dc_predictor_4x4_dspr2, NULL, NULL,
|
||||
NULL, NULL, vpx_h_predictor_4x4_dspr2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_tm_predictor_4x4_dspr2)
|
||||
INTRA_PRED_TEST(DSPR2, TestIntraPred8, vpx_dc_predictor_8x8_dspr2, NULL, NULL,
|
||||
NULL, NULL, vpx_h_predictor_8x8_dspr2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_tm_predictor_8x8_c)
|
||||
INTRA_PRED_TEST(DSPR2, TestIntraPred16, vpx_dc_predictor_16x16_dspr2, NULL,
|
||||
NULL, NULL, NULL, vpx_h_predictor_16x16_dspr2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL)
|
||||
#endif // HAVE_DSPR2
|
||||
|
||||
#if HAVE_NEON
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred4, vpx_dc_predictor_4x4_neon,
|
||||
vpx_dc_left_predictor_4x4_neon, vpx_dc_top_predictor_4x4_neon,
|
||||
vpx_dc_128_predictor_4x4_neon, vpx_v_predictor_4x4_neon,
|
||||
vpx_h_predictor_4x4_neon, vpx_d45_predictor_4x4_neon,
|
||||
vpx_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_4x4_neon)
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred8, vpx_dc_predictor_8x8_neon,
|
||||
vpx_dc_left_predictor_8x8_neon, vpx_dc_top_predictor_8x8_neon,
|
||||
vpx_dc_128_predictor_8x8_neon, vpx_v_predictor_8x8_neon,
|
||||
vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon,
|
||||
vpx_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_8x8_neon)
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred16, vpx_dc_predictor_16x16_neon,
|
||||
vpx_dc_left_predictor_16x16_neon,
|
||||
vpx_dc_top_predictor_16x16_neon,
|
||||
vpx_dc_128_predictor_16x16_neon, vpx_v_predictor_16x16_neon,
|
||||
vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon,
|
||||
vpx_d135_predictor_16x16_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_16x16_neon)
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon,
|
||||
vpx_dc_left_predictor_32x32_neon,
|
||||
vpx_dc_top_predictor_32x32_neon,
|
||||
vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon,
|
||||
vpx_h_predictor_32x32_neon, vpx_d45_predictor_32x32_neon,
|
||||
vpx_d135_predictor_32x32_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_32x32_neon)
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
INTRA_PRED_TEST(MSA, TestIntraPred4, vpx_dc_predictor_4x4_msa,
|
||||
vpx_dc_left_predictor_4x4_msa, vpx_dc_top_predictor_4x4_msa,
|
||||
vpx_dc_128_predictor_4x4_msa, vpx_v_predictor_4x4_msa,
|
||||
vpx_h_predictor_4x4_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_4x4_msa)
|
||||
INTRA_PRED_TEST(MSA, TestIntraPred8, vpx_dc_predictor_8x8_msa,
|
||||
vpx_dc_left_predictor_8x8_msa, vpx_dc_top_predictor_8x8_msa,
|
||||
vpx_dc_128_predictor_8x8_msa, vpx_v_predictor_8x8_msa,
|
||||
vpx_h_predictor_8x8_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_8x8_msa)
|
||||
INTRA_PRED_TEST(MSA, TestIntraPred16, vpx_dc_predictor_16x16_msa,
|
||||
vpx_dc_left_predictor_16x16_msa, vpx_dc_top_predictor_16x16_msa,
|
||||
vpx_dc_128_predictor_16x16_msa, vpx_v_predictor_16x16_msa,
|
||||
vpx_h_predictor_16x16_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_16x16_msa)
|
||||
INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa,
|
||||
vpx_dc_left_predictor_32x32_msa, vpx_dc_top_predictor_32x32_msa,
|
||||
vpx_dc_128_predictor_32x32_msa, vpx_v_predictor_32x32_msa,
|
||||
vpx_h_predictor_32x32_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_32x32_msa)
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
// TODO(crbug.com/webm/1522): Fix test failures.
|
||||
#if 0
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred4, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_h_predictor_4x4_vsx, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_4x4_vsx)
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred8, vpx_dc_predictor_8x8_vsx, NULL, NULL, NULL,
|
||||
NULL, vpx_h_predictor_8x8_vsx, vpx_d45_predictor_8x8_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_8x8_vsx,
|
||||
vpx_tm_predictor_8x8_vsx)
|
||||
#endif
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred16, vpx_dc_predictor_16x16_vsx,
|
||||
vpx_dc_left_predictor_16x16_vsx, vpx_dc_top_predictor_16x16_vsx,
|
||||
vpx_dc_128_predictor_16x16_vsx, vpx_v_predictor_16x16_vsx,
|
||||
vpx_h_predictor_16x16_vsx, vpx_d45_predictor_16x16_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_16x16_vsx,
|
||||
vpx_tm_predictor_16x16_vsx)
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred32, vpx_dc_predictor_32x32_vsx,
|
||||
vpx_dc_left_predictor_32x32_vsx, vpx_dc_top_predictor_32x32_vsx,
|
||||
vpx_dc_128_predictor_32x32_vsx, vpx_v_predictor_32x32_vsx,
|
||||
vpx_h_predictor_32x32_vsx, vpx_d45_predictor_32x32_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_32x32_vsx,
|
||||
vpx_tm_predictor_32x32_vsx)
|
||||
#endif // HAVE_VSX
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
namespace {
|
||||
|
||||
typedef void (*VpxHighbdPredFunc)(uint16_t *dst, ptrdiff_t y_stride,
|
||||
const uint16_t *above, const uint16_t *left,
|
||||
int bd);
|
||||
|
||||
typedef IntraPredTestMem<uint16_t> Vp9HighbdIntraPredTestMem;
|
||||
|
||||
void TestHighbdIntraPred(const char name[], VpxHighbdPredFunc const *pred_funcs,
|
||||
const char *const signatures[], int block_size) {
|
||||
const int kNumTests = static_cast<int>(
|
||||
2.e10 / (block_size * block_size * kNumVp9IntraPredFuncs));
|
||||
Vp9HighbdIntraPredTestMem intra_pred_test_mem;
|
||||
const uint16_t *const above = intra_pred_test_mem.above_mem + 16;
|
||||
|
||||
intra_pred_test_mem.Init(block_size, 12);
|
||||
|
||||
for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) {
|
||||
if (pred_funcs[k] == NULL) continue;
|
||||
memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src,
|
||||
sizeof(intra_pred_test_mem.src));
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int num_tests = 0; num_tests < kNumTests; ++num_tests) {
|
||||
pred_funcs[k](intra_pred_test_mem.src, kBPS, above,
|
||||
intra_pred_test_mem.left, 12);
|
||||
}
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||
CheckMd5Signature(name, signatures, intra_pred_test_mem.src,
|
||||
sizeof(intra_pred_test_mem.src), elapsed_time, k);
|
||||
}
|
||||
}
|
||||
|
||||
void TestHighbdIntraPred4(VpxHighbdPredFunc const *pred_funcs) {
|
||||
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||
"11f74af6c5737df472f3275cbde062fa", "51bea056b6447c93f6eb8f6b7e8f6f71",
|
||||
"27e97f946766331795886f4de04c5594", "53ab15974b049111fb596c5168ec7e3f",
|
||||
"f0b640bb176fbe4584cf3d32a9b0320a", "729783ca909e03afd4b47111c80d967b",
|
||||
"fbf1c30793d9f32812e4d9f905d53530", "293fc903254a33754133314c6cdba81f",
|
||||
"f8074d704233e73dfd35b458c6092374", "aa6363d08544a1ec4da33d7a0be5640d",
|
||||
"462abcfdfa3d087bb33c9a88f2aec491", "863eab65d22550dd44a2397277c1ec71",
|
||||
"23d61df1574d0fa308f9731811047c4b"
|
||||
};
|
||||
TestHighbdIntraPred("Intra4", pred_funcs, kSignatures, 4);
|
||||
}
|
||||
|
||||
void TestHighbdIntraPred8(VpxHighbdPredFunc const *pred_funcs) {
|
||||
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||
"03da8829fe94663047fd108c5fcaa71d", "ecdb37b8120a2d3a4c706b016bd1bfd7",
|
||||
"1d4543ed8d2b9368cb96898095fe8a75", "f791c9a67b913cbd82d9da8ecede30e2",
|
||||
"065c70646f4dbaff913282f55a45a441", "51f87123616662ef7c35691497dfd0ba",
|
||||
"2a5b0131ef4716f098ee65e6df01e3dd", "9ffe186a6bc7db95275f1bbddd6f7aba",
|
||||
"a3258a2eae2e2bd55cb8f71351b22998", "8d909f0a2066e39b3216092c6289ece4",
|
||||
"d183abb30b9f24c886a0517e991b22c7", "702a42fe4c7d665dc561b2aeeb60f311",
|
||||
"7b5dbbbe7ae3a4ac2948731600bde5d6"
|
||||
};
|
||||
TestHighbdIntraPred("Intra8", pred_funcs, kSignatures, 8);
|
||||
}
|
||||
|
||||
void TestHighbdIntraPred16(VpxHighbdPredFunc const *pred_funcs) {
|
||||
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||
"e33cb3f56a878e2fddb1b2fc51cdd275", "c7bff6f04b6052c8ab335d726dbbd52d",
|
||||
"d0b0b47b654a9bcc5c6008110a44589b", "78f5da7b10b2b9ab39f114a33b6254e9",
|
||||
"c78e31d23831abb40d6271a318fdd6f3", "90d1347f4ec9198a0320daecb6ff90b8",
|
||||
"d2c623746cbb64a0c9e29c10f2c57041", "cf28bd387b81ad3e5f1a1c779a4b70a0",
|
||||
"24c304330431ddeaf630f6ce94af2eac", "91a329798036bf64e8e00a87b131b8b1",
|
||||
"d39111f22885307f920796a42084c872", "e2e702f7250ece98dd8f3f2854c31eeb",
|
||||
"e2fb05b01eb8b88549e85641d8ce5b59"
|
||||
};
|
||||
TestHighbdIntraPred("Intra16", pred_funcs, kSignatures, 16);
|
||||
}
|
||||
|
||||
void TestHighbdIntraPred32(VpxHighbdPredFunc const *pred_funcs) {
|
||||
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||
"a3e8056ba7e36628cce4917cd956fedd", "cc7d3024fe8748b512407edee045377e",
|
||||
"2aab0a0f330a1d3e19b8ecb8f06387a3", "a547bc3fb7b06910bf3973122a426661",
|
||||
"26f712514da95042f93d6e8dc8e431dc", "bb08c6e16177081daa3d936538dbc2e3",
|
||||
"8f031af3e2650e89620d8d2c3a843d8b", "42867c8553285e94ee8e4df7abafbda8",
|
||||
"6496bdee96100667833f546e1be3d640", "2ebfa25bf981377e682e580208504300",
|
||||
"3e8ae52fd1f607f348aa4cb436c71ab7", "3d4efe797ca82193613696753ea624c4",
|
||||
"cb8aab6d372278f3131e8d99efde02d9"
|
||||
};
|
||||
TestHighbdIntraPred("Intra32", pred_funcs, kSignatures, 32);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Defines a test case for |arch| (e.g., C, SSE2, ...) passing the predictors
|
||||
// to |test_func|. The test name is 'arch.test_func', e.g., C.TestIntraPred4.
|
||||
#define HIGHBD_INTRA_PRED_TEST(arch, test_func, dc, dc_left, dc_top, dc_128, \
|
||||
v, h, d45, d135, d117, d153, d207, d63, tm) \
|
||||
TEST(arch, test_func) { \
|
||||
static const VpxHighbdPredFunc vpx_intra_pred[] = { \
|
||||
dc, dc_left, dc_top, dc_128, v, h, d45, d135, d117, d153, d207, d63, tm \
|
||||
}; \
|
||||
test_func(vpx_intra_pred); \
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
C, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_c,
|
||||
vpx_highbd_dc_left_predictor_4x4_c, vpx_highbd_dc_top_predictor_4x4_c,
|
||||
vpx_highbd_dc_128_predictor_4x4_c, vpx_highbd_v_predictor_4x4_c,
|
||||
vpx_highbd_h_predictor_4x4_c, vpx_highbd_d45_predictor_4x4_c,
|
||||
vpx_highbd_d135_predictor_4x4_c, vpx_highbd_d117_predictor_4x4_c,
|
||||
vpx_highbd_d153_predictor_4x4_c, vpx_highbd_d207_predictor_4x4_c,
|
||||
vpx_highbd_d63_predictor_4x4_c, vpx_highbd_tm_predictor_4x4_c)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
C, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_c,
|
||||
vpx_highbd_dc_left_predictor_8x8_c, vpx_highbd_dc_top_predictor_8x8_c,
|
||||
vpx_highbd_dc_128_predictor_8x8_c, vpx_highbd_v_predictor_8x8_c,
|
||||
vpx_highbd_h_predictor_8x8_c, vpx_highbd_d45_predictor_8x8_c,
|
||||
vpx_highbd_d135_predictor_8x8_c, vpx_highbd_d117_predictor_8x8_c,
|
||||
vpx_highbd_d153_predictor_8x8_c, vpx_highbd_d207_predictor_8x8_c,
|
||||
vpx_highbd_d63_predictor_8x8_c, vpx_highbd_tm_predictor_8x8_c)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
C, TestHighbdIntraPred16, vpx_highbd_dc_predictor_16x16_c,
|
||||
vpx_highbd_dc_left_predictor_16x16_c, vpx_highbd_dc_top_predictor_16x16_c,
|
||||
vpx_highbd_dc_128_predictor_16x16_c, vpx_highbd_v_predictor_16x16_c,
|
||||
vpx_highbd_h_predictor_16x16_c, vpx_highbd_d45_predictor_16x16_c,
|
||||
vpx_highbd_d135_predictor_16x16_c, vpx_highbd_d117_predictor_16x16_c,
|
||||
vpx_highbd_d153_predictor_16x16_c, vpx_highbd_d207_predictor_16x16_c,
|
||||
vpx_highbd_d63_predictor_16x16_c, vpx_highbd_tm_predictor_16x16_c)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
C, TestHighbdIntraPred32, vpx_highbd_dc_predictor_32x32_c,
|
||||
vpx_highbd_dc_left_predictor_32x32_c, vpx_highbd_dc_top_predictor_32x32_c,
|
||||
vpx_highbd_dc_128_predictor_32x32_c, vpx_highbd_v_predictor_32x32_c,
|
||||
vpx_highbd_h_predictor_32x32_c, vpx_highbd_d45_predictor_32x32_c,
|
||||
vpx_highbd_d135_predictor_32x32_c, vpx_highbd_d117_predictor_32x32_c,
|
||||
vpx_highbd_d153_predictor_32x32_c, vpx_highbd_d207_predictor_32x32_c,
|
||||
vpx_highbd_d63_predictor_32x32_c, vpx_highbd_tm_predictor_32x32_c)
|
||||
|
||||
#if HAVE_SSE2
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
SSE2, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_sse2,
|
||||
vpx_highbd_dc_left_predictor_4x4_sse2, vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
vpx_highbd_dc_128_predictor_4x4_sse2, vpx_highbd_v_predictor_4x4_sse2,
|
||||
vpx_highbd_h_predictor_4x4_sse2, NULL, vpx_highbd_d135_predictor_4x4_sse2,
|
||||
vpx_highbd_d117_predictor_4x4_sse2, vpx_highbd_d153_predictor_4x4_sse2,
|
||||
vpx_highbd_d207_predictor_4x4_sse2, vpx_highbd_d63_predictor_4x4_sse2,
|
||||
vpx_highbd_tm_predictor_4x4_c)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred8,
|
||||
vpx_highbd_dc_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
vpx_highbd_v_predictor_8x8_sse2,
|
||||
vpx_highbd_h_predictor_8x8_sse2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_tm_predictor_8x8_sse2)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred16,
|
||||
vpx_highbd_dc_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
vpx_highbd_v_predictor_16x16_sse2,
|
||||
vpx_highbd_h_predictor_16x16_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_16x16_sse2)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred32,
|
||||
vpx_highbd_dc_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
vpx_highbd_v_predictor_32x32_sse2,
|
||||
vpx_highbd_h_predictor_32x32_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_32x32_sse2)
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred4, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_4x4_ssse3, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred8, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
vpx_highbd_d63_predictor_8x8_ssse3, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred16, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
vpx_highbd_d63_predictor_16x16_ssse3, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred32, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
vpx_highbd_d117_predictor_32x32_ssse3,
|
||||
vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
vpx_highbd_d63_predictor_32x32_ssse3, NULL)
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_NEON
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
NEON, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_neon,
|
||||
vpx_highbd_dc_left_predictor_4x4_neon, vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
vpx_highbd_dc_128_predictor_4x4_neon, vpx_highbd_v_predictor_4x4_neon,
|
||||
vpx_highbd_h_predictor_4x4_neon, vpx_highbd_d45_predictor_4x4_neon,
|
||||
vpx_highbd_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_4x4_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
NEON, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_neon,
|
||||
vpx_highbd_dc_left_predictor_8x8_neon, vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
vpx_highbd_dc_128_predictor_8x8_neon, vpx_highbd_v_predictor_8x8_neon,
|
||||
vpx_highbd_h_predictor_8x8_neon, vpx_highbd_d45_predictor_8x8_neon,
|
||||
vpx_highbd_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_8x8_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred16,
|
||||
vpx_highbd_dc_predictor_16x16_neon,
|
||||
vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
vpx_highbd_v_predictor_16x16_neon,
|
||||
vpx_highbd_h_predictor_16x16_neon,
|
||||
vpx_highbd_d45_predictor_16x16_neon,
|
||||
vpx_highbd_d135_predictor_16x16_neon, NULL, NULL, NULL,
|
||||
NULL, vpx_highbd_tm_predictor_16x16_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred32,
|
||||
vpx_highbd_dc_predictor_32x32_neon,
|
||||
vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
vpx_highbd_v_predictor_32x32_neon,
|
||||
vpx_highbd_h_predictor_32x32_neon,
|
||||
vpx_highbd_d45_predictor_32x32_neon,
|
||||
vpx_highbd_d135_predictor_32x32_neon, NULL, NULL, NULL,
|
||||
NULL, vpx_highbd_tm_predictor_32x32_neon)
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#include "test/test_libvpx.cc"
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 <string>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#if VPX_ARCH_X86 || VPX_ARCH_X86_64
|
||||
#include "vpx_ports/x86.h"
|
||||
#endif
|
||||
extern "C" {
|
||||
#if CONFIG_VP8
|
||||
extern void vp8_rtcd();
|
||||
#endif // CONFIG_VP8
|
||||
#if CONFIG_VP9
|
||||
extern void vp9_rtcd();
|
||||
#endif // CONFIG_VP9
|
||||
extern void vpx_dsp_rtcd();
|
||||
extern void vpx_scale_rtcd();
|
||||
}
|
||||
|
||||
#if VPX_ARCH_X86 || VPX_ARCH_X86_64
|
||||
static void append_negative_gtest_filter(const char *str) {
|
||||
std::string filter = ::testing::FLAGS_gtest_filter;
|
||||
// Negative patterns begin with one '-' followed by a ':' separated list.
|
||||
if (filter.find('-') == std::string::npos) filter += '-';
|
||||
filter += str;
|
||||
::testing::FLAGS_gtest_filter = filter;
|
||||
}
|
||||
#endif // VPX_ARCH_X86 || VPX_ARCH_X86_64
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
#if VPX_ARCH_X86 || VPX_ARCH_X86_64
|
||||
const int simd_caps = x86_simd_caps();
|
||||
if (!(simd_caps & HAS_MMX)) append_negative_gtest_filter(":MMX.*:MMX/*");
|
||||
if (!(simd_caps & HAS_SSE)) append_negative_gtest_filter(":SSE.*:SSE/*");
|
||||
if (!(simd_caps & HAS_SSE2)) append_negative_gtest_filter(":SSE2.*:SSE2/*");
|
||||
if (!(simd_caps & HAS_SSE3)) append_negative_gtest_filter(":SSE3.*:SSE3/*");
|
||||
if (!(simd_caps & HAS_SSSE3)) {
|
||||
append_negative_gtest_filter(":SSSE3.*:SSSE3/*");
|
||||
}
|
||||
if (!(simd_caps & HAS_SSE4_1)) {
|
||||
append_negative_gtest_filter(":SSE4_1.*:SSE4_1/*");
|
||||
}
|
||||
if (!(simd_caps & HAS_AVX)) append_negative_gtest_filter(":AVX.*:AVX/*");
|
||||
if (!(simd_caps & HAS_AVX2)) append_negative_gtest_filter(":AVX2.*:AVX2/*");
|
||||
if (!(simd_caps & HAS_AVX512)) {
|
||||
append_negative_gtest_filter(":AVX512.*:AVX512/*");
|
||||
}
|
||||
#endif // VPX_ARCH_X86 || VPX_ARCH_X86_64
|
||||
|
||||
#if !CONFIG_SHARED
|
||||
// Shared library builds don't support whitebox tests
|
||||
// that exercise internal symbols.
|
||||
#if CONFIG_VP8
|
||||
vp8_rtcd();
|
||||
#endif // CONFIG_VP8
|
||||
#if CONFIG_VP9
|
||||
vp9_rtcd();
|
||||
#endif // CONFIG_VP9
|
||||
vpx_dsp_rtcd();
|
||||
vpx_scale_rtcd();
|
||||
#endif // !CONFIG_SHARED
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "../tools_common.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/test_vectors.h"
|
||||
#include "test/util.h"
|
||||
#if CONFIG_WEBM_IO
|
||||
#include "test/webm_video_source.h"
|
||||
#endif
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const int kThreads = 0;
|
||||
const int kMtMode = 1;
|
||||
const int kFileName = 2;
|
||||
|
||||
typedef std::tuple<int, int, const char *> DecodeParam;
|
||||
|
||||
class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
||||
protected:
|
||||
TestVectorTest() : DecoderTest(GET_PARAM(0)), md5_file_(NULL) {
|
||||
#if CONFIG_VP9_DECODER
|
||||
resize_clips_.insert(::libvpx_test::kVP9TestVectorsResize,
|
||||
::libvpx_test::kVP9TestVectorsResize +
|
||||
::libvpx_test::kNumVP9TestVectorsResize);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~TestVectorTest() {
|
||||
if (md5_file_) fclose(md5_file_);
|
||||
}
|
||||
|
||||
void OpenMD5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
virtual void PreDecodeFrameHook(
|
||||
const libvpx_test::CompressedVideoSource &video,
|
||||
libvpx_test::Decoder *decoder) {
|
||||
if (video.frame_number() == 0 && mt_mode_ >= 0) {
|
||||
if (mt_mode_ == 1) {
|
||||
decoder->Control(VP9D_SET_LOOP_FILTER_OPT, 1);
|
||||
decoder->Control(VP9D_SET_ROW_MT, 0);
|
||||
} else if (mt_mode_ == 2) {
|
||||
decoder->Control(VP9D_SET_LOOP_FILTER_OPT, 0);
|
||||
decoder->Control(VP9D_SET_ROW_MT, 1);
|
||||
} else {
|
||||
decoder->Control(VP9D_SET_LOOP_FILTER_OPT, 0);
|
||||
decoder->Control(VP9D_SET_ROW_MT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
const unsigned int frame_number) {
|
||||
ASSERT_TRUE(md5_file_ != NULL);
|
||||
char expected_md5[33];
|
||||
char junk[128];
|
||||
|
||||
// Read correct md5 checksums.
|
||||
const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
|
||||
ASSERT_NE(res, EOF) << "Read md5 data failed";
|
||||
expected_md5[32] = '\0';
|
||||
|
||||
::libvpx_test::MD5 md5_res;
|
||||
md5_res.Add(&img);
|
||||
const char *actual_md5 = md5_res.Get();
|
||||
|
||||
// Check md5 match.
|
||||
ASSERT_STREQ(expected_md5, actual_md5)
|
||||
<< "Md5 checksums don't match: frame number = " << frame_number;
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
std::set<std::string> resize_clips_;
|
||||
#endif
|
||||
int mt_mode_;
|
||||
|
||||
private:
|
||||
FILE *md5_file_;
|
||||
};
|
||||
|
||||
// This test runs through the whole set of test vectors, and decodes them.
|
||||
// The md5 checksums are computed for each frame in the video file. If md5
|
||||
// checksums match the correct md5 data, then the test is passed. Otherwise,
|
||||
// the test failed.
|
||||
TEST_P(TestVectorTest, MD5Match) {
|
||||
const DecodeParam input = GET_PARAM(1);
|
||||
const std::string filename = std::get<kFileName>(input);
|
||||
vpx_codec_flags_t flags = 0;
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
char str[256];
|
||||
|
||||
cfg.threads = std::get<kThreads>(input);
|
||||
mt_mode_ = std::get<kMtMode>(input);
|
||||
snprintf(str, sizeof(str) / sizeof(str[0]) - 1,
|
||||
"file: %s threads: %d MT mode: %d", filename.c_str(), cfg.threads,
|
||||
mt_mode_);
|
||||
SCOPED_TRACE(str);
|
||||
|
||||
// Open compressed video file.
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
|
||||
#if CONFIG_WEBM_IO
|
||||
video.reset(new libvpx_test::WebMVideoSource(filename));
|
||||
#else
|
||||
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
||||
filename.c_str());
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
|
||||
// Construct md5 file name.
|
||||
const std::string md5_filename = filename + ".md5";
|
||||
OpenMD5File(md5_filename);
|
||||
|
||||
// Set decode config and flags.
|
||||
set_cfg(cfg);
|
||||
set_flags(flags);
|
||||
|
||||
// Decode frame, and check the md5 matching.
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
|
||||
}
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
VP8_INSTANTIATE_TEST_CASE(
|
||||
TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(1), // Single thread.
|
||||
::testing::Values(-1), // LPF opt and Row MT is not applicable
|
||||
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
||||
libvpx_test::kVP8TestVectors +
|
||||
libvpx_test::kNumVP8TestVectors)));
|
||||
|
||||
// Test VP8 decode in with different numbers of threads.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP8MultiThreaded, TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)),
|
||||
::testing::Combine(
|
||||
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||
::testing::Values(-1), // LPF opt and Row MT is not applicable
|
||||
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
||||
libvpx_test::kVP8TestVectors +
|
||||
libvpx_test::kNumVP8TestVectors))));
|
||||
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(1), // Single thread.
|
||||
::testing::Values(-1), // LPF opt and Row MT is not applicable
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
libvpx_test::kNumVP9TestVectors)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9MultiThreaded, TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Combine(
|
||||
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||
::testing::Range(0, 3), // With multi threads modes 0 ~ 2
|
||||
// 0: LPF opt and Row MT disabled
|
||||
// 1: LPF opt enabled
|
||||
// 2: Row MT enabled
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
libvpx_test::kNumVP9TestVectors))));
|
||||
#endif
|
||||
} // namespace
|
||||
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test/test_vectors.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
const char *const kVP8TestVectors[] = {
|
||||
"vp80-00-comprehensive-001.ivf", "vp80-00-comprehensive-002.ivf",
|
||||
"vp80-00-comprehensive-003.ivf", "vp80-00-comprehensive-004.ivf",
|
||||
"vp80-00-comprehensive-005.ivf", "vp80-00-comprehensive-006.ivf",
|
||||
"vp80-00-comprehensive-007.ivf", "vp80-00-comprehensive-008.ivf",
|
||||
"vp80-00-comprehensive-009.ivf", "vp80-00-comprehensive-010.ivf",
|
||||
"vp80-00-comprehensive-011.ivf", "vp80-00-comprehensive-012.ivf",
|
||||
"vp80-00-comprehensive-013.ivf", "vp80-00-comprehensive-014.ivf",
|
||||
"vp80-00-comprehensive-015.ivf", "vp80-00-comprehensive-016.ivf",
|
||||
"vp80-00-comprehensive-017.ivf", "vp80-00-comprehensive-018.ivf",
|
||||
"vp80-01-intra-1400.ivf", "vp80-01-intra-1411.ivf",
|
||||
"vp80-01-intra-1416.ivf", "vp80-01-intra-1417.ivf",
|
||||
"vp80-02-inter-1402.ivf", "vp80-02-inter-1412.ivf",
|
||||
"vp80-02-inter-1418.ivf", "vp80-02-inter-1424.ivf",
|
||||
"vp80-03-segmentation-01.ivf", "vp80-03-segmentation-02.ivf",
|
||||
"vp80-03-segmentation-03.ivf", "vp80-03-segmentation-04.ivf",
|
||||
"vp80-03-segmentation-1401.ivf", "vp80-03-segmentation-1403.ivf",
|
||||
"vp80-03-segmentation-1407.ivf", "vp80-03-segmentation-1408.ivf",
|
||||
"vp80-03-segmentation-1409.ivf", "vp80-03-segmentation-1410.ivf",
|
||||
"vp80-03-segmentation-1413.ivf", "vp80-03-segmentation-1414.ivf",
|
||||
"vp80-03-segmentation-1415.ivf", "vp80-03-segmentation-1425.ivf",
|
||||
"vp80-03-segmentation-1426.ivf", "vp80-03-segmentation-1427.ivf",
|
||||
"vp80-03-segmentation-1432.ivf", "vp80-03-segmentation-1435.ivf",
|
||||
"vp80-03-segmentation-1436.ivf", "vp80-03-segmentation-1437.ivf",
|
||||
"vp80-03-segmentation-1441.ivf", "vp80-03-segmentation-1442.ivf",
|
||||
"vp80-04-partitions-1404.ivf", "vp80-04-partitions-1405.ivf",
|
||||
"vp80-04-partitions-1406.ivf", "vp80-05-sharpness-1428.ivf",
|
||||
"vp80-05-sharpness-1429.ivf", "vp80-05-sharpness-1430.ivf",
|
||||
"vp80-05-sharpness-1431.ivf", "vp80-05-sharpness-1433.ivf",
|
||||
"vp80-05-sharpness-1434.ivf", "vp80-05-sharpness-1438.ivf",
|
||||
"vp80-05-sharpness-1439.ivf", "vp80-05-sharpness-1440.ivf",
|
||||
"vp80-05-sharpness-1443.ivf", "vp80-06-smallsize.ivf"
|
||||
};
|
||||
const int kNumVP8TestVectors = NELEMENTS(kVP8TestVectors);
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
#if CONFIG_VP9_DECODER
|
||||
#define RESIZE_TEST_VECTORS \
|
||||
"vp90-2-21-resize_inter_320x180_5_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_320x180_5_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_320x180_7_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_320x180_7_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_320x240_5_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_320x240_5_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_320x240_7_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_320x240_7_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_640x360_5_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_640x360_5_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_640x360_7_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_640x360_7_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_640x480_5_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_640x480_5_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_640x480_7_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_640x480_7_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_1280x720_5_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_1280x720_5_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_1280x720_7_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_1280x720_7_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_1920x1080_5_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_1920x1080_5_3-4.webm", \
|
||||
"vp90-2-21-resize_inter_1920x1080_7_1-2.webm", \
|
||||
"vp90-2-21-resize_inter_1920x1080_7_3-4.webm",
|
||||
|
||||
const char *const kVP9TestVectors[] = {
|
||||
"vp90-2-00-quantizer-00.webm",
|
||||
"vp90-2-00-quantizer-01.webm",
|
||||
"vp90-2-00-quantizer-02.webm",
|
||||
"vp90-2-00-quantizer-03.webm",
|
||||
"vp90-2-00-quantizer-04.webm",
|
||||
"vp90-2-00-quantizer-05.webm",
|
||||
"vp90-2-00-quantizer-06.webm",
|
||||
"vp90-2-00-quantizer-07.webm",
|
||||
"vp90-2-00-quantizer-08.webm",
|
||||
"vp90-2-00-quantizer-09.webm",
|
||||
"vp90-2-00-quantizer-10.webm",
|
||||
"vp90-2-00-quantizer-11.webm",
|
||||
"vp90-2-00-quantizer-12.webm",
|
||||
"vp90-2-00-quantizer-13.webm",
|
||||
"vp90-2-00-quantizer-14.webm",
|
||||
"vp90-2-00-quantizer-15.webm",
|
||||
"vp90-2-00-quantizer-16.webm",
|
||||
"vp90-2-00-quantizer-17.webm",
|
||||
"vp90-2-00-quantizer-18.webm",
|
||||
"vp90-2-00-quantizer-19.webm",
|
||||
"vp90-2-00-quantizer-20.webm",
|
||||
"vp90-2-00-quantizer-21.webm",
|
||||
"vp90-2-00-quantizer-22.webm",
|
||||
"vp90-2-00-quantizer-23.webm",
|
||||
"vp90-2-00-quantizer-24.webm",
|
||||
"vp90-2-00-quantizer-25.webm",
|
||||
"vp90-2-00-quantizer-26.webm",
|
||||
"vp90-2-00-quantizer-27.webm",
|
||||
"vp90-2-00-quantizer-28.webm",
|
||||
"vp90-2-00-quantizer-29.webm",
|
||||
"vp90-2-00-quantizer-30.webm",
|
||||
"vp90-2-00-quantizer-31.webm",
|
||||
"vp90-2-00-quantizer-32.webm",
|
||||
"vp90-2-00-quantizer-33.webm",
|
||||
"vp90-2-00-quantizer-34.webm",
|
||||
"vp90-2-00-quantizer-35.webm",
|
||||
"vp90-2-00-quantizer-36.webm",
|
||||
"vp90-2-00-quantizer-37.webm",
|
||||
"vp90-2-00-quantizer-38.webm",
|
||||
"vp90-2-00-quantizer-39.webm",
|
||||
"vp90-2-00-quantizer-40.webm",
|
||||
"vp90-2-00-quantizer-41.webm",
|
||||
"vp90-2-00-quantizer-42.webm",
|
||||
"vp90-2-00-quantizer-43.webm",
|
||||
"vp90-2-00-quantizer-44.webm",
|
||||
"vp90-2-00-quantizer-45.webm",
|
||||
"vp90-2-00-quantizer-46.webm",
|
||||
"vp90-2-00-quantizer-47.webm",
|
||||
"vp90-2-00-quantizer-48.webm",
|
||||
"vp90-2-00-quantizer-49.webm",
|
||||
"vp90-2-00-quantizer-50.webm",
|
||||
"vp90-2-00-quantizer-51.webm",
|
||||
"vp90-2-00-quantizer-52.webm",
|
||||
"vp90-2-00-quantizer-53.webm",
|
||||
"vp90-2-00-quantizer-54.webm",
|
||||
"vp90-2-00-quantizer-55.webm",
|
||||
"vp90-2-00-quantizer-56.webm",
|
||||
"vp90-2-00-quantizer-57.webm",
|
||||
"vp90-2-00-quantizer-58.webm",
|
||||
"vp90-2-00-quantizer-59.webm",
|
||||
"vp90-2-00-quantizer-60.webm",
|
||||
"vp90-2-00-quantizer-61.webm",
|
||||
"vp90-2-00-quantizer-62.webm",
|
||||
"vp90-2-00-quantizer-63.webm",
|
||||
"vp90-2-01-sharpness-1.webm",
|
||||
"vp90-2-01-sharpness-2.webm",
|
||||
"vp90-2-01-sharpness-3.webm",
|
||||
"vp90-2-01-sharpness-4.webm",
|
||||
"vp90-2-01-sharpness-5.webm",
|
||||
"vp90-2-01-sharpness-6.webm",
|
||||
"vp90-2-01-sharpness-7.webm",
|
||||
"vp90-2-02-size-08x08.webm",
|
||||
"vp90-2-02-size-08x10.webm",
|
||||
"vp90-2-02-size-08x16.webm",
|
||||
"vp90-2-02-size-08x18.webm",
|
||||
"vp90-2-02-size-08x32.webm",
|
||||
"vp90-2-02-size-08x34.webm",
|
||||
"vp90-2-02-size-08x64.webm",
|
||||
"vp90-2-02-size-08x66.webm",
|
||||
"vp90-2-02-size-10x08.webm",
|
||||
"vp90-2-02-size-10x10.webm",
|
||||
"vp90-2-02-size-10x16.webm",
|
||||
"vp90-2-02-size-10x18.webm",
|
||||
"vp90-2-02-size-10x32.webm",
|
||||
"vp90-2-02-size-10x34.webm",
|
||||
"vp90-2-02-size-10x64.webm",
|
||||
"vp90-2-02-size-10x66.webm",
|
||||
"vp90-2-02-size-16x08.webm",
|
||||
"vp90-2-02-size-16x10.webm",
|
||||
"vp90-2-02-size-16x16.webm",
|
||||
"vp90-2-02-size-16x18.webm",
|
||||
"vp90-2-02-size-16x32.webm",
|
||||
"vp90-2-02-size-16x34.webm",
|
||||
"vp90-2-02-size-16x64.webm",
|
||||
"vp90-2-02-size-16x66.webm",
|
||||
"vp90-2-02-size-18x08.webm",
|
||||
"vp90-2-02-size-18x10.webm",
|
||||
"vp90-2-02-size-18x16.webm",
|
||||
"vp90-2-02-size-18x18.webm",
|
||||
"vp90-2-02-size-18x32.webm",
|
||||
"vp90-2-02-size-18x34.webm",
|
||||
"vp90-2-02-size-18x64.webm",
|
||||
"vp90-2-02-size-18x66.webm",
|
||||
"vp90-2-02-size-32x08.webm",
|
||||
"vp90-2-02-size-32x10.webm",
|
||||
"vp90-2-02-size-32x16.webm",
|
||||
"vp90-2-02-size-32x18.webm",
|
||||
"vp90-2-02-size-32x32.webm",
|
||||
"vp90-2-02-size-32x34.webm",
|
||||
"vp90-2-02-size-32x64.webm",
|
||||
"vp90-2-02-size-32x66.webm",
|
||||
"vp90-2-02-size-34x08.webm",
|
||||
"vp90-2-02-size-34x10.webm",
|
||||
"vp90-2-02-size-34x16.webm",
|
||||
"vp90-2-02-size-34x18.webm",
|
||||
"vp90-2-02-size-34x32.webm",
|
||||
"vp90-2-02-size-34x34.webm",
|
||||
"vp90-2-02-size-34x64.webm",
|
||||
"vp90-2-02-size-34x66.webm",
|
||||
"vp90-2-02-size-64x08.webm",
|
||||
"vp90-2-02-size-64x10.webm",
|
||||
"vp90-2-02-size-64x16.webm",
|
||||
"vp90-2-02-size-64x18.webm",
|
||||
"vp90-2-02-size-64x32.webm",
|
||||
"vp90-2-02-size-64x34.webm",
|
||||
"vp90-2-02-size-64x64.webm",
|
||||
"vp90-2-02-size-64x66.webm",
|
||||
"vp90-2-02-size-66x08.webm",
|
||||
"vp90-2-02-size-66x10.webm",
|
||||
"vp90-2-02-size-66x16.webm",
|
||||
"vp90-2-02-size-66x18.webm",
|
||||
"vp90-2-02-size-66x32.webm",
|
||||
"vp90-2-02-size-66x34.webm",
|
||||
"vp90-2-02-size-66x64.webm",
|
||||
"vp90-2-02-size-66x66.webm",
|
||||
"vp90-2-02-size-130x132.webm",
|
||||
"vp90-2-02-size-132x130.webm",
|
||||
"vp90-2-02-size-132x132.webm",
|
||||
"vp90-2-02-size-178x180.webm",
|
||||
"vp90-2-02-size-180x178.webm",
|
||||
"vp90-2-02-size-180x180.webm",
|
||||
"vp90-2-03-size-196x196.webm",
|
||||
"vp90-2-03-size-196x198.webm",
|
||||
"vp90-2-03-size-196x200.webm",
|
||||
"vp90-2-03-size-196x202.webm",
|
||||
"vp90-2-03-size-196x208.webm",
|
||||
"vp90-2-03-size-196x210.webm",
|
||||
"vp90-2-03-size-196x224.webm",
|
||||
"vp90-2-03-size-196x226.webm",
|
||||
"vp90-2-03-size-198x196.webm",
|
||||
"vp90-2-03-size-198x198.webm",
|
||||
"vp90-2-03-size-198x200.webm",
|
||||
"vp90-2-03-size-198x202.webm",
|
||||
"vp90-2-03-size-198x208.webm",
|
||||
"vp90-2-03-size-198x210.webm",
|
||||
"vp90-2-03-size-198x224.webm",
|
||||
"vp90-2-03-size-198x226.webm",
|
||||
"vp90-2-03-size-200x196.webm",
|
||||
"vp90-2-03-size-200x198.webm",
|
||||
"vp90-2-03-size-200x200.webm",
|
||||
"vp90-2-03-size-200x202.webm",
|
||||
"vp90-2-03-size-200x208.webm",
|
||||
"vp90-2-03-size-200x210.webm",
|
||||
"vp90-2-03-size-200x224.webm",
|
||||
"vp90-2-03-size-200x226.webm",
|
||||
"vp90-2-03-size-202x196.webm",
|
||||
"vp90-2-03-size-202x198.webm",
|
||||
"vp90-2-03-size-202x200.webm",
|
||||
"vp90-2-03-size-202x202.webm",
|
||||
"vp90-2-03-size-202x208.webm",
|
||||
"vp90-2-03-size-202x210.webm",
|
||||
"vp90-2-03-size-202x224.webm",
|
||||
"vp90-2-03-size-202x226.webm",
|
||||
"vp90-2-03-size-208x196.webm",
|
||||
"vp90-2-03-size-208x198.webm",
|
||||
"vp90-2-03-size-208x200.webm",
|
||||
"vp90-2-03-size-208x202.webm",
|
||||
"vp90-2-03-size-208x208.webm",
|
||||
"vp90-2-03-size-208x210.webm",
|
||||
"vp90-2-03-size-208x224.webm",
|
||||
"vp90-2-03-size-208x226.webm",
|
||||
"vp90-2-03-size-210x196.webm",
|
||||
"vp90-2-03-size-210x198.webm",
|
||||
"vp90-2-03-size-210x200.webm",
|
||||
"vp90-2-03-size-210x202.webm",
|
||||
"vp90-2-03-size-210x208.webm",
|
||||
"vp90-2-03-size-210x210.webm",
|
||||
"vp90-2-03-size-210x224.webm",
|
||||
"vp90-2-03-size-210x226.webm",
|
||||
"vp90-2-03-size-224x196.webm",
|
||||
"vp90-2-03-size-224x198.webm",
|
||||
"vp90-2-03-size-224x200.webm",
|
||||
"vp90-2-03-size-224x202.webm",
|
||||
"vp90-2-03-size-224x208.webm",
|
||||
"vp90-2-03-size-224x210.webm",
|
||||
"vp90-2-03-size-224x224.webm",
|
||||
"vp90-2-03-size-224x226.webm",
|
||||
"vp90-2-03-size-226x196.webm",
|
||||
"vp90-2-03-size-226x198.webm",
|
||||
"vp90-2-03-size-226x200.webm",
|
||||
"vp90-2-03-size-226x202.webm",
|
||||
"vp90-2-03-size-226x208.webm",
|
||||
"vp90-2-03-size-226x210.webm",
|
||||
"vp90-2-03-size-226x224.webm",
|
||||
"vp90-2-03-size-226x226.webm",
|
||||
"vp90-2-03-size-352x288.webm",
|
||||
"vp90-2-03-deltaq.webm",
|
||||
"vp90-2-05-resize.ivf",
|
||||
"vp90-2-06-bilinear.webm",
|
||||
"vp90-2-07-frame_parallel.webm",
|
||||
"vp90-2-08-tile_1x2_frame_parallel.webm",
|
||||
"vp90-2-08-tile_1x2.webm",
|
||||
"vp90-2-08-tile_1x4_frame_parallel.webm",
|
||||
"vp90-2-08-tile_1x4.webm",
|
||||
"vp90-2-08-tile_1x8_frame_parallel.webm",
|
||||
"vp90-2-08-tile_1x8.webm",
|
||||
"vp90-2-08-tile-4x4.webm",
|
||||
"vp90-2-08-tile-4x1.webm",
|
||||
"vp90-2-09-subpixel-00.ivf",
|
||||
"vp90-2-02-size-lf-1920x1080.webm",
|
||||
"vp90-2-09-aq2.webm",
|
||||
"vp90-2-09-lf_deltas.webm",
|
||||
"vp90-2-10-show-existing-frame.webm",
|
||||
"vp90-2-10-show-existing-frame2.webm",
|
||||
"vp90-2-11-size-351x287.webm",
|
||||
"vp90-2-11-size-351x288.webm",
|
||||
"vp90-2-11-size-352x287.webm",
|
||||
"vp90-2-12-droppable_1.ivf",
|
||||
"vp90-2-12-droppable_2.ivf",
|
||||
"vp90-2-12-droppable_3.ivf",
|
||||
#if !CONFIG_SIZE_LIMIT || \
|
||||
(DECODE_WIDTH_LIMIT >= 20400 && DECODE_HEIGHT_LIMIT >= 120)
|
||||
"vp90-2-13-largescaling.webm",
|
||||
#endif
|
||||
"vp90-2-14-resize-fp-tiles-1-16.webm",
|
||||
"vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm",
|
||||
"vp90-2-14-resize-fp-tiles-1-2.webm",
|
||||
"vp90-2-14-resize-fp-tiles-1-4.webm",
|
||||
"vp90-2-14-resize-fp-tiles-16-1.webm",
|
||||
"vp90-2-14-resize-fp-tiles-16-2.webm",
|
||||
"vp90-2-14-resize-fp-tiles-16-4.webm",
|
||||
"vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm",
|
||||
"vp90-2-14-resize-fp-tiles-16-8.webm",
|
||||
"vp90-2-14-resize-fp-tiles-1-8.webm",
|
||||
"vp90-2-14-resize-fp-tiles-2-16.webm",
|
||||
"vp90-2-14-resize-fp-tiles-2-1.webm",
|
||||
"vp90-2-14-resize-fp-tiles-2-4.webm",
|
||||
"vp90-2-14-resize-fp-tiles-2-8.webm",
|
||||
"vp90-2-14-resize-fp-tiles-4-16.webm",
|
||||
"vp90-2-14-resize-fp-tiles-4-1.webm",
|
||||
"vp90-2-14-resize-fp-tiles-4-2.webm",
|
||||
"vp90-2-14-resize-fp-tiles-4-8.webm",
|
||||
"vp90-2-14-resize-fp-tiles-8-16.webm",
|
||||
"vp90-2-14-resize-fp-tiles-8-1.webm",
|
||||
"vp90-2-14-resize-fp-tiles-8-2.webm",
|
||||
"vp90-2-14-resize-fp-tiles-8-4.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-1-2.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-1-4.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-1-8.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-2-1.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-2-4.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-2-8.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-4-1.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-4-2.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-4-8.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-8-1.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-8-2.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm",
|
||||
"vp90-2-14-resize-10frames-fp-tiles-8-4.webm",
|
||||
"vp90-2-15-segkey.webm",
|
||||
"vp90-2-15-segkey_adpq.webm",
|
||||
"vp90-2-16-intra-only.webm",
|
||||
"vp90-2-17-show-existing-frame.webm",
|
||||
"vp90-2-18-resize.ivf",
|
||||
"vp90-2-19-skip.webm",
|
||||
"vp90-2-19-skip-01.webm",
|
||||
"vp90-2-19-skip-02.webm",
|
||||
"vp91-2-04-yuv444.webm",
|
||||
"vp91-2-04-yuv422.webm",
|
||||
"vp91-2-04-yuv440.webm",
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
"vp92-2-20-10bit-yuv420.webm",
|
||||
"vp92-2-20-12bit-yuv420.webm",
|
||||
"vp93-2-20-10bit-yuv422.webm",
|
||||
"vp93-2-20-12bit-yuv422.webm",
|
||||
"vp93-2-20-10bit-yuv440.webm",
|
||||
"vp93-2-20-12bit-yuv440.webm",
|
||||
"vp93-2-20-10bit-yuv444.webm",
|
||||
"vp93-2-20-12bit-yuv444.webm",
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
"vp90-2-20-big_superframe-01.webm",
|
||||
"vp90-2-20-big_superframe-02.webm",
|
||||
"vp90-2-22-svc_1280x720_1.webm",
|
||||
RESIZE_TEST_VECTORS
|
||||
};
|
||||
const char *const kVP9TestVectorsSvc[] = { "vp90-2-22-svc_1280x720_3.ivf" };
|
||||
const int kNumVP9TestVectors = NELEMENTS(kVP9TestVectors);
|
||||
const int kNumVP9TestVectorsSvc = NELEMENTS(kVP9TestVectorsSvc);
|
||||
const char *const kVP9TestVectorsResize[] = { RESIZE_TEST_VECTORS };
|
||||
const int kNumVP9TestVectorsResize = NELEMENTS(kVP9TestVectorsResize);
|
||||
#undef RESIZE_TEST_VECTORS
|
||||
#endif // CONFIG_VP9_DECODER
|
||||
|
||||
} // namespace libvpx_test
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 VPX_TEST_TEST_VECTORS_H_
|
||||
#define VPX_TEST_TEST_VECTORS_H_
|
||||
|
||||
#include "./vpx_config.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
extern const int kNumVP8TestVectors;
|
||||
extern const char *const kVP8TestVectors[];
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
extern const int kNumVP9TestVectors;
|
||||
extern const char *const kVP9TestVectors[];
|
||||
extern const int kNumVP9TestVectorsSvc;
|
||||
extern const char *const kVP9TestVectorsSvc[];
|
||||
extern const int kNumVP9TestVectorsResize;
|
||||
extern const char *const kVP9TestVectorsResize[];
|
||||
#endif // CONFIG_VP9_DECODER
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // VPX_TEST_TEST_VECTORS_H_
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#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"
|
||||
#include "test/md5_helper.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
class TileIndependenceTest : public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<int> {
|
||||
protected:
|
||||
TileIndependenceTest()
|
||||
: EncoderTest(GET_PARAM(0)), md5_fw_order_(), md5_inv_order_(),
|
||||
n_tiles_(GET_PARAM(1)) {
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
cfg.w = 704;
|
||||
cfg.h = 144;
|
||||
cfg.threads = 1;
|
||||
fw_dec_ = codec_->CreateDecoder(cfg, 0);
|
||||
inv_dec_ = codec_->CreateDecoder(cfg, 0);
|
||||
inv_dec_->Control(VP9_INVERT_TILE_DECODE_ORDER, 1);
|
||||
}
|
||||
|
||||
virtual ~TileIndependenceTest() {
|
||||
delete fw_dec_;
|
||||
delete inv_dec_;
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(libvpx_test::kTwoPassGood);
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, n_tiles_);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateMD5(::libvpx_test::Decoder *dec, const vpx_codec_cx_pkt_t *pkt,
|
||||
::libvpx_test::MD5 *md5) {
|
||||
const vpx_codec_err_t res = dec->DecodeFrame(
|
||||
reinterpret_cast<uint8_t *>(pkt->data.frame.buf), pkt->data.frame.sz);
|
||||
if (res != VPX_CODEC_OK) {
|
||||
abort_ = true;
|
||||
ASSERT_EQ(VPX_CODEC_OK, res);
|
||||
}
|
||||
const vpx_image_t *img = dec->GetDxData().Next();
|
||||
md5->Add(img);
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
UpdateMD5(fw_dec_, pkt, &md5_fw_order_);
|
||||
UpdateMD5(inv_dec_, pkt, &md5_inv_order_);
|
||||
}
|
||||
|
||||
::libvpx_test::MD5 md5_fw_order_, md5_inv_order_;
|
||||
::libvpx_test::Decoder *fw_dec_, *inv_dec_;
|
||||
|
||||
private:
|
||||
int n_tiles_;
|
||||
};
|
||||
|
||||
// run an encode with 2 or 4 tiles, and do the decode both in normal and
|
||||
// inverted tile ordering. Ensure that the MD5 of the output in both cases
|
||||
// is identical. If so, tiles are considered independent and the test passes.
|
||||
TEST_P(TileIndependenceTest, MD5Match) {
|
||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||
cfg_.g_timebase = timebase;
|
||||
cfg_.rc_target_bitrate = 500;
|
||||
cfg_.g_lag_in_frames = 25;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
|
||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 704, 144,
|
||||
timebase.den, timebase.num, 0, 30);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
const char *md5_fw_str = md5_fw_order_.Get();
|
||||
const char *md5_inv_str = md5_inv_order_.Get();
|
||||
|
||||
// could use ASSERT_EQ(!memcmp(.., .., 16) here, but this gives nicer
|
||||
// output if it fails. Not sure if it's helpful since it's really just
|
||||
// a MD5...
|
||||
ASSERT_STREQ(md5_fw_str, md5_inv_str);
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(TileIndependenceTest, ::testing::Range(0, 2, 1));
|
||||
} // namespace
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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/codec_factory.h"
|
||||
#include "test/encode_test_driver.h"
|
||||
#include "test/util.h"
|
||||
#include "test/video_source.h"
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const int kVideoSourceWidth = 320;
|
||||
const int kVideoSourceHeight = 240;
|
||||
const int kFramesToEncode = 3;
|
||||
|
||||
// A video source that exposes functions to set the timebase, framerate and
|
||||
// starting pts.
|
||||
class DummyTimebaseVideoSource : public ::libvpx_test::DummyVideoSource {
|
||||
public:
|
||||
// Parameters num and den set the timebase for the video source.
|
||||
DummyTimebaseVideoSource(int num, int den)
|
||||
: timebase_({ num, den }), framerate_numerator_(30),
|
||||
framerate_denominator_(1), starting_pts_(0) {
|
||||
SetSize(kVideoSourceWidth, kVideoSourceHeight);
|
||||
set_limit(kFramesToEncode);
|
||||
}
|
||||
|
||||
void SetFramerate(int numerator, int denominator) {
|
||||
framerate_numerator_ = numerator;
|
||||
framerate_denominator_ = denominator;
|
||||
}
|
||||
|
||||
// Returns one frames duration in timebase units as a double.
|
||||
double FrameDuration() const {
|
||||
return (static_cast<double>(timebase_.den) / timebase_.num) /
|
||||
(static_cast<double>(framerate_numerator_) / framerate_denominator_);
|
||||
}
|
||||
|
||||
virtual vpx_codec_pts_t pts() const {
|
||||
return static_cast<vpx_codec_pts_t>(frame_ * FrameDuration() +
|
||||
starting_pts_ + 0.5);
|
||||
}
|
||||
|
||||
virtual unsigned long duration() const {
|
||||
return static_cast<unsigned long>(FrameDuration() + 0.5);
|
||||
}
|
||||
|
||||
virtual vpx_rational_t timebase() const { return timebase_; }
|
||||
|
||||
void set_starting_pts(int64_t starting_pts) { starting_pts_ = starting_pts; }
|
||||
|
||||
private:
|
||||
vpx_rational_t timebase_;
|
||||
int framerate_numerator_;
|
||||
int framerate_denominator_;
|
||||
int64_t starting_pts_;
|
||||
};
|
||||
|
||||
class TimestampTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
protected:
|
||||
TimestampTest() : EncoderTest(GET_PARAM(0)) {}
|
||||
virtual ~TimestampTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
}
|
||||
};
|
||||
|
||||
// Tests encoding in millisecond timebase.
|
||||
TEST_P(TimestampTest, EncodeFrames) {
|
||||
DummyTimebaseVideoSource video(1, 1000);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
TEST_P(TimestampTest, TestMicrosecondTimebase) {
|
||||
// Set the timebase to microseconds.
|
||||
DummyTimebaseVideoSource video(1, 1000000);
|
||||
video.set_limit(1);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
TEST_P(TimestampTest, TestVpxRollover) {
|
||||
DummyTimebaseVideoSource video(1, 1000);
|
||||
video.set_starting_pts(922337170351ll);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(TimestampTest,
|
||||
::testing::Values(::libvpx_test::kTwoPassGood));
|
||||
VP9_INSTANTIATE_TEST_CASE(TimestampTest,
|
||||
::testing::Values(::libvpx_test::kTwoPassGood));
|
||||
} // namespace
|
||||
@@ -0,0 +1,442 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file contains shell code shared by test scripts for libvpx tools.
|
||||
|
||||
# Use $VPX_TEST_TOOLS_COMMON_SH as a pseudo include guard.
|
||||
if [ -z "${VPX_TEST_TOOLS_COMMON_SH}" ]; then
|
||||
VPX_TEST_TOOLS_COMMON_SH=included
|
||||
|
||||
set -e
|
||||
devnull='> /dev/null 2>&1'
|
||||
VPX_TEST_PREFIX=""
|
||||
|
||||
elog() {
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
|
||||
vlog() {
|
||||
if [ "${VPX_TEST_VERBOSE_OUTPUT}" = "yes" ]; then
|
||||
echo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# Sets $VPX_TOOL_TEST to the name specified by positional parameter one.
|
||||
test_begin() {
|
||||
VPX_TOOL_TEST="${1}"
|
||||
}
|
||||
|
||||
# Clears the VPX_TOOL_TEST variable after confirming that $VPX_TOOL_TEST matches
|
||||
# positional parameter one.
|
||||
test_end() {
|
||||
if [ "$1" != "${VPX_TOOL_TEST}" ]; then
|
||||
echo "FAIL completed test mismatch!."
|
||||
echo " completed test: ${1}"
|
||||
echo " active test: ${VPX_TOOL_TEST}."
|
||||
return 1
|
||||
fi
|
||||
VPX_TOOL_TEST='<unset>'
|
||||
}
|
||||
|
||||
# Echoes the target configuration being tested.
|
||||
test_configuration_target() {
|
||||
vpx_config_mk="${LIBVPX_CONFIG_PATH}/config.mk"
|
||||
# Find the TOOLCHAIN line, split it using ':=' as the field separator, and
|
||||
# print the last field to get the value. Then pipe the value to tr to consume
|
||||
# any leading/trailing spaces while allowing tr to echo the output to stdout.
|
||||
awk -F ':=' '/TOOLCHAIN/ { print $NF }' "${vpx_config_mk}" | tr -d ' '
|
||||
}
|
||||
|
||||
# Trap function used for failure reports and tool output directory removal.
|
||||
# When the contents of $VPX_TOOL_TEST do not match the string '<unset>', reports
|
||||
# failure of test stored in $VPX_TOOL_TEST.
|
||||
cleanup() {
|
||||
if [ -n "${VPX_TOOL_TEST}" ] && [ "${VPX_TOOL_TEST}" != '<unset>' ]; then
|
||||
echo "FAIL: $VPX_TOOL_TEST"
|
||||
fi
|
||||
if [ -n "${VPX_TEST_OUTPUT_DIR}" ] && [ -d "${VPX_TEST_OUTPUT_DIR}" ]; then
|
||||
rm -rf "${VPX_TEST_OUTPUT_DIR}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Echoes the git hash portion of the VERSION_STRING variable defined in
|
||||
# $LIBVPX_CONFIG_PATH/config.mk to stdout, or the version number string when
|
||||
# no git hash is contained in VERSION_STRING.
|
||||
config_hash() {
|
||||
vpx_config_mk="${LIBVPX_CONFIG_PATH}/config.mk"
|
||||
# Find VERSION_STRING line, split it with "-g" and print the last field to
|
||||
# output the git hash to stdout.
|
||||
vpx_version=$(awk -F -g '/VERSION_STRING/ {print $NF}' "${vpx_config_mk}")
|
||||
# Handle two situations here:
|
||||
# 1. The default case: $vpx_version is a git hash, so echo it unchanged.
|
||||
# 2. When being run a non-dev tree, the -g portion is not present in the
|
||||
# version string: It's only the version number.
|
||||
# In this case $vpx_version is something like 'VERSION_STRING=v1.3.0', so
|
||||
# we echo only what is after the '='.
|
||||
echo "${vpx_version##*=}"
|
||||
}
|
||||
|
||||
# Echoes the short form of the current git hash.
|
||||
current_hash() {
|
||||
if git --version > /dev/null 2>&1; then
|
||||
(cd "$(dirname "${0}")"
|
||||
git rev-parse --short HEAD)
|
||||
else
|
||||
# Return the config hash if git is unavailable: Fail silently, git hashes
|
||||
# are used only for warnings.
|
||||
config_hash
|
||||
fi
|
||||
}
|
||||
|
||||
# Echoes warnings to stdout when git hash in vpx_config.h does not match the
|
||||
# current git hash.
|
||||
check_git_hashes() {
|
||||
hash_at_configure_time=$(config_hash)
|
||||
hash_now=$(current_hash)
|
||||
|
||||
if [ "${hash_at_configure_time}" != "${hash_now}" ]; then
|
||||
echo "Warning: git hash has changed since last configure."
|
||||
fi
|
||||
}
|
||||
|
||||
# $1 is the name of an environment variable containing a directory name to
|
||||
# test.
|
||||
test_env_var_dir() {
|
||||
local dir=$(eval echo "\${$1}")
|
||||
if [ ! -d "${dir}" ]; then
|
||||
elog "'${dir}': No such directory"
|
||||
elog "The $1 environment variable must be set to a valid directory."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# This script requires that the LIBVPX_BIN_PATH, LIBVPX_CONFIG_PATH, and
|
||||
# LIBVPX_TEST_DATA_PATH variables are in the environment: Confirm that
|
||||
# the variables are set and that they all evaluate to directory paths.
|
||||
verify_vpx_test_environment() {
|
||||
test_env_var_dir "LIBVPX_BIN_PATH" \
|
||||
&& test_env_var_dir "LIBVPX_CONFIG_PATH" \
|
||||
&& test_env_var_dir "LIBVPX_TEST_DATA_PATH"
|
||||
}
|
||||
|
||||
# Greps vpx_config.h in LIBVPX_CONFIG_PATH for positional parameter one, which
|
||||
# should be a LIBVPX preprocessor flag. Echoes yes to stdout when the feature
|
||||
# is available.
|
||||
vpx_config_option_enabled() {
|
||||
vpx_config_option="${1}"
|
||||
vpx_config_file="${LIBVPX_CONFIG_PATH}/vpx_config.h"
|
||||
config_line=$(grep "${vpx_config_option}" "${vpx_config_file}")
|
||||
if echo "${config_line}" | egrep -q '1$'; then
|
||||
echo yes
|
||||
fi
|
||||
}
|
||||
|
||||
# Echoes yes when output of test_configuration_target() contains win32 or win64.
|
||||
is_windows_target() {
|
||||
if test_configuration_target \
|
||||
| grep -q -e win32 -e win64 > /dev/null 2>&1; then
|
||||
echo yes
|
||||
fi
|
||||
}
|
||||
|
||||
# Echoes path to $1 when it's executable and exists in ${LIBVPX_BIN_PATH}, or an
|
||||
# empty string. Caller is responsible for testing the string once the function
|
||||
# returns.
|
||||
vpx_tool_path() {
|
||||
local tool_name="$1"
|
||||
local tool_path="${LIBVPX_BIN_PATH}/${tool_name}${VPX_TEST_EXE_SUFFIX}"
|
||||
if [ ! -x "${tool_path}" ]; then
|
||||
# Try one directory up: when running via examples.sh the tool could be in
|
||||
# the parent directory of $LIBVPX_BIN_PATH.
|
||||
tool_path="${LIBVPX_BIN_PATH}/../${tool_name}${VPX_TEST_EXE_SUFFIX}"
|
||||
fi
|
||||
|
||||
if [ ! -x "${tool_path}" ]; then
|
||||
tool_path=""
|
||||
fi
|
||||
echo "${tool_path}"
|
||||
}
|
||||
|
||||
# Echoes yes to stdout when the file named by positional parameter one exists
|
||||
# in LIBVPX_BIN_PATH, and is executable.
|
||||
vpx_tool_available() {
|
||||
local tool_name="$1"
|
||||
local tool="${LIBVPX_BIN_PATH}/${tool_name}${VPX_TEST_EXE_SUFFIX}"
|
||||
[ -x "${tool}" ] && echo yes
|
||||
}
|
||||
|
||||
# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
|
||||
# CONFIG_VP8_DECODER.
|
||||
vp8_decode_available() {
|
||||
[ "$(vpx_config_option_enabled CONFIG_VP8_DECODER)" = "yes" ] && echo yes
|
||||
}
|
||||
|
||||
# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
|
||||
# CONFIG_VP8_ENCODER.
|
||||
vp8_encode_available() {
|
||||
[ "$(vpx_config_option_enabled CONFIG_VP8_ENCODER)" = "yes" ] && echo yes
|
||||
}
|
||||
|
||||
# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
|
||||
# CONFIG_VP9_DECODER.
|
||||
vp9_decode_available() {
|
||||
[ "$(vpx_config_option_enabled CONFIG_VP9_DECODER)" = "yes" ] && echo yes
|
||||
}
|
||||
|
||||
# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
|
||||
# CONFIG_VP9_ENCODER.
|
||||
vp9_encode_available() {
|
||||
[ "$(vpx_config_option_enabled CONFIG_VP9_ENCODER)" = "yes" ] && echo yes
|
||||
}
|
||||
|
||||
# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
|
||||
# CONFIG_WEBM_IO.
|
||||
webm_io_available() {
|
||||
[ "$(vpx_config_option_enabled CONFIG_WEBM_IO)" = "yes" ] && echo yes
|
||||
}
|
||||
|
||||
# Filters strings from $1 using the filter specified by $2. Filter behavior
|
||||
# depends on the presence of $3. When $3 is present, strings that match the
|
||||
# filter are excluded. When $3 is omitted, strings matching the filter are
|
||||
# included.
|
||||
# The filtered result is echoed to stdout.
|
||||
filter_strings() {
|
||||
strings=${1}
|
||||
filter=${2}
|
||||
exclude=${3}
|
||||
|
||||
if [ -n "${exclude}" ]; then
|
||||
# When positional parameter three exists the caller wants to remove strings.
|
||||
# Tell grep to invert matches using the -v argument.
|
||||
exclude='-v'
|
||||
else
|
||||
unset exclude
|
||||
fi
|
||||
|
||||
if [ -n "${filter}" ]; then
|
||||
for s in ${strings}; do
|
||||
if echo "${s}" | egrep -q ${exclude} "${filter}" > /dev/null 2>&1; then
|
||||
filtered_strings="${filtered_strings} ${s}"
|
||||
fi
|
||||
done
|
||||
else
|
||||
filtered_strings="${strings}"
|
||||
fi
|
||||
echo "${filtered_strings}"
|
||||
}
|
||||
|
||||
# Runs user test functions passed via positional parameters one and two.
|
||||
# Functions in positional parameter one are treated as environment verification
|
||||
# functions and are run unconditionally. Functions in positional parameter two
|
||||
# are run according to the rules specified in vpx_test_usage().
|
||||
run_tests() {
|
||||
local env_tests="verify_vpx_test_environment $1"
|
||||
local tests_to_filter="$2"
|
||||
local test_name="${VPX_TEST_NAME}"
|
||||
|
||||
if [ -z "${test_name}" ]; then
|
||||
test_name="$(basename "${0%.*}")"
|
||||
fi
|
||||
|
||||
if [ "${VPX_TEST_RUN_DISABLED_TESTS}" != "yes" ]; then
|
||||
# Filter out DISABLED tests.
|
||||
tests_to_filter=$(filter_strings "${tests_to_filter}" ^DISABLED exclude)
|
||||
fi
|
||||
|
||||
if [ -n "${VPX_TEST_FILTER}" ]; then
|
||||
# Remove tests not matching the user's filter.
|
||||
tests_to_filter=$(filter_strings "${tests_to_filter}" ${VPX_TEST_FILTER})
|
||||
fi
|
||||
|
||||
# User requested test listing: Dump test names and return.
|
||||
if [ "${VPX_TEST_LIST_TESTS}" = "yes" ]; then
|
||||
for test_name in $tests_to_filter; do
|
||||
echo ${test_name}
|
||||
done
|
||||
return
|
||||
fi
|
||||
|
||||
# Don't bother with the environment tests if everything else was disabled.
|
||||
[ -z "${tests_to_filter}" ] && return
|
||||
|
||||
# Combine environment and actual tests.
|
||||
local tests_to_run="${env_tests} ${tests_to_filter}"
|
||||
|
||||
check_git_hashes
|
||||
|
||||
# Run tests.
|
||||
for test in ${tests_to_run}; do
|
||||
test_begin "${test}"
|
||||
vlog " RUN ${test}"
|
||||
"${test}"
|
||||
vlog " PASS ${test}"
|
||||
test_end "${test}"
|
||||
done
|
||||
|
||||
local tested_config="$(test_configuration_target) @ $(current_hash)"
|
||||
echo "${test_name}: Done, all tests pass for ${tested_config}."
|
||||
}
|
||||
|
||||
vpx_test_usage() {
|
||||
cat << EOF
|
||||
Usage: ${0##*/} [arguments]
|
||||
--bin-path <path to libvpx binaries directory>
|
||||
--config-path <path to libvpx config directory>
|
||||
--filter <filter>: User test filter. Only tests matching filter are run.
|
||||
--run-disabled-tests: Run disabled tests.
|
||||
--help: Display this message and exit.
|
||||
--test-data-path <path to libvpx test data directory>
|
||||
--show-program-output: Shows output from all programs being tested.
|
||||
--prefix: Allows for a user specified prefix to be inserted before all test
|
||||
programs. Grants the ability, for example, to run test programs
|
||||
within valgrind.
|
||||
--list-tests: List all test names and exit without actually running tests.
|
||||
--verbose: Verbose output.
|
||||
|
||||
When the --bin-path option is not specified the script attempts to use
|
||||
\$LIBVPX_BIN_PATH and then the current directory.
|
||||
|
||||
When the --config-path option is not specified the script attempts to use
|
||||
\$LIBVPX_CONFIG_PATH and then the current directory.
|
||||
|
||||
When the -test-data-path option is not specified the script attempts to use
|
||||
\$LIBVPX_TEST_DATA_PATH and then the current directory.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Returns non-zero (failure) when required environment variables are empty
|
||||
# strings.
|
||||
vpx_test_check_environment() {
|
||||
if [ -z "${LIBVPX_BIN_PATH}" ] || \
|
||||
[ -z "${LIBVPX_CONFIG_PATH}" ] || \
|
||||
[ -z "${LIBVPX_TEST_DATA_PATH}" ]; then
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Parse the command line.
|
||||
while [ -n "$1" ]; do
|
||||
case "$1" in
|
||||
--bin-path)
|
||||
LIBVPX_BIN_PATH="$2"
|
||||
shift
|
||||
;;
|
||||
--config-path)
|
||||
LIBVPX_CONFIG_PATH="$2"
|
||||
shift
|
||||
;;
|
||||
--filter)
|
||||
VPX_TEST_FILTER="$2"
|
||||
shift
|
||||
;;
|
||||
--run-disabled-tests)
|
||||
VPX_TEST_RUN_DISABLED_TESTS=yes
|
||||
;;
|
||||
--help)
|
||||
vpx_test_usage
|
||||
exit
|
||||
;;
|
||||
--test-data-path)
|
||||
LIBVPX_TEST_DATA_PATH="$2"
|
||||
shift
|
||||
;;
|
||||
--prefix)
|
||||
VPX_TEST_PREFIX="$2"
|
||||
shift
|
||||
;;
|
||||
--verbose)
|
||||
VPX_TEST_VERBOSE_OUTPUT=yes
|
||||
;;
|
||||
--show-program-output)
|
||||
devnull=
|
||||
;;
|
||||
--list-tests)
|
||||
VPX_TEST_LIST_TESTS=yes
|
||||
;;
|
||||
*)
|
||||
vpx_test_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Handle running the tests from a build directory without arguments when running
|
||||
# the tests on *nix/macosx.
|
||||
LIBVPX_BIN_PATH="${LIBVPX_BIN_PATH:-.}"
|
||||
LIBVPX_CONFIG_PATH="${LIBVPX_CONFIG_PATH:-.}"
|
||||
LIBVPX_TEST_DATA_PATH="${LIBVPX_TEST_DATA_PATH:-.}"
|
||||
|
||||
# Create a temporary directory for output files, and a trap to clean it up.
|
||||
if [ -n "${TMPDIR}" ]; then
|
||||
VPX_TEST_TEMP_ROOT="${TMPDIR}"
|
||||
elif [ -n "${TEMPDIR}" ]; then
|
||||
VPX_TEST_TEMP_ROOT="${TEMPDIR}"
|
||||
else
|
||||
VPX_TEST_TEMP_ROOT=/tmp
|
||||
fi
|
||||
|
||||
VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_$$"
|
||||
|
||||
if ! mkdir -p "${VPX_TEST_OUTPUT_DIR}" || \
|
||||
[ ! -d "${VPX_TEST_OUTPUT_DIR}" ]; then
|
||||
echo "${0##*/}: Cannot create output directory, giving up."
|
||||
echo "${0##*/}: VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$(is_windows_target)" = "yes" ]; then
|
||||
VPX_TEST_EXE_SUFFIX=".exe"
|
||||
fi
|
||||
|
||||
# Variables shared by tests.
|
||||
VP8_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp80-00-comprehensive-001.ivf"
|
||||
VP9_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-09-subpixel-00.ivf"
|
||||
|
||||
VP9_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-00-quantizer-00.webm"
|
||||
VP9_FPM_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-07-frame_parallel-1.webm"
|
||||
VP9_LT_50_FRAMES_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-02-size-32x08.webm"
|
||||
|
||||
VP9_RAW_FILE="${LIBVPX_TEST_DATA_PATH}/crbug-1539.rawfile"
|
||||
|
||||
YUV_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/hantro_collage_w352h288.yuv"
|
||||
YUV_RAW_INPUT_WIDTH=352
|
||||
YUV_RAW_INPUT_HEIGHT=288
|
||||
|
||||
Y4M_NOSQ_PAR_INPUT="${LIBVPX_TEST_DATA_PATH}/park_joy_90p_8_420_a10-1.y4m"
|
||||
Y4M_720P_INPUT="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.y4m"
|
||||
Y4M_720P_INPUT_WIDTH=1280
|
||||
Y4M_720P_INPUT_HEIGHT=720
|
||||
|
||||
# Setup a trap function to clean up after tests complete.
|
||||
trap cleanup EXIT
|
||||
|
||||
vlog "$(basename "${0%.*}") test configuration:
|
||||
LIBVPX_BIN_PATH=${LIBVPX_BIN_PATH}
|
||||
LIBVPX_CONFIG_PATH=${LIBVPX_CONFIG_PATH}
|
||||
LIBVPX_TEST_DATA_PATH=${LIBVPX_TEST_DATA_PATH}
|
||||
VP8_IVF_FILE=${VP8_IVF_FILE}
|
||||
VP9_IVF_FILE=${VP9_IVF_FILE}
|
||||
VP9_WEBM_FILE=${VP9_WEBM_FILE}
|
||||
VPX_TEST_EXE_SUFFIX=${VPX_TEST_EXE_SUFFIX}
|
||||
VPX_TEST_FILTER=${VPX_TEST_FILTER}
|
||||
VPX_TEST_LIST_TESTS=${VPX_TEST_LIST_TESTS}
|
||||
VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}
|
||||
VPX_TEST_PREFIX=${VPX_TEST_PREFIX}
|
||||
VPX_TEST_RUN_DISABLED_TESTS=${VPX_TEST_RUN_DISABLED_TESTS}
|
||||
VPX_TEST_SHOW_PROGRAM_OUTPUT=${VPX_TEST_SHOW_PROGRAM_OUTPUT}
|
||||
VPX_TEST_TEMP_ROOT=${VPX_TEST_TEMP_ROOT}
|
||||
VPX_TEST_VERBOSE_OUTPUT=${VPX_TEST_VERBOSE_OUTPUT}
|
||||
YUV_RAW_INPUT=${YUV_RAW_INPUT}
|
||||
YUV_RAW_INPUT_WIDTH=${YUV_RAW_INPUT_WIDTH}
|
||||
YUV_RAW_INPUT_HEIGHT=${YUV_RAW_INPUT_HEIGHT}
|
||||
Y4M_NOSQ_PAR_INPUT=${Y4M_NOSQ_PAR_INPUT}"
|
||||
|
||||
fi # End $VPX_TEST_TOOLS_COMMON_SH pseudo include guard.
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## Copyright (c) 2014 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.
|
||||
##
|
||||
## This file tests the libvpx twopass_encoder example. To add new tests to this
|
||||
## file, do the following:
|
||||
## 1. Write a shell function (this is your test).
|
||||
## 2. Add the function to twopass_encoder_tests (on a new line).
|
||||
##
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
# Environment check: $YUV_RAW_INPUT is required.
|
||||
twopass_encoder_verify_environment() {
|
||||
if [ ! -e "${YUV_RAW_INPUT}" ]; then
|
||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Runs twopass_encoder using the codec specified by $1 with a frame limit of
|
||||
# 100.
|
||||
twopass_encoder() {
|
||||
local encoder="${LIBVPX_BIN_PATH}/twopass_encoder${VPX_TEST_EXE_SUFFIX}"
|
||||
local codec="$1"
|
||||
local output_file="${VPX_TEST_OUTPUT_DIR}/twopass_encoder_${codec}.ivf"
|
||||
|
||||
if [ ! -x "${encoder}" ]; then
|
||||
elog "${encoder} does not exist or is not executable."
|
||||
return 1
|
||||
fi
|
||||
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 100 \
|
||||
${devnull}
|
||||
|
||||
[ -e "${output_file}" ] || return 1
|
||||
}
|
||||
|
||||
twopass_encoder_vp8() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
twopass_encoder vp8 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
twopass_encoder_vp9() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
twopass_encoder vp9 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" != "yes" ]; then
|
||||
twopass_encoder_tests="twopass_encoder_vp8
|
||||
twopass_encoder_vp9"
|
||||
|
||||
run_tests twopass_encoder_verify_environment "${twopass_encoder_tests}"
|
||||
fi
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/util.h"
|
||||
#if CONFIG_WEBM_IO
|
||||
#include "test/webm_video_source.h"
|
||||
#endif
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx/vp8.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using std::string;
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
|
||||
void CheckUserPrivateData(void *user_priv, int *target) {
|
||||
// actual pointer value should be the same as expected.
|
||||
EXPECT_EQ(reinterpret_cast<void *>(target), user_priv)
|
||||
<< "user_priv pointer value does not match.";
|
||||
}
|
||||
|
||||
// Decodes |filename|. Passes in user_priv data when calling DecodeFrame and
|
||||
// compares the user_priv from return img with the original user_priv to see if
|
||||
// they match. Both the pointer values and the values inside the addresses
|
||||
// should match.
|
||||
string DecodeFile(const string &filename) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
libvpx_test::WebMVideoSource video(filename);
|
||||
video.Init();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
libvpx_test::VP9Decoder decoder(cfg, 0);
|
||||
|
||||
libvpx_test::MD5 md5;
|
||||
int frame_num = 0;
|
||||
for (video.Begin(); !::testing::Test::HasFailure() && video.cxdata();
|
||||
video.Next()) {
|
||||
void *user_priv = reinterpret_cast<void *>(&frame_num);
|
||||
const vpx_codec_err_t res =
|
||||
decoder.DecodeFrame(video.cxdata(), video.frame_size(),
|
||||
(frame_num == 0) ? NULL : user_priv);
|
||||
if (res != VPX_CODEC_OK) {
|
||||
EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
break;
|
||||
}
|
||||
libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
|
||||
const vpx_image_t *img = NULL;
|
||||
|
||||
// Get decompressed data.
|
||||
while ((img = dec_iter.Next())) {
|
||||
if (frame_num == 0) {
|
||||
CheckUserPrivateData(img->user_priv, NULL);
|
||||
} else {
|
||||
CheckUserPrivateData(img->user_priv, &frame_num);
|
||||
|
||||
// Also test ctrl_get_reference api.
|
||||
struct vp9_ref_frame ref = vp9_ref_frame();
|
||||
// Randomly fetch a reference frame.
|
||||
ref.idx = rnd.Rand8() % 3;
|
||||
decoder.Control(VP9_GET_REFERENCE, &ref);
|
||||
|
||||
CheckUserPrivateData(ref.img.user_priv, NULL);
|
||||
}
|
||||
md5.Add(img);
|
||||
}
|
||||
|
||||
frame_num++;
|
||||
}
|
||||
return string(md5.Get());
|
||||
}
|
||||
|
||||
TEST(UserPrivTest, VideoDecode) {
|
||||
// no tiles or frame parallel; this exercises the decoding to test the
|
||||
// user_priv.
|
||||
EXPECT_STREQ("b35a1b707b28e82be025d960aba039bc",
|
||||
DecodeFile("vp90-2-03-size-226x226.webm").c_str());
|
||||
}
|
||||
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 VPX_TEST_UTIL_H_
|
||||
#define VPX_TEST_UTIL_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "vpx/vpx_image.h"
|
||||
|
||||
// Macros
|
||||
#define GET_PARAM(k) std::get<k>(GetParam())
|
||||
|
||||
inline double compute_psnr(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||
assert((img1->fmt == img2->fmt) && (img1->d_w == img2->d_w) &&
|
||||
(img1->d_h == img2->d_h));
|
||||
|
||||
const unsigned int width_y = img1->d_w;
|
||||
const unsigned int height_y = img1->d_h;
|
||||
unsigned int i, j;
|
||||
|
||||
int64_t sqrerr = 0;
|
||||
for (i = 0; i < height_y; ++i) {
|
||||
for (j = 0; j < width_y; ++j) {
|
||||
int64_t d = img1->planes[VPX_PLANE_Y][i * img1->stride[VPX_PLANE_Y] + j] -
|
||||
img2->planes[VPX_PLANE_Y][i * img2->stride[VPX_PLANE_Y] + j];
|
||||
sqrerr += d * d;
|
||||
}
|
||||
}
|
||||
double mse = static_cast<double>(sqrerr) / (width_y * height_y);
|
||||
double psnr = 100.0;
|
||||
if (mse > 0.0) {
|
||||
psnr = 10 * log10(255.0 * 255.0 / mse);
|
||||
}
|
||||
return psnr;
|
||||
}
|
||||
|
||||
#endif // VPX_TEST_UTIL_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* 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 VPX_TEST_VIDEO_SOURCE_H_
|
||||
#define VPX_TEST_VIDEO_SOURCE_H_
|
||||
|
||||
#if defined(_WIN32)
|
||||
#undef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include "test/acm_random.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
// Helper macros to ensure LIBVPX_TEST_DATA_PATH is a quoted string.
|
||||
// These are undefined right below GetDataPath
|
||||
// NOTE: LIBVPX_TEST_DATA_PATH MUST NOT be a quoted string before
|
||||
// Stringification or the GetDataPath will fail at runtime
|
||||
#define TO_STRING(S) #S
|
||||
#define STRINGIFY(S) TO_STRING(S)
|
||||
|
||||
// A simple function to encapsulate cross platform retrieval of test data path
|
||||
static std::string GetDataPath() {
|
||||
const char *const data_path = getenv("LIBVPX_TEST_DATA_PATH");
|
||||
if (data_path == NULL) {
|
||||
#ifdef LIBVPX_TEST_DATA_PATH
|
||||
// In some environments, we cannot set environment variables
|
||||
// Instead, we set the data path by using a preprocessor symbol
|
||||
// which can be set from make files
|
||||
return STRINGIFY(LIBVPX_TEST_DATA_PATH);
|
||||
#else
|
||||
return ".";
|
||||
#endif
|
||||
}
|
||||
return data_path;
|
||||
}
|
||||
|
||||
// Undefining stringification macros because they are not used elsewhere
|
||||
#undef TO_STRING
|
||||
#undef STRINGIFY
|
||||
|
||||
inline FILE *OpenTestDataFile(const std::string &file_name) {
|
||||
const std::string path_to_source = GetDataPath() + "/" + file_name;
|
||||
return fopen(path_to_source.c_str(), "rb");
|
||||
}
|
||||
|
||||
static FILE *GetTempOutFile(std::string *file_name) {
|
||||
file_name->clear();
|
||||
#if defined(_WIN32)
|
||||
char fname[MAX_PATH];
|
||||
char tmppath[MAX_PATH];
|
||||
if (GetTempPathA(MAX_PATH, tmppath)) {
|
||||
// Assume for now that the filename generated is unique per process
|
||||
if (GetTempFileNameA(tmppath, "lvx", 0, fname)) {
|
||||
file_name->assign(fname);
|
||||
return fopen(fname, "wb+");
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
#else
|
||||
return tmpfile();
|
||||
#endif
|
||||
}
|
||||
|
||||
class TempOutFile {
|
||||
public:
|
||||
TempOutFile() { file_ = GetTempOutFile(&file_name_); }
|
||||
~TempOutFile() {
|
||||
CloseFile();
|
||||
if (!file_name_.empty()) {
|
||||
EXPECT_EQ(0, remove(file_name_.c_str()));
|
||||
}
|
||||
}
|
||||
FILE *file() { return file_; }
|
||||
const std::string &file_name() { return file_name_; }
|
||||
|
||||
protected:
|
||||
void CloseFile() {
|
||||
if (file_) {
|
||||
fclose(file_);
|
||||
file_ = NULL;
|
||||
}
|
||||
}
|
||||
FILE *file_;
|
||||
std::string file_name_;
|
||||
};
|
||||
|
||||
// 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;
|
||||
|
||||
// Get the current file limit.
|
||||
virtual unsigned int limit() const = 0;
|
||||
};
|
||||
|
||||
class DummyVideoSource : public VideoSource {
|
||||
public:
|
||||
DummyVideoSource()
|
||||
: img_(NULL), limit_(100), width_(80), height_(64),
|
||||
format_(VPX_IMG_FMT_I420) {
|
||||
ReallocImage();
|
||||
}
|
||||
|
||||
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_; }
|
||||
|
||||
virtual unsigned int limit() const { return limit_; }
|
||||
|
||||
void set_limit(unsigned int limit) { limit_ = limit; }
|
||||
|
||||
void SetSize(unsigned int width, unsigned int height) {
|
||||
if (width != width_ || height != height_) {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
ReallocImage();
|
||||
}
|
||||
}
|
||||
|
||||
void SetImageFormat(vpx_img_fmt_t format) {
|
||||
if (format_ != format) {
|
||||
format_ = format;
|
||||
ReallocImage();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void FillFrame() {
|
||||
if (img_) memset(img_->img_data, 0, raw_sz_);
|
||||
}
|
||||
|
||||
void ReallocImage() {
|
||||
vpx_img_free(img_);
|
||||
img_ = vpx_img_alloc(NULL, format_, width_, height_, 32);
|
||||
raw_sz_ = ((img_->w + 31) & ~31) * img_->h * img_->bps / 8;
|
||||
}
|
||||
|
||||
vpx_image_t *img_;
|
||||
size_t raw_sz_;
|
||||
unsigned int limit_;
|
||||
unsigned int frame_;
|
||||
unsigned int width_;
|
||||
unsigned int height_;
|
||||
vpx_img_fmt_t format_;
|
||||
};
|
||||
|
||||
class RandomVideoSource : public DummyVideoSource {
|
||||
public:
|
||||
RandomVideoSource(int seed = ACMRandom::DeterministicSeed())
|
||||
: rnd_(seed), seed_(seed) {}
|
||||
|
||||
protected:
|
||||
// Reset the RNG to get a matching stream for the second pass
|
||||
virtual void Begin() {
|
||||
frame_ = 0;
|
||||
rnd_.Reset(seed_);
|
||||
FillFrame();
|
||||
}
|
||||
|
||||
// 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 (img_) {
|
||||
if (frame_ % 30 < 15) {
|
||||
for (size_t i = 0; i < raw_sz_; ++i) img_->img_data[i] = rnd_.Rand8();
|
||||
} else {
|
||||
memset(img_->img_data, 0, raw_sz_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ACMRandom rnd_;
|
||||
int seed_;
|
||||
};
|
||||
|
||||
// Abstract base class for test video sources, which provide a stream of
|
||||
// decompressed images to the decoder.
|
||||
class CompressedVideoSource {
|
||||
public:
|
||||
virtual ~CompressedVideoSource() {}
|
||||
|
||||
virtual void Init() = 0;
|
||||
|
||||
// Prepare the stream for reading, rewind/open as necessary.
|
||||
virtual void Begin() = 0;
|
||||
|
||||
// Advance the cursor to the next frame
|
||||
virtual void Next() = 0;
|
||||
|
||||
virtual const uint8_t *cxdata() const = 0;
|
||||
|
||||
virtual size_t frame_size() const = 0;
|
||||
|
||||
virtual unsigned int frame_number() const = 0;
|
||||
};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // VPX_TEST_VIDEO_SOURCE_H_
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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 <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "vp8/decoder/dboolhuff.h"
|
||||
#include "vp8/encoder/boolhuff.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
namespace {
|
||||
const int num_tests = 10;
|
||||
|
||||
// In a real use the 'decrypt_state' parameter will be a pointer to a struct
|
||||
// with whatever internal state the decryptor uses. For testing we'll just
|
||||
// xor with a constant key, and decrypt_state will point to the start of
|
||||
// the original buffer.
|
||||
const uint8_t secret_key[16] = {
|
||||
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
|
||||
0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0
|
||||
};
|
||||
|
||||
void encrypt_buffer(uint8_t *buffer, size_t size) {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
buffer[i] ^= secret_key[i & 15];
|
||||
}
|
||||
}
|
||||
|
||||
void test_decrypt_cb(void *decrypt_state, const uint8_t *input, uint8_t *output,
|
||||
int count) {
|
||||
const size_t offset = input - reinterpret_cast<uint8_t *>(decrypt_state);
|
||||
for (int i = 0; i < count; i++) {
|
||||
output[i] = input[i] ^ secret_key[(offset + i) & 15];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
TEST(VP8, TestBitIO) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
for (int n = 0; n < num_tests; ++n) {
|
||||
for (int method = 0; method <= 7; ++method) { // we generate various proba
|
||||
const int kBitsToTest = 1000;
|
||||
uint8_t probas[kBitsToTest];
|
||||
|
||||
for (int i = 0; i < kBitsToTest; ++i) {
|
||||
const int parity = i & 1;
|
||||
/* clang-format off */
|
||||
probas[i] =
|
||||
(method == 0) ? 0 : (method == 1) ? 255 :
|
||||
(method == 2) ? 128 :
|
||||
(method == 3) ? rnd.Rand8() :
|
||||
(method == 4) ? (parity ? 0 : 255) :
|
||||
// alternate between low and high proba:
|
||||
(method == 5) ? (parity ? rnd(128) : 255 - rnd(128)) :
|
||||
(method == 6) ?
|
||||
(parity ? rnd(64) : 255 - rnd(64)) :
|
||||
(parity ? rnd(32) : 255 - rnd(32));
|
||||
/* clang-format on */
|
||||
}
|
||||
for (int bit_method = 0; bit_method <= 3; ++bit_method) {
|
||||
const int random_seed = 6432;
|
||||
const int kBufferSize = 10000;
|
||||
ACMRandom bit_rnd(random_seed);
|
||||
BOOL_CODER bw;
|
||||
uint8_t bw_buffer[kBufferSize];
|
||||
vp8_start_encode(&bw, bw_buffer, bw_buffer + kBufferSize);
|
||||
|
||||
int bit = (bit_method == 0) ? 0 : (bit_method == 1) ? 1 : 0;
|
||||
for (int i = 0; i < kBitsToTest; ++i) {
|
||||
if (bit_method == 2) {
|
||||
bit = (i & 1);
|
||||
} else if (bit_method == 3) {
|
||||
bit = bit_rnd(2);
|
||||
}
|
||||
vp8_encode_bool(&bw, bit, static_cast<int>(probas[i]));
|
||||
}
|
||||
|
||||
vp8_stop_encode(&bw);
|
||||
// vp8dx_bool_decoder_fill() may read into uninitialized data that
|
||||
// isn't used meaningfully, but may trigger an MSan warning.
|
||||
memset(bw_buffer + bw.pos, 0, sizeof(VP8_BD_VALUE) - 1);
|
||||
|
||||
BOOL_DECODER br;
|
||||
encrypt_buffer(bw_buffer, kBufferSize);
|
||||
vp8dx_start_decode(&br, bw_buffer, kBufferSize, test_decrypt_cb,
|
||||
reinterpret_cast<void *>(bw_buffer));
|
||||
bit_rnd.Reset(random_seed);
|
||||
for (int i = 0; i < kBitsToTest; ++i) {
|
||||
if (bit_method == 2) {
|
||||
bit = (i & 1);
|
||||
} else if (bit_method == 3) {
|
||||
bit = bit_rnd(2);
|
||||
}
|
||||
GTEST_ASSERT_EQ(vp8dx_decode_bool(&br, probas[i]), bit)
|
||||
<< "pos: " << i << " / " << kBitsToTest
|
||||
<< " bit_method: " << bit_method << " method: " << method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* 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 "./vpx_config.h"
|
||||
#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"
|
||||
#include "test/y4m_video_source.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class DatarateTestLarge
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
public:
|
||||
DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
|
||||
|
||||
virtual ~DatarateTestLarge() {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
set_cpu_used_ = GET_PARAM(2);
|
||||
ResetModel();
|
||||
}
|
||||
|
||||
virtual void ResetModel() {
|
||||
last_pts_ = 0;
|
||||
bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
|
||||
frame_number_ = 0;
|
||||
first_drop_ = 0;
|
||||
bits_total_ = 0;
|
||||
duration_ = 0.0;
|
||||
denoiser_offon_test_ = 0;
|
||||
denoiser_offon_period_ = -1;
|
||||
gf_boost_ = 0;
|
||||
use_roi_ = false;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_);
|
||||
}
|
||||
|
||||
if (use_roi_) {
|
||||
encoder->Control(VP8E_SET_ROI_MAP, &roi_);
|
||||
}
|
||||
|
||||
if (denoiser_offon_test_) {
|
||||
ASSERT_GT(denoiser_offon_period_, 0)
|
||||
<< "denoiser_offon_period_ is not positive.";
|
||||
if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
|
||||
// Flip denoiser_on_ periodically
|
||||
denoiser_on_ ^= 1;
|
||||
}
|
||||
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
}
|
||||
|
||||
const vpx_rational_t tb = video->timebase();
|
||||
timebase_ = static_cast<double>(tb.num) / tb.den;
|
||||
duration_ = 0;
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
// Time since last timestamp = duration.
|
||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
||||
|
||||
// TODO(jimbankoski): Remove these lines when the issue:
|
||||
// http://code.google.com/p/webm/issues/detail?id=496 is fixed.
|
||||
// For now the codec assumes buffer starts at starting buffer rate
|
||||
// plus one frame's time.
|
||||
if (last_pts_ == 0) duration = 1;
|
||||
|
||||
// Add to the buffer the bits we'd expect from a constant bitrate server.
|
||||
bits_in_buffer_model_ += static_cast<int64_t>(
|
||||
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
|
||||
|
||||
/* Test the buffer model here before subtracting the frame. Do so because
|
||||
* the way the leaky bucket model works in libvpx is to allow the buffer to
|
||||
* empty - and then stop showing frames until we've got enough bits to
|
||||
* show one. As noted in comment below (issue 495), this does not currently
|
||||
* apply to key frames. For now exclude key frames in condition below. */
|
||||
const bool key_frame =
|
||||
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
|
||||
if (!key_frame) {
|
||||
ASSERT_GE(bits_in_buffer_model_, 0)
|
||||
<< "Buffer Underrun at frame " << pkt->data.frame.pts;
|
||||
}
|
||||
|
||||
const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
|
||||
// Subtract from the buffer the bits associated with a played back frame.
|
||||
bits_in_buffer_model_ -= frame_size_in_bits;
|
||||
|
||||
// Update the running total of bits for end of test datarate checks.
|
||||
bits_total_ += frame_size_in_bits;
|
||||
|
||||
// If first drop not set and we have a drop set it to this time.
|
||||
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
|
||||
|
||||
// Update the most recent pts.
|
||||
last_pts_ = pkt->data.frame.pts;
|
||||
|
||||
// We update this so that we can calculate the datarate minus the last
|
||||
// frame encoded in the file.
|
||||
bits_in_last_frame_ = frame_size_in_bits;
|
||||
|
||||
++frame_number_;
|
||||
}
|
||||
|
||||
virtual void EndPassHook(void) {
|
||||
if (bits_total_) {
|
||||
const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
|
||||
|
||||
duration_ = (last_pts_ + 1) * timebase_;
|
||||
|
||||
// Effective file datarate includes the time spent prebuffering.
|
||||
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 /
|
||||
(cfg_.rc_buf_initial_sz / 1000.0 + duration_);
|
||||
|
||||
file_datarate_ = file_size_in_kb / duration_;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DenoiserLevelsTest() {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
|
||||
288, 30, 1, 0, 140);
|
||||
for (int j = 1; j < 5; ++j) {
|
||||
// Run over the denoiser levels.
|
||||
// For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
|
||||
// refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
|
||||
// denoiserOnAggressive, and denoiserOnAdaptive.
|
||||
denoiser_on_ = j;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DenoiserOffOnTest() {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
|
||||
288, 30, 1, 0, 299);
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
// The denoiser is off by default.
|
||||
denoiser_on_ = 0;
|
||||
// Set the offon test flag.
|
||||
denoiser_offon_test_ = 1;
|
||||
denoiser_offon_period_ = 100;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
|
||||
virtual void BasicBufferModelTest() {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// 2 pass cbr datarate control has a bug hidden by the small # of
|
||||
// frames selected in this encode. The problem is that even if the buffer is
|
||||
// negative we produce a keyframe on a cutscene. Ignoring datarate
|
||||
// constraints
|
||||
// TODO(jimbankoski): ( Fix when issue
|
||||
// http://code.google.com/p/webm/issues/detail?id=495 is addressed. )
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
|
||||
288, 30, 1, 0, 140);
|
||||
|
||||
// There is an issue for low bitrates in real-time mode, where the
|
||||
// effective_datarate slightly overshoots the target bitrate.
|
||||
// This is same the issue as noted about (#495).
|
||||
// TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
|
||||
// when the issue is resolved.
|
||||
for (int i = 100; i < 800; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ChangingDropFrameThreshTest() {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_max_quantizer = 36;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||
|
||||
const int frame_count = 40;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
|
||||
288, 30, 1, 0, frame_count);
|
||||
|
||||
// Here we check that the first dropped frame gets earlier and earlier
|
||||
// as the drop frame threshold is increased.
|
||||
|
||||
const int kDropFrameThreshTestStep = 30;
|
||||
vpx_codec_pts_t last_drop = frame_count;
|
||||
for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
|
||||
cfg_.rc_dropframe_thresh = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_LE(first_drop_, last_drop)
|
||||
<< " The first dropped frame for drop_thresh " << i
|
||||
<< " > first dropped frame for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
last_drop = first_drop_;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DropFramesMultiThreadsTest() {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 30;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
|
||||
288, 30, 1, 0, 140);
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
|
||||
vpx_codec_pts_t last_pts_;
|
||||
int64_t bits_in_buffer_model_;
|
||||
double timebase_;
|
||||
int frame_number_;
|
||||
vpx_codec_pts_t first_drop_;
|
||||
int64_t bits_total_;
|
||||
double duration_;
|
||||
double file_datarate_;
|
||||
double effective_datarate_;
|
||||
int64_t bits_in_last_frame_;
|
||||
int denoiser_on_;
|
||||
int denoiser_offon_test_;
|
||||
int denoiser_offon_period_;
|
||||
int set_cpu_used_;
|
||||
int gf_boost_;
|
||||
bool use_roi_;
|
||||
vpx_roi_map_t roi_;
|
||||
};
|
||||
|
||||
#if CONFIG_TEMPORAL_DENOISING
|
||||
// Check basic datarate targeting, for a single bitrate, but loop over the
|
||||
// various denoiser settings.
|
||||
TEST_P(DatarateTestLarge, DenoiserLevels) { DenoiserLevelsTest(); }
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||
// and on.
|
||||
TEST_P(DatarateTestLarge, DenoiserOffOn) { DenoiserOffOnTest(); }
|
||||
#endif // CONFIG_TEMPORAL_DENOISING
|
||||
|
||||
TEST_P(DatarateTestLarge, BasicBufferModel) { BasicBufferModelTest(); }
|
||||
|
||||
TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
|
||||
ChangingDropFrameThreshTest();
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
|
||||
DropFramesMultiThreadsTest();
|
||||
}
|
||||
|
||||
class DatarateTestRealTime : public DatarateTestLarge {
|
||||
public:
|
||||
virtual ~DatarateTestRealTime() {}
|
||||
};
|
||||
|
||||
#if CONFIG_TEMPORAL_DENOISING
|
||||
// Check basic datarate targeting, for a single bitrate, but loop over the
|
||||
// various denoiser settings.
|
||||
TEST_P(DatarateTestRealTime, DenoiserLevels) { DenoiserLevelsTest(); }
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||
// and on.
|
||||
TEST_P(DatarateTestRealTime, DenoiserOffOn) {}
|
||||
#endif // CONFIG_TEMPORAL_DENOISING
|
||||
|
||||
TEST_P(DatarateTestRealTime, BasicBufferModel) { BasicBufferModelTest(); }
|
||||
|
||||
TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) {
|
||||
ChangingDropFrameThreshTest();
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
|
||||
DropFramesMultiThreadsTest();
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestRealTime, RegionOfInterest) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 450;
|
||||
cfg_.g_w = 352;
|
||||
cfg_.g_h = 288;
|
||||
|
||||
ResetModel();
|
||||
|
||||
// Set ROI parameters
|
||||
use_roi_ = true;
|
||||
memset(&roi_, 0, sizeof(roi_));
|
||||
|
||||
roi_.rows = (cfg_.g_h + 15) / 16;
|
||||
roi_.cols = (cfg_.g_w + 15) / 16;
|
||||
|
||||
roi_.delta_q[0] = 0;
|
||||
roi_.delta_q[1] = -20;
|
||||
roi_.delta_q[2] = 0;
|
||||
roi_.delta_q[3] = 0;
|
||||
|
||||
roi_.delta_lf[0] = 0;
|
||||
roi_.delta_lf[1] = -20;
|
||||
roi_.delta_lf[2] = 0;
|
||||
roi_.delta_lf[3] = 0;
|
||||
|
||||
roi_.static_threshold[0] = 0;
|
||||
roi_.static_threshold[1] = 1000;
|
||||
roi_.static_threshold[2] = 0;
|
||||
roi_.static_threshold[3] = 0;
|
||||
|
||||
// Use 2 states: 1 is center square, 0 is the rest.
|
||||
roi_.roi_map =
|
||||
(uint8_t *)calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map));
|
||||
for (unsigned int i = 0; i < roi_.rows; ++i) {
|
||||
for (unsigned int j = 0; j < roi_.cols; ++j) {
|
||||
if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) &&
|
||||
j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) {
|
||||
roi_.roi_map[i * roi_.cols + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
|
||||
free(roi_.roi_map);
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestRealTime, GFBoost) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_error_resilient = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
// Apply a gf boost.
|
||||
gf_boost_ = 50;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES,
|
||||
::testing::Values(0));
|
||||
VP8_INSTANTIATE_TEST_CASE(DatarateTestRealTime,
|
||||
::testing::Values(::libvpx_test::kRealTime),
|
||||
::testing::Values(-6, -12));
|
||||
} // namespace
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user