531 строка
22 KiB
C++
531 строка
22 KiB
C++
/*
|
|
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
|
*
|
|
* This source code is subject to the terms of the BSD 2 Clause License and
|
|
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
|
* was not distributed with this source code in the LICENSE file, you can
|
|
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
|
* Media Patent License 1.0 was not distributed with this source code in the
|
|
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
|
*/
|
|
|
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
|
|
#include "./av1_rtcd.h"
|
|
#include "./aom_dsp_rtcd.h"
|
|
#include "test/acm_random.h"
|
|
#include "av1/common/filter.h"
|
|
#include "av1/common/convolve.h"
|
|
#include "aom_dsp/aom_dsp_common.h"
|
|
#include "aom_ports/mem.h"
|
|
|
|
using libaom_test::ACMRandom;
|
|
|
|
namespace {
|
|
void setup_convolve() {
|
|
#if HAVE_SSSE3 && CONFIG_RUNTIME_CPU_DETECT
|
|
av1_convolve_horiz = av1_convolve_horiz_c;
|
|
av1_convolve_vert = av1_convolve_vert_c;
|
|
#endif
|
|
}
|
|
|
|
TEST(AV1ConvolveTest, av1_convolve8) {
|
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
#if CONFIG_DUAL_FILTER
|
|
InterpFilter interp_filter[4] = { EIGHTTAP_REGULAR, EIGHTTAP_REGULAR,
|
|
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR };
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter[0]);
|
|
#else
|
|
InterpFilter interp_filter = EIGHTTAP_REGULAR;
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter);
|
|
#endif
|
|
int filter_size = filter_params.taps;
|
|
int filter_center = filter_size / 2 - 1;
|
|
uint8_t src[12 * 12];
|
|
int src_stride = filter_size;
|
|
uint8_t dst[1] = { 0 };
|
|
uint8_t dst1[1] = { 0 };
|
|
int dst_stride = 1;
|
|
int x_step_q4 = 16;
|
|
int y_step_q4 = 16;
|
|
int subpel_x_q4 = 3;
|
|
int subpel_y_q4 = 2;
|
|
|
|
int w = 1;
|
|
int h = 1;
|
|
|
|
ConvolveParams conv_params = get_conv_params(0);
|
|
|
|
setup_convolve();
|
|
|
|
for (int i = 0; i < filter_size * filter_size; i++) {
|
|
src[i] = rnd.Rand16() % (1 << 8);
|
|
}
|
|
|
|
av1_convolve(src + src_stride * filter_center + filter_center, src_stride,
|
|
dst, dst_stride, w, h, interp_filter, subpel_x_q4, x_step_q4,
|
|
subpel_y_q4, y_step_q4, &conv_params);
|
|
|
|
const int16_t *x_filter =
|
|
av1_get_interp_filter_subpel_kernel(filter_params, subpel_x_q4);
|
|
const int16_t *y_filter =
|
|
av1_get_interp_filter_subpel_kernel(filter_params, subpel_y_q4);
|
|
|
|
aom_convolve8_c(src + src_stride * filter_center + filter_center, src_stride,
|
|
dst1, dst_stride, x_filter, 16, y_filter, 16, w, h);
|
|
EXPECT_EQ(dst[0], dst1[0]);
|
|
}
|
|
TEST(AV1ConvolveTest, av1_convolve) {
|
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
#if CONFIG_DUAL_FILTER
|
|
InterpFilter interp_filter[4] = { EIGHTTAP_REGULAR, EIGHTTAP_REGULAR,
|
|
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR };
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter[0]);
|
|
#else
|
|
InterpFilter interp_filter = EIGHTTAP_REGULAR;
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter);
|
|
#endif
|
|
int filter_size = filter_params.taps;
|
|
int filter_center = filter_size / 2 - 1;
|
|
uint8_t src[12 * 12];
|
|
int src_stride = filter_size;
|
|
uint8_t dst[1] = { 0 };
|
|
int dst_stride = 1;
|
|
int x_step_q4 = 16;
|
|
int y_step_q4 = 16;
|
|
int w = 1;
|
|
int h = 1;
|
|
|
|
int subpel_x_q4;
|
|
int subpel_y_q4;
|
|
|
|
ConvolveParams conv_params = get_conv_params(0);
|
|
|
|
ASSERT_LE(filter_size, 12);
|
|
setup_convolve();
|
|
|
|
for (int i = 0; i < static_cast<int>(sizeof(src) / sizeof(src[0])); i++) {
|
|
src[i] = rnd.Rand16() % (1 << 8);
|
|
}
|
|
|
|
for (subpel_x_q4 = 0; subpel_x_q4 < SUBPEL_SHIFTS; subpel_x_q4++) {
|
|
for (subpel_y_q4 = 0; subpel_y_q4 < SUBPEL_SHIFTS; subpel_y_q4++) {
|
|
av1_convolve(src + src_stride * filter_center + filter_center, src_stride,
|
|
dst, dst_stride, w, h, interp_filter, subpel_x_q4, x_step_q4,
|
|
subpel_y_q4, y_step_q4, &conv_params);
|
|
|
|
const int16_t *x_filter =
|
|
av1_get_interp_filter_subpel_kernel(filter_params, subpel_x_q4);
|
|
const int16_t *y_filter =
|
|
av1_get_interp_filter_subpel_kernel(filter_params, subpel_y_q4);
|
|
|
|
int temp[12];
|
|
int dst_ref = 0;
|
|
for (int r = 0; r < filter_size; r++) {
|
|
temp[r] = 0;
|
|
for (int c = 0; c < filter_size; c++) {
|
|
temp[r] += x_filter[c] * src[r * filter_size + c];
|
|
}
|
|
temp[r] = clip_pixel(ROUND_POWER_OF_TWO(temp[r], FILTER_BITS));
|
|
dst_ref += temp[r] * y_filter[r];
|
|
}
|
|
dst_ref = clip_pixel(ROUND_POWER_OF_TWO(dst_ref, FILTER_BITS));
|
|
EXPECT_EQ(dst[0], dst_ref);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if CONFIG_DUAL_FILTER
|
|
TEST(AV1ConvolveTest, av1_convolve_vert_first) {
|
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
InterpFilter interp_filter[4] = { EIGHTTAP_REGULAR, MULTITAP_SHARP,
|
|
EIGHTTAP_REGULAR, MULTITAP_SHARP };
|
|
InterpFilterParams filter_params_x =
|
|
av1_get_interp_filter_params(interp_filter[1]);
|
|
InterpFilterParams filter_params_y =
|
|
av1_get_interp_filter_params(interp_filter[0]);
|
|
int filter_size_x = filter_params_x.taps;
|
|
int filter_size_y = filter_params_y.taps;
|
|
int filter_center_x = filter_size_x / 2 - 1;
|
|
int filter_center_y = filter_size_y / 2 - 1;
|
|
uint8_t src[12 * 12];
|
|
int src_stride = filter_size_x;
|
|
uint8_t dst[1] = { 0 };
|
|
int dst_stride = 1;
|
|
int x_step_q4 = 16;
|
|
int y_step_q4 = 16;
|
|
int w = 1;
|
|
int h = 1;
|
|
|
|
int subpel_x_q4;
|
|
int subpel_y_q4;
|
|
|
|
ConvolveParams conv_params = get_conv_params(0);
|
|
|
|
ASSERT_LE(filter_size_x, 12);
|
|
ASSERT_LE(filter_size_y, 12);
|
|
setup_convolve();
|
|
|
|
for (int i = 0; i < static_cast<int>(sizeof(src) / sizeof(src[0])); i++) {
|
|
src[i] = rnd.Rand16() % (1 << 8);
|
|
}
|
|
|
|
for (subpel_x_q4 = 1; subpel_x_q4 < SUBPEL_SHIFTS; subpel_x_q4++) {
|
|
for (subpel_y_q4 = 1; subpel_y_q4 < SUBPEL_SHIFTS; subpel_y_q4++) {
|
|
av1_convolve(src + src_stride * filter_center_y + filter_center_x,
|
|
src_stride, dst, dst_stride, w, h, interp_filter,
|
|
subpel_x_q4, x_step_q4, subpel_y_q4, y_step_q4,
|
|
&conv_params);
|
|
|
|
const int16_t *x_filter =
|
|
av1_get_interp_filter_subpel_kernel(filter_params_x, subpel_x_q4);
|
|
const int16_t *y_filter =
|
|
av1_get_interp_filter_subpel_kernel(filter_params_y, subpel_y_q4);
|
|
|
|
int temp[12];
|
|
int dst_ref = 0;
|
|
for (int c = 0; c < filter_size_x; c++) {
|
|
temp[c] = 0;
|
|
for (int r = 0; r < filter_size_y; r++) {
|
|
temp[c] += y_filter[r] * src[r * filter_size_x + c];
|
|
}
|
|
temp[c] = clip_pixel(ROUND_POWER_OF_TWO(temp[c], FILTER_BITS));
|
|
dst_ref += temp[c] * x_filter[c];
|
|
}
|
|
dst_ref = clip_pixel(ROUND_POWER_OF_TWO(dst_ref, FILTER_BITS));
|
|
EXPECT_EQ(dst[0], dst_ref);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
TEST(AV1ConvolveTest, av1_convolve_avg) {
|
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
#if CONFIG_DUAL_FILTER
|
|
InterpFilter interp_filter[4] = { EIGHTTAP_REGULAR, EIGHTTAP_REGULAR,
|
|
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR };
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter[0]);
|
|
#else
|
|
InterpFilter interp_filter = EIGHTTAP_REGULAR;
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter);
|
|
#endif
|
|
int filter_size = filter_params.taps;
|
|
int filter_center = filter_size / 2 - 1;
|
|
uint8_t src0[12 * 12];
|
|
uint8_t src1[12 * 12];
|
|
int src_stride = filter_size;
|
|
uint8_t dst0[1] = { 0 };
|
|
uint8_t dst1[1] = { 0 };
|
|
uint8_t dst[1] = { 0 };
|
|
int dst_stride = 1;
|
|
int x_step_q4 = 16;
|
|
int y_step_q4 = 16;
|
|
|
|
int w = 1;
|
|
int h = 1;
|
|
|
|
int subpel_x_q4;
|
|
int subpel_y_q4;
|
|
|
|
ConvolveParams conv_params = get_conv_params(0);
|
|
|
|
setup_convolve();
|
|
|
|
for (int i = 0; i < filter_size * filter_size; i++) {
|
|
src0[i] = rnd.Rand16() % (1 << 8);
|
|
src1[i] = rnd.Rand16() % (1 << 8);
|
|
}
|
|
|
|
int offset = filter_size * filter_center + filter_center;
|
|
|
|
for (subpel_x_q4 = 0; subpel_x_q4 < SUBPEL_SHIFTS; subpel_x_q4++) {
|
|
for (subpel_y_q4 = 0; subpel_y_q4 < SUBPEL_SHIFTS; subpel_y_q4++) {
|
|
conv_params.ref = 0;
|
|
av1_convolve(src0 + offset, src_stride, dst0, dst_stride, w, h,
|
|
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
|
y_step_q4, &conv_params);
|
|
conv_params.ref = 0;
|
|
av1_convolve(src1 + offset, src_stride, dst1, dst_stride, w, h,
|
|
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
|
y_step_q4, &conv_params);
|
|
|
|
conv_params.ref = 0;
|
|
av1_convolve(src0 + offset, src_stride, dst, dst_stride, w, h,
|
|
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
|
y_step_q4, &conv_params);
|
|
conv_params.ref = 1;
|
|
av1_convolve(src1 + offset, src_stride, dst, dst_stride, w, h,
|
|
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
|
y_step_q4, &conv_params);
|
|
|
|
EXPECT_EQ(dst[0], ROUND_POWER_OF_TWO(dst0[0] + dst1[0], 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
#if CONFIG_AOM_HIGHBITDEPTH
|
|
TEST(AV1ConvolveTest, av1_highbd_convolve) {
|
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
#if CONFIG_DUAL_FILTER
|
|
InterpFilter interp_filter[4] = { EIGHTTAP_REGULAR, EIGHTTAP_REGULAR,
|
|
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR };
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter[0]);
|
|
#else
|
|
InterpFilter interp_filter = EIGHTTAP_REGULAR;
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter);
|
|
#endif
|
|
int filter_size = filter_params.taps;
|
|
int filter_center = filter_size / 2 - 1;
|
|
uint16_t src[12 * 12];
|
|
int src_stride = filter_size;
|
|
uint16_t dst[1] = { 0 };
|
|
int dst_stride = 1;
|
|
int x_step_q4 = 16;
|
|
int y_step_q4 = 16;
|
|
int avg = 0;
|
|
int bd = 10;
|
|
int w = 1;
|
|
int h = 1;
|
|
|
|
int subpel_x_q4;
|
|
int subpel_y_q4;
|
|
|
|
for (int i = 0; i < filter_size * filter_size; i++) {
|
|
src[i] = rnd.Rand16() % (1 << bd);
|
|
}
|
|
|
|
for (subpel_x_q4 = 0; subpel_x_q4 < SUBPEL_SHIFTS; subpel_x_q4++) {
|
|
for (subpel_y_q4 = 0; subpel_y_q4 < SUBPEL_SHIFTS; subpel_y_q4++) {
|
|
av1_highbd_convolve(
|
|
CONVERT_TO_BYTEPTR(src + src_stride * filter_center + filter_center),
|
|
src_stride, CONVERT_TO_BYTEPTR(dst), dst_stride, w, h, interp_filter,
|
|
subpel_x_q4, x_step_q4, subpel_y_q4, y_step_q4, avg, bd);
|
|
|
|
const int16_t *x_filter =
|
|
av1_get_interp_filter_subpel_kernel(filter_params, subpel_x_q4);
|
|
const int16_t *y_filter =
|
|
av1_get_interp_filter_subpel_kernel(filter_params, subpel_y_q4);
|
|
|
|
int temp[12];
|
|
int dst_ref = 0;
|
|
for (int r = 0; r < filter_size; r++) {
|
|
temp[r] = 0;
|
|
for (int c = 0; c < filter_size; c++) {
|
|
temp[r] += x_filter[c] * src[r * filter_size + c];
|
|
}
|
|
temp[r] =
|
|
clip_pixel_highbd(ROUND_POWER_OF_TWO(temp[r], FILTER_BITS), bd);
|
|
dst_ref += temp[r] * y_filter[r];
|
|
}
|
|
dst_ref = clip_pixel_highbd(ROUND_POWER_OF_TWO(dst_ref, FILTER_BITS), bd);
|
|
EXPECT_EQ(dst[0], dst_ref);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST(AV1ConvolveTest, av1_highbd_convolve_avg) {
|
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
#if CONFIG_DUAL_FILTER
|
|
InterpFilter interp_filter[4] = { EIGHTTAP_REGULAR, EIGHTTAP_REGULAR,
|
|
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR };
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter[0]);
|
|
#else
|
|
InterpFilter interp_filter = EIGHTTAP_REGULAR;
|
|
InterpFilterParams filter_params =
|
|
av1_get_interp_filter_params(interp_filter);
|
|
#endif
|
|
int filter_size = filter_params.taps;
|
|
int filter_center = filter_size / 2 - 1;
|
|
uint16_t src0[12 * 12];
|
|
uint16_t src1[12 * 12];
|
|
int src_stride = filter_size;
|
|
uint16_t dst0[1] = { 0 };
|
|
uint16_t dst1[1] = { 0 };
|
|
uint16_t dst[1] = { 0 };
|
|
int dst_stride = 1;
|
|
int x_step_q4 = 16;
|
|
int y_step_q4 = 16;
|
|
int avg = 0;
|
|
int bd = 10;
|
|
|
|
int w = 1;
|
|
int h = 1;
|
|
|
|
int subpel_x_q4;
|
|
int subpel_y_q4;
|
|
|
|
for (int i = 0; i < filter_size * filter_size; i++) {
|
|
src0[i] = rnd.Rand16() % (1 << bd);
|
|
src1[i] = rnd.Rand16() % (1 << bd);
|
|
}
|
|
|
|
for (subpel_x_q4 = 0; subpel_x_q4 < SUBPEL_SHIFTS; subpel_x_q4++) {
|
|
for (subpel_y_q4 = 0; subpel_y_q4 < SUBPEL_SHIFTS; subpel_y_q4++) {
|
|
int offset = filter_size * filter_center + filter_center;
|
|
|
|
avg = 0;
|
|
av1_highbd_convolve(CONVERT_TO_BYTEPTR(src0 + offset), src_stride,
|
|
CONVERT_TO_BYTEPTR(dst0), dst_stride, w, h,
|
|
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
|
y_step_q4, avg, bd);
|
|
avg = 0;
|
|
av1_highbd_convolve(CONVERT_TO_BYTEPTR(src1 + offset), src_stride,
|
|
CONVERT_TO_BYTEPTR(dst1), dst_stride, w, h,
|
|
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
|
y_step_q4, avg, bd);
|
|
|
|
avg = 0;
|
|
av1_highbd_convolve(CONVERT_TO_BYTEPTR(src0 + offset), src_stride,
|
|
CONVERT_TO_BYTEPTR(dst), dst_stride, w, h,
|
|
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
|
y_step_q4, avg, bd);
|
|
avg = 1;
|
|
av1_highbd_convolve(CONVERT_TO_BYTEPTR(src1 + offset), src_stride,
|
|
CONVERT_TO_BYTEPTR(dst), dst_stride, w, h,
|
|
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
|
y_step_q4, avg, bd);
|
|
|
|
EXPECT_EQ(dst[0], ROUND_POWER_OF_TWO(dst0[0] + dst1[0], 1));
|
|
}
|
|
}
|
|
}
|
|
#endif // CONFIG_AOM_HIGHBITDEPTH
|
|
|
|
#define CONVOLVE_SPEED_TEST 0
|
|
#if CONVOLVE_SPEED_TEST
|
|
#define highbd_convolve_speed(func, block_size, frame_size) \
|
|
TEST(AV1ConvolveTest, func##_speed_##block_size##_##frame_size) { \
|
|
ACMRandom rnd(ACMRandom::DeterministicSeed()); \
|
|
InterpFilter interp_filter = EIGHTTAP; \
|
|
InterpFilterParams filter_params = \
|
|
av1_get_interp_filter_params(interp_filter); \
|
|
int filter_size = filter_params.tap; \
|
|
int filter_center = filter_size / 2 - 1; \
|
|
DECLARE_ALIGNED(16, uint16_t, \
|
|
src[(frame_size + 7) * (frame_size + 7)]) = { 0 }; \
|
|
int src_stride = frame_size + 7; \
|
|
DECLARE_ALIGNED(16, uint16_t, dst[frame_size * frame_size]) = { 0 }; \
|
|
int dst_stride = frame_size; \
|
|
int x_step_q4 = 16; \
|
|
int y_step_q4 = 16; \
|
|
int subpel_x_q4 = 8; \
|
|
int subpel_y_q4 = 6; \
|
|
int bd = 10; \
|
|
\
|
|
int w = block_size; \
|
|
int h = block_size; \
|
|
\
|
|
const int16_t *filter_x = \
|
|
av1_get_interp_filter_kernel(filter_params, subpel_x_q4); \
|
|
const int16_t *filter_y = \
|
|
av1_get_interp_filter_kernel(filter_params, subpel_y_q4); \
|
|
\
|
|
for (int i = 0; i < src_stride * src_stride; i++) { \
|
|
src[i] = rnd.Rand16() % (1 << bd); \
|
|
} \
|
|
\
|
|
int offset = filter_center * src_stride + filter_center; \
|
|
int row_offset = 0; \
|
|
int col_offset = 0; \
|
|
for (int i = 0; i < 100000; i++) { \
|
|
int src_total_offset = offset + col_offset * src_stride + row_offset; \
|
|
int dst_total_offset = col_offset * dst_stride + row_offset; \
|
|
func(CONVERT_TO_BYTEPTR(src + src_total_offset), src_stride, \
|
|
CONVERT_TO_BYTEPTR(dst + dst_total_offset), dst_stride, filter_x, \
|
|
x_step_q4, filter_y, y_step_q4, w, h, bd); \
|
|
if (offset + w + w < frame_size) { \
|
|
row_offset += w; \
|
|
} else { \
|
|
row_offset = 0; \
|
|
col_offset += h; \
|
|
} \
|
|
if (col_offset + h >= frame_size) { \
|
|
col_offset = 0; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#define lowbd_convolve_speed(func, block_size, frame_size) \
|
|
TEST(AV1ConvolveTest, func##_speed_l_##block_size##_##frame_size) { \
|
|
ACMRandom rnd(ACMRandom::DeterministicSeed()); \
|
|
InterpFilter interp_filter = EIGHTTAP; \
|
|
InterpFilterParams filter_params = \
|
|
av1_get_interp_filter_params(interp_filter); \
|
|
int filter_size = filter_params.tap; \
|
|
int filter_center = filter_size / 2 - 1; \
|
|
DECLARE_ALIGNED(16, uint8_t, src[(frame_size + 7) * (frame_size + 7)]); \
|
|
int src_stride = frame_size + 7; \
|
|
DECLARE_ALIGNED(16, uint8_t, dst[frame_size * frame_size]); \
|
|
int dst_stride = frame_size; \
|
|
int x_step_q4 = 16; \
|
|
int y_step_q4 = 16; \
|
|
int subpel_x_q4 = 8; \
|
|
int subpel_y_q4 = 6; \
|
|
int bd = 8; \
|
|
\
|
|
int w = block_size; \
|
|
int h = block_size; \
|
|
\
|
|
const int16_t *filter_x = \
|
|
av1_get_interp_filter_kernel(filter_params, subpel_x_q4); \
|
|
const int16_t *filter_y = \
|
|
av1_get_interp_filter_kernel(filter_params, subpel_y_q4); \
|
|
\
|
|
for (int i = 0; i < src_stride * src_stride; i++) { \
|
|
src[i] = rnd.Rand16() % (1 << bd); \
|
|
} \
|
|
\
|
|
int offset = filter_center * src_stride + filter_center; \
|
|
int row_offset = 0; \
|
|
int col_offset = 0; \
|
|
for (int i = 0; i < 100000; i++) { \
|
|
func(src + offset, src_stride, dst, dst_stride, filter_x, x_step_q4, \
|
|
filter_y, y_step_q4, w, h); \
|
|
if (offset + w + w < frame_size) { \
|
|
row_offset += w; \
|
|
} else { \
|
|
row_offset = 0; \
|
|
col_offset += h; \
|
|
} \
|
|
if (col_offset + h >= frame_size) { \
|
|
col_offset = 0; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
// This experiment shows that when frame size is 64x64
|
|
// aom_highbd_convolve8_sse2 and aom_convolve8_sse2's speed are similar.
|
|
// However when frame size becomes 1024x1024
|
|
// aom_highbd_convolve8_sse2 is around 50% slower than aom_convolve8_sse2
|
|
// we think the bottleneck is from memory IO
|
|
highbd_convolve_speed(aom_highbd_convolve8_sse2, 8, 64);
|
|
highbd_convolve_speed(aom_highbd_convolve8_sse2, 16, 64);
|
|
highbd_convolve_speed(aom_highbd_convolve8_sse2, 32, 64);
|
|
highbd_convolve_speed(aom_highbd_convolve8_sse2, 64, 64);
|
|
|
|
lowbd_convolve_speed(aom_convolve8_sse2, 8, 64);
|
|
lowbd_convolve_speed(aom_convolve8_sse2, 16, 64);
|
|
lowbd_convolve_speed(aom_convolve8_sse2, 32, 64);
|
|
lowbd_convolve_speed(aom_convolve8_sse2, 64, 64);
|
|
|
|
highbd_convolve_speed(aom_highbd_convolve8_sse2, 8, 1024);
|
|
highbd_convolve_speed(aom_highbd_convolve8_sse2, 16, 1024);
|
|
highbd_convolve_speed(aom_highbd_convolve8_sse2, 32, 1024);
|
|
highbd_convolve_speed(aom_highbd_convolve8_sse2, 64, 1024);
|
|
|
|
lowbd_convolve_speed(aom_convolve8_sse2, 8, 1024);
|
|
lowbd_convolve_speed(aom_convolve8_sse2, 16, 1024);
|
|
lowbd_convolve_speed(aom_convolve8_sse2, 32, 1024);
|
|
lowbd_convolve_speed(aom_convolve8_sse2, 64, 1024);
|
|
#endif // CONVOLVE_SPEED_TEST
|
|
} // namespace
|