Commit 999d2f65 authored by Debargha Mukherjee's avatar Debargha Mukherjee
Browse files

More cleanups / fixes on loop-restoration buffers

Also includes some minor renaming of macros.

Change-Id: I9493cc97c6ec9c8dae8020a05a02d6f322db9a02
parent 18885360
/*
*
* 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
......@@ -91,7 +92,9 @@ void av1_alloc_restoration_buffers(AV1_COMMON *cm) {
av1_alloc_restoration_struct(&cm->rst_info, cm->width, cm->height);
cm->rst_internal.tmpbuf =
(uint8_t *)aom_realloc(cm->rst_internal.tmpbuf, RESTORATION_TMPBUF_SIZE);
assert(cm->rst_internal.tmpbuf != NULL);
if (cm->rst_internal.tmpbuf == NULL)
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate internal tmpbuf for restoration");
}
void av1_free_restoration_buffers(AV1_COMMON *cm) {
......
......@@ -113,17 +113,17 @@ void av1_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
if (rsi->frame_restoration_type == RESTORE_WIENER) {
for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
if (rsi->wiener_info[tile_idx].level) {
rsi->wiener_info[tile_idx].vfilter[RESTORATION_HALFWIN] =
rsi->wiener_info[tile_idx].hfilter[RESTORATION_HALFWIN] =
RESTORATION_FILT_STEP;
for (i = 0; i < RESTORATION_HALFWIN; ++i) {
rsi->wiener_info[tile_idx].vfilter[RESTORATION_WIN - 1 - i] =
rsi->wiener_info[tile_idx].vfilter[WIENER_HALFWIN] =
rsi->wiener_info[tile_idx].hfilter[WIENER_HALFWIN] =
WIENER_FILT_STEP;
for (i = 0; i < WIENER_HALFWIN; ++i) {
rsi->wiener_info[tile_idx].vfilter[WIENER_WIN - 1 - i] =
rsi->wiener_info[tile_idx].vfilter[i];
rsi->wiener_info[tile_idx].hfilter[RESTORATION_WIN - 1 - i] =
rsi->wiener_info[tile_idx].hfilter[WIENER_WIN - 1 - i] =
rsi->wiener_info[tile_idx].hfilter[i];
rsi->wiener_info[tile_idx].vfilter[RESTORATION_HALFWIN] -=
rsi->wiener_info[tile_idx].vfilter[WIENER_HALFWIN] -=
2 * rsi->wiener_info[tile_idx].vfilter[i];
rsi->wiener_info[tile_idx].hfilter[RESTORATION_HALFWIN] -=
rsi->wiener_info[tile_idx].hfilter[WIENER_HALFWIN] -=
2 * rsi->wiener_info[tile_idx].hfilter[i];
}
}
......@@ -131,17 +131,17 @@ void av1_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
} else if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
if (rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
rsi->wiener_info[tile_idx].vfilter[RESTORATION_HALFWIN] =
rsi->wiener_info[tile_idx].hfilter[RESTORATION_HALFWIN] =
RESTORATION_FILT_STEP;
for (i = 0; i < RESTORATION_HALFWIN; ++i) {
rsi->wiener_info[tile_idx].vfilter[RESTORATION_WIN - 1 - i] =
rsi->wiener_info[tile_idx].vfilter[WIENER_HALFWIN] =
rsi->wiener_info[tile_idx].hfilter[WIENER_HALFWIN] =
WIENER_FILT_STEP;
for (i = 0; i < WIENER_HALFWIN; ++i) {
rsi->wiener_info[tile_idx].vfilter[WIENER_WIN - 1 - i] =
rsi->wiener_info[tile_idx].vfilter[i];
rsi->wiener_info[tile_idx].hfilter[RESTORATION_WIN - 1 - i] =
rsi->wiener_info[tile_idx].hfilter[WIENER_WIN - 1 - i] =
rsi->wiener_info[tile_idx].hfilter[i];
rsi->wiener_info[tile_idx].vfilter[RESTORATION_HALFWIN] -=
rsi->wiener_info[tile_idx].vfilter[WIENER_HALFWIN] -=
2 * rsi->wiener_info[tile_idx].vfilter[i];
rsi->wiener_info[tile_idx].hfilter[RESTORATION_HALFWIN] -=
rsi->wiener_info[tile_idx].hfilter[WIENER_HALFWIN] -=
2 * rsi->wiener_info[tile_idx].hfilter[i];
}
}
......@@ -149,21 +149,20 @@ void av1_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
}
}
// Some filters do not write the outermost RESTORATION_HALFWIN pixels,
// Some filters do not write the outermost WIENER_HALFWIN pixels,
// so copy them over explicitly.
static void copy_border(uint8_t *data, int width, int height, int stride,
uint8_t *dst, int dst_stride) {
int i;
for (i = RESTORATION_HALFWIN; i < height - RESTORATION_HALFWIN; ++i) {
memcpy(dst + i * dst_stride, data + i * stride, RESTORATION_HALFWIN);
memcpy(dst + i * dst_stride + (width - RESTORATION_HALFWIN),
data + i * stride + (width - RESTORATION_HALFWIN),
RESTORATION_HALFWIN);
for (i = WIENER_HALFWIN; i < height - WIENER_HALFWIN; ++i) {
memcpy(dst + i * dst_stride, data + i * stride, WIENER_HALFWIN);
memcpy(dst + i * dst_stride + (width - WIENER_HALFWIN),
data + i * stride + (width - WIENER_HALFWIN), WIENER_HALFWIN);
}
for (i = 0; i < RESTORATION_HALFWIN; ++i) {
for (i = 0; i < WIENER_HALFWIN; ++i) {
memcpy(dst + i * dst_stride, data + i * stride, width);
}
for (i = height - RESTORATION_HALFWIN; i < height; ++i)
for (i = height - WIENER_HALFWIN; i < height; ++i)
memcpy(dst + i * dst_stride, data + i * stride, width);
}
......@@ -172,16 +171,16 @@ static void extend_frame(uint8_t *data, int width, int height, int stride) {
int i;
for (i = 0; i < height; ++i) {
data_p = data + i * stride;
memset(data_p - RESTORATION_HALFWIN, data_p[0], RESTORATION_HALFWIN);
memset(data_p + width, data_p[width - 1], RESTORATION_HALFWIN);
memset(data_p - WIENER_HALFWIN, data_p[0], WIENER_HALFWIN);
memset(data_p + width, data_p[width - 1], WIENER_HALFWIN);
}
data_p = data - RESTORATION_HALFWIN;
for (i = -RESTORATION_HALFWIN; i < 0; ++i) {
memcpy(data_p + i * stride, data_p, width + 2 * RESTORATION_HALFWIN);
data_p = data - WIENER_HALFWIN;
for (i = -WIENER_HALFWIN; i < 0; ++i) {
memcpy(data_p + i * stride, data_p, width + 2 * WIENER_HALFWIN);
}
for (i = height; i < height + RESTORATION_HALFWIN; ++i) {
for (i = height; i < height + WIENER_HALFWIN; ++i) {
memcpy(data_p + i * stride, data_p + (height - 1) * stride,
width + 2 * RESTORATION_HALFWIN);
width + 2 * WIENER_HALFWIN);
}
}
......@@ -219,13 +218,13 @@ static void loop_wiener_filter_tile(uint8_t *data, int tile_idx, int width,
}
// TODO(david.barker): Store hfilter/vfilter as an InterpKernel
// instead of the current format. Then this can be removed.
assert(RESTORATION_WIN == SUBPEL_TAPS - 1);
for (i = 0; i < RESTORATION_WIN; ++i) {
assert(WIENER_WIN == SUBPEL_TAPS - 1);
for (i = 0; i < WIENER_WIN; ++i) {
hkernel[i] = rst->rsi->wiener_info[tile_idx].hfilter[i];
vkernel[i] = rst->rsi->wiener_info[tile_idx].vfilter[i];
}
hkernel[RESTORATION_WIN] = 0;
vkernel[RESTORATION_WIN] = 0;
hkernel[WIENER_WIN] = 0;
vkernel[WIENER_WIN] = 0;
av1_get_rest_tile_limits(tile_idx, 0, 0, rst->nhtiles, rst->nvtiles,
tile_width, tile_height, width, height, 0, 0,
&h_start, &h_end, &v_start, &v_end);
......@@ -749,17 +748,17 @@ static void loop_switchable_filter(uint8_t *data, int width, int height,
static void copy_border_highbd(uint16_t *data, int width, int height,
int stride, uint16_t *dst, int dst_stride) {
int i;
for (i = RESTORATION_HALFWIN; i < height - RESTORATION_HALFWIN; ++i) {
for (i = WIENER_HALFWIN; i < height - WIENER_HALFWIN; ++i) {
memcpy(dst + i * dst_stride, data + i * stride,
RESTORATION_HALFWIN * sizeof(*dst));
memcpy(dst + i * dst_stride + (width - RESTORATION_HALFWIN),
data + i * stride + (width - RESTORATION_HALFWIN),
RESTORATION_HALFWIN * sizeof(*dst));
WIENER_HALFWIN * sizeof(*dst));
memcpy(dst + i * dst_stride + (width - WIENER_HALFWIN),
data + i * stride + (width - WIENER_HALFWIN),
WIENER_HALFWIN * sizeof(*dst));
}
for (i = 0; i < RESTORATION_HALFWIN; ++i) {
for (i = 0; i < WIENER_HALFWIN; ++i) {
memcpy(dst + i * dst_stride, data + i * stride, width * sizeof(*dst));
}
for (i = height - RESTORATION_HALFWIN; i < height; ++i)
for (i = height - WIENER_HALFWIN; i < height; ++i)
memcpy(dst + i * dst_stride, data + i * stride, width * sizeof(*dst));
}
......@@ -769,18 +768,18 @@ static void extend_frame_highbd(uint16_t *data, int width, int height,
int i, j;
for (i = 0; i < height; ++i) {
data_p = data + i * stride;
for (j = -RESTORATION_HALFWIN; j < 0; ++j) data_p[j] = data_p[0];
for (j = width; j < width + RESTORATION_HALFWIN; ++j)
for (j = -WIENER_HALFWIN; j < 0; ++j) data_p[j] = data_p[0];
for (j = width; j < width + WIENER_HALFWIN; ++j)
data_p[j] = data_p[width - 1];
}
data_p = data - RESTORATION_HALFWIN;
for (i = -RESTORATION_HALFWIN; i < 0; ++i) {
data_p = data - WIENER_HALFWIN;
for (i = -WIENER_HALFWIN; i < 0; ++i) {
memcpy(data_p + i * stride, data_p,
(width + 2 * RESTORATION_HALFWIN) * sizeof(uint16_t));
(width + 2 * WIENER_HALFWIN) * sizeof(uint16_t));
}
for (i = height; i < height + RESTORATION_HALFWIN; ++i) {
for (i = height; i < height + WIENER_HALFWIN; ++i) {
memcpy(data_p + i * stride, data_p + (height - 1) * stride,
(width + 2 * RESTORATION_HALFWIN) * sizeof(uint16_t));
(width + 2 * WIENER_HALFWIN) * sizeof(uint16_t));
}
}
......@@ -819,13 +818,13 @@ static void loop_wiener_filter_tile_highbd(uint16_t *data, int tile_idx,
}
// TODO(david.barker): Store hfilter/vfilter as an InterpKernel
// instead of the current format. Then this can be removed.
assert(RESTORATION_WIN == SUBPEL_TAPS - 1);
for (i = 0; i < RESTORATION_WIN; ++i) {
assert(WIENER_WIN == SUBPEL_TAPS - 1);
for (i = 0; i < WIENER_WIN; ++i) {
hkernel[i] = rst->rsi->wiener_info[tile_idx].hfilter[i];
vkernel[i] = rst->rsi->wiener_info[tile_idx].vfilter[i];
}
hkernel[RESTORATION_WIN] = 0;
vkernel[RESTORATION_WIN] = 0;
hkernel[WIENER_WIN] = 0;
vkernel[WIENER_WIN] = 0;
av1_get_rest_tile_limits(tile_idx, 0, 0, rst->nhtiles, rst->nvtiles,
tile_width, tile_height, width, height, 0, 0,
&h_start, &h_end, &v_start, &v_end);
......
......@@ -65,20 +65,19 @@ extern "C" {
#define SGRPROJ_BITS (SGRPROJ_PRJ_BITS * 2 + SGRPROJ_PARAMS_BITS)
// Max of SGRPROJ_TMPBUF_SIZE and DOMAINTXFMRF_TMPBUF_SIZE
#define RESTORATION_TMPBUF_SIZE (SGRPROJ_TMPBUF_SIZE)
#define RESTORATION_HALFWIN 3
#define RESTORATION_HALFWIN1 (RESTORATION_HALFWIN + 1)
#define RESTORATION_WIN (2 * RESTORATION_HALFWIN + 1)
#define RESTORATION_WIN2 ((RESTORATION_WIN) * (RESTORATION_WIN))
#define WIENER_HALFWIN 3
#define WIENER_HALFWIN1 (WIENER_HALFWIN + 1)
#define WIENER_WIN (2 * WIENER_HALFWIN + 1)
#define WIENER_WIN2 ((WIENER_WIN) * (WIENER_WIN))
#define WIENER_TMPBUF_SIZE (0)
#define RESTORATION_FILT_BITS 7
#define RESTORATION_FILT_STEP (1 << RESTORATION_FILT_BITS)
#define WIENER_FILT_PREC_BITS 7
#define WIENER_FILT_STEP (1 << WIENER_FILT_PREC_BITS)
#define WIENER_FILT_TAP0_MINV (-5)
#define WIENER_FILT_TAP1_MINV (-23)
#define WIENER_FILT_TAP2_MINV (-16)
// Central values for the taps
#define WIENER_FILT_TAP0_MIDV (3)
#define WIENER_FILT_TAP1_MIDV (-7)
#define WIENER_FILT_TAP2_MIDV (16)
#define WIENER_FILT_TAP0_BITS 4
#define WIENER_FILT_TAP1_BITS 5
......@@ -87,16 +86,26 @@ extern "C" {
#define WIENER_FILT_BITS \
((WIENER_FILT_TAP0_BITS + WIENER_FILT_TAP1_BITS + WIENER_FILT_TAP2_BITS) * 2)
#define WIENER_FILT_TAP0_MINV \
(WIENER_FILT_TAP0_MIDV - (1 << WIENER_FILT_TAP0_BITS) / 2)
#define WIENER_FILT_TAP1_MINV \
(WIENER_FILT_TAP1_MIDV - (1 << WIENER_FILT_TAP1_BITS) / 2)
#define WIENER_FILT_TAP2_MINV \
(WIENER_FILT_TAP2_MIDV - (1 << WIENER_FILT_TAP2_BITS) / 2)
#define WIENER_FILT_TAP0_MAXV \
(WIENER_FILT_TAP0_MINV - 1 + (1 << WIENER_FILT_TAP0_BITS))
(WIENER_FILT_TAP0_MIDV - 1 + (1 << WIENER_FILT_TAP0_BITS) / 2)
#define WIENER_FILT_TAP1_MAXV \
(WIENER_FILT_TAP1_MINV - 1 + (1 << WIENER_FILT_TAP1_BITS))
(WIENER_FILT_TAP1_MIDV - 1 + (1 << WIENER_FILT_TAP1_BITS) / 2)
#define WIENER_FILT_TAP2_MAXV \
(WIENER_FILT_TAP2_MINV - 1 + (1 << WIENER_FILT_TAP2_BITS))
(WIENER_FILT_TAP2_MIDV - 1 + (1 << WIENER_FILT_TAP2_BITS) / 2)
// Max of SGRPROJ_TMPBUF_SIZE, DOMAINTXFMRF_TMPBUF_SIZE, WIENER_TMPBUF_SIZE
#define RESTORATION_TMPBUF_SIZE (SGRPROJ_TMPBUF_SIZE)
typedef struct {
int level;
int vfilter[RESTORATION_WIN], hfilter[RESTORATION_WIN];
int vfilter[WIENER_WIN], hfilter[WIENER_WIN];
} WienerInfo;
typedef struct {
......@@ -187,12 +196,12 @@ static INLINE void av1_get_rest_tile_limits(
: *v_start + subtile_height;
}
if (clamp_h) {
*h_start = AOMMAX(*h_start, RESTORATION_HALFWIN);
*h_end = AOMMIN(*h_end, im_width - RESTORATION_HALFWIN);
*h_start = AOMMAX(*h_start, clamp_h);
*h_end = AOMMIN(*h_end, im_width - clamp_h);
}
if (clamp_v) {
*v_start = AOMMAX(*v_start, RESTORATION_HALFWIN);
*v_end = AOMMIN(*v_end, im_height - RESTORATION_HALFWIN);
*v_start = AOMMAX(*v_start, clamp_v);
*v_end = AOMMIN(*v_end, im_height - clamp_v);
}
}
......
......@@ -451,9 +451,11 @@ static void dealloc_compressor_data(AV1_COMP *cpi) {
aom_free_frame_buffer(&cpi->last_frame_uf);
#if CONFIG_LOOP_RESTORATION
aom_free_frame_buffer(&cpi->last_frame_db);
aom_free(cpi->highprec_srcbuf);
av1_free_restoration_buffers(cm);
aom_free_frame_buffer(&cpi->last_frame_db);
aom_free_frame_buffer(&cpi->trial_frame_rst);
aom_free(cpi->extra_rstbuf);
av1_free_restoration_struct(&cpi->rst_search);
#endif // CONFIG_LOOP_RESTORATION
aom_free_frame_buffer(&cpi->scaled_source);
aom_free_frame_buffer(&cpi->scaled_last_source);
......@@ -727,11 +729,21 @@ static void alloc_util_frame_buffers(AV1_COMP *cpi) {
NULL, NULL))
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate last frame deblocked buffer");
cpi->highprec_srcbuf = (uint8_t *)aom_realloc(
cpi->highprec_srcbuf, RESTORATION_TILEPELS_MAX * sizeof(int64_t));
if (!cpi->highprec_srcbuf)
if (aom_realloc_frame_buffer(&cpi->trial_frame_rst, cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_AOM_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
NULL, NULL))
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate trial restored frame buffer");
cpi->extra_rstbuf = (uint8_t *)aom_realloc(
cpi->extra_rstbuf, RESTORATION_TILEPELS_MAX * sizeof(int64_t));
if (!cpi->extra_rstbuf)
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate highprec srcbuf for restoration");
"Failed to allocate extra rstbuf for restoration");
av1_alloc_restoration_struct(&cpi->rst_search, cm->width, cm->height);
#endif // CONFIG_LOOP_RESTORATION
if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
......
......@@ -400,8 +400,10 @@ typedef struct AV1_COMP {
YV12_BUFFER_CONFIG last_frame_uf;
#if CONFIG_LOOP_RESTORATION
YV12_BUFFER_CONFIG last_frame_db;
uint8_t *highprec_srcbuf;
#endif // CONFIG_LOOP_RESTORATION
YV12_BUFFER_CONFIG trial_frame_rst;
uint8_t *extra_rstbuf; // Size RESTORATION_TILEPELS_MAX at highest precision
RestorationInfo rst_search; // Used for encoder side search
#endif // CONFIG_LOOP_RESTORATION
// Ambient reconstruction err target for force key frames
int64_t ambient_err;
......
This diff is collapsed.
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