Commit f16387bc authored by Angie Chiang's avatar Angie Chiang

Add av1_convolve for adjustable tap size

Change-Id: I2aa0b1741a6b652d0b0269223ebca6b82bb90b05
parent 35e21505
......@@ -44,9 +44,9 @@
#define ALIGN_POWER_OF_TWO(value, n) \
(((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
#define CONVERT_TO_SHORTPTR(x) ((uint16_t *)(((uintptr_t)x) << 1))
#define CONVERT_TO_SHORTPTR(x) ((uint16_t *)(((uintptr_t)(x)) << 1))
#if CONFIG_AOM_HIGHBITDEPTH
#define CONVERT_TO_BYTEPTR(x) ((uint8_t *)(((uintptr_t)x) >> 1))
#define CONVERT_TO_BYTEPTR(x) ((uint8_t *)(((uintptr_t)(x)) >> 1))
#endif // CONFIG_AOM_HIGHBITDEPTH
#endif // AOM_PORTS_MEM_H_
......@@ -29,6 +29,8 @@ AV1_COMMON_SRCS-yes += common/entropymv.h
AV1_COMMON_SRCS-yes += common/enums.h
AV1_COMMON_SRCS-yes += common/filter.h
AV1_COMMON_SRCS-yes += common/filter.c
AV1_COMMON_SRCS-yes += common/convolve.c
AV1_COMMON_SRCS-yes += common/convolve.h
AV1_COMMON_SRCS-yes += common/idct.h
AV1_COMMON_SRCS-yes += common/idct.c
AV1_COMMON_SRCS-yes += common/av1_inv_txfm.h
......
This diff is collapsed.
#ifndef AV1_COMMON_CONVOLVE_H_
#define AV1_COMMON_CONVOLVE_H_
#include "av1/common/filter.h"
#ifdef __cplusplus
extern "C" {
#endif
void av1_convolve(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
const InterpFilter *interp_filter, const int subpel_x,
const int subpel_y, int xstep, int ystep, int avg);
#if CONFIG_AOM_HIGHBITDEPTH
void av1_highbd_convolve(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
const InterpFilter *interp_filter, const int subpel_x,
const int subpel_y, int xstep, int ystep, int avg,
int bd);
#endif // CONFIG_AOM_HIGHBITDEPTH
#ifdef __cplusplus
} // extern "C"
#endif
#endif // AV1_COMMON_AOM_CONVOLVE_H_
......@@ -18,9 +18,11 @@
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_SB_SIZE_LOG2 6
#define MAX_SB_SIZE (1 << MAX_SB_SIZE_LOG2)
#define MI_SIZE_LOG2 3
#define MI_BLOCK_SIZE_LOG2 (6 - MI_SIZE_LOG2) // 64 = 2^6
#define MI_BLOCK_SIZE_LOG2 (MAX_SB_SIZE_LOG2 - MI_SIZE_LOG2) // 64 = 2^6
#define MI_SIZE (1 << MI_SIZE_LOG2) // pixels per mi-unit
#define MI_BLOCK_SIZE (1 << MI_BLOCK_SIZE_LOG2) // mi-units per max block
......
......@@ -12,10 +12,11 @@
#ifndef AV1_COMMON_RECONINTER_H_
#define AV1_COMMON_RECONINTER_H_
#include "av1/common/filter.h"
#include "av1/common/onyxc_int.h"
#include "aom/aom_integer.h"
#include "aom_dsp/aom_filter.h"
#include "av1/common/convolve.h"
#include "av1/common/filter.h"
#include "av1/common/onyxc_int.h"
#ifdef __cplusplus
extern "C" {
......@@ -29,13 +30,18 @@ static INLINE void inter_predictor(const uint8_t *src, int src_stride,
int xs, int ys) {
InterpFilterParams interp_filter_params =
get_interp_filter_params(*interp_filter);
const int16_t *filter_x =
get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
const int16_t *filter_y =
get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
sf->predict[subpel_x != 0][subpel_y != 0][ref](
src, src_stride, dst, dst_stride, filter_x, xs, filter_y, ys, w, h);
if (interp_filter_params.taps == SUBPEL_TAPS) {
const int16_t *filter_x =
get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
const int16_t *filter_y =
get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
sf->predict[subpel_x != 0][subpel_y != 0][ref](
src, src_stride, dst, dst_stride, filter_x, xs, filter_y, ys, w, h);
} else {
av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, ref);
}
}
#if CONFIG_AOM_HIGHBITDEPTH
......@@ -48,13 +54,18 @@ static INLINE void high_inter_predictor(const uint8_t *src, int src_stride,
int xs, int ys, int bd) {
InterpFilterParams interp_filter_params =
get_interp_filter_params(*interp_filter);
const int16_t *filter_x =
get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
const int16_t *filter_y =
get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref](
src, src_stride, dst, dst_stride, filter_x, xs, filter_y, ys, w, h, bd);
if (interp_filter_params.taps == SUBPEL_TAPS) {
const int16_t *filter_x =
get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
const int16_t *filter_y =
get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref](
src, src_stride, dst, dst_stride, filter_x, xs, filter_y, ys, w, h, bd);
} else {
av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, ref, bd);
}
}
#endif // CONFIG_AOM_HIGHBITDEPTH
......
#include "third_party/googletest/src/include/gtest/gtest.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 {
TEST(AV1ConvolveTest, av1_convolve8) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
InterpFilter interp_filter = EIGHTTAP;
InterpFilterParams filter_params = get_interp_filter_params(interp_filter);
ptrdiff_t 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 avg = 0;
int w = 1;
int h = 1;
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, avg);
const int16_t* x_filter =
get_interp_filter_subpel_kernel(filter_params, subpel_x_q4);
const int16_t* y_filter =
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());
InterpFilter interp_filter = EIGHTTAP;
InterpFilterParams filter_params = get_interp_filter_params(interp_filter);
ptrdiff_t 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 avg = 0;
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 << 8);
}
for (subpel_x_q4 = 0; subpel_x_q4 < 16; subpel_x_q4++) {
for (subpel_y_q4 = 0; subpel_y_q4 < 16; 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, avg);
const int16_t* x_filter =
get_interp_filter_subpel_kernel(filter_params, subpel_x_q4);
const int16_t* y_filter =
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);
}
}
}
TEST(AV1ConvolveTest, av1_convolve_avg) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
InterpFilter interp_filter = EIGHTTAP;
InterpFilterParams filter_params = get_interp_filter_params(interp_filter);
ptrdiff_t 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 avg = 0;
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 << 8);
src1[i] = rnd.Rand16() % (1 << 8);
}
int offset = filter_size * filter_center + filter_center;
for (subpel_x_q4 = 0; subpel_x_q4 < 16; subpel_x_q4++) {
for (subpel_y_q4 = 0; subpel_y_q4 < 16; subpel_y_q4++) {
avg = 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, avg);
avg = 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, avg);
avg = 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, avg);
avg = 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, avg);
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());
InterpFilter interp_filter = EIGHTTAP;
InterpFilterParams filter_params = get_interp_filter_params(interp_filter);
ptrdiff_t 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 < 16; subpel_x_q4++) {
for (subpel_y_q4 = 0; subpel_y_q4 < 16; 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 =
get_interp_filter_subpel_kernel(filter_params, subpel_x_q4);
const int16_t* y_filter =
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());
InterpFilter interp_filter = EIGHTTAP;
InterpFilterParams filter_params = get_interp_filter_params(interp_filter);
ptrdiff_t 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 < 16; subpel_x_q4++) {
for (subpel_y_q4 = 0; subpel_y_q4 < 16; 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
} // namespace
......@@ -97,6 +97,7 @@ LIBAOM_TEST_SRCS-yes += encoder_parms_get_to_decoder.cc
endif
LIBAOM_TEST_SRCS-yes += convolve_test.cc
LIBAOM_TEST_SRCS-yes += av1_convolve_test.cc
LIBAOM_TEST_SRCS-yes += lpf_8_test.cc
LIBAOM_TEST_SRCS-yes += intrapred_test.cc
LIBAOM_TEST_SRCS-$(CONFIG_AV1_ENCODER) += dct16x16_test.cc
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment