Commit dd6f09ab authored by Rupert Swarbrick's avatar Rupert Swarbrick

Expose av1_loop_restoration_filter_unit in restoration.h

This patch also does a certain amount of rejigging for loop
restoration coefficients, grouping the information for a given
restoration unit into a structure called RestorationUnitInfo. The end
result is to completely dispense with the RestorationInternal
structure.

The copy_tile functions in restoration.c, together with those
functions that operate on a single stripe, have been changed so that
they take pointers to the top-left corner of the area on which they
should work, together with a width and height.

The same isn't true of av1_loop_restoration_filter_unit, which still
takes pointers to the top-left of the tile. This is because you
actually need the absolute position in the tile in order to do striped
loop restoration properly.

Change-Id: I768c182cd15c9b2d6cfabb5ffca697cd2a3ff9e1
parent d1ba92a6
......@@ -162,8 +162,9 @@ void av1_alloc_restoration_buffers(AV1_COMMON *cm) {
int buf_size = num_stripes * 2 * stride;
uint8_t *above_buf, *below_buf;
aom_free(cm->rst_info[p].stripe_boundary_above);
aom_free(cm->rst_info[p].stripe_boundary_below);
RestorationStripeBoundaries *boundaries = &cm->rst_info[p].boundaries;
aom_free(boundaries->stripe_boundary_above);
aom_free(boundaries->stripe_boundary_below);
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth) buf_size = buf_size * 2;
......@@ -172,9 +173,9 @@ void av1_alloc_restoration_buffers(AV1_COMMON *cm) {
(uint8_t *)aom_memalign(1 << align_bits, buf_size));
CHECK_MEM_ERROR(cm, below_buf,
(uint8_t *)aom_memalign(1 << align_bits, buf_size));
cm->rst_info[p].stripe_boundary_above = above_buf;
cm->rst_info[p].stripe_boundary_below = below_buf;
cm->rst_info[p].stripe_boundary_stride = stride;
boundaries->stripe_boundary_above = above_buf;
boundaries->stripe_boundary_below = below_buf;
boundaries->stripe_boundary_stride = stride;
}
#endif // CONFIG_STRIPED_LOOP_RESTORATION
}
......
......@@ -576,7 +576,7 @@ if (aom_config("CONFIG_GLOBAL_MOTION") eq "yes" &&
# LOOP_RESTORATION functions
if (aom_config("CONFIG_LOOP_RESTORATION") eq "yes") {
add_proto qw/void apply_selfguided_restoration/, "const uint8_t *dat, int width, int height, int stride, int eps, int *xqd, uint8_t *dst, int dst_stride, int32_t *tmpbuf";
add_proto qw/void apply_selfguided_restoration/, "const uint8_t *dat, int width, int height, int stride, int eps, const int *xqd, uint8_t *dst, int dst_stride, int32_t *tmpbuf";
specialize qw/apply_selfguided_restoration sse4_1/;
add_proto qw/void av1_selfguided_restoration/, "const uint8_t *dgd, int width, int height, int stride, int32_t *dst, int dst_stride, int r, int eps";
......@@ -586,7 +586,7 @@ if (aom_config("CONFIG_LOOP_RESTORATION") eq "yes") {
specialize qw/av1_highpass_filter sse4_1/;
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void apply_selfguided_restoration_highbd/, "const uint16_t *dat, int width, int height, int stride, int bit_depth, int eps, int *xqd, uint16_t *dst, int dst_stride, int32_t *tmpbuf";
add_proto qw/void apply_selfguided_restoration_highbd/, "const uint16_t *dat, int width, int height, int stride, int bit_depth, int eps, const int *xqd, uint16_t *dst, int dst_stride, int32_t *tmpbuf";
specialize qw/apply_selfguided_restoration_highbd sse4_1/;
add_proto qw/void av1_selfguided_restoration_highbd/, "const uint16_t *dgd, int width, int height, int stride, int32_t *dst, int dst_stride, int bit_depth, int r, int eps";
......
This diff is collapsed.
......@@ -207,18 +207,38 @@ typedef struct {
} sgr_params_type;
typedef struct {
int restoration_tilesize;
int procunit_width, procunit_height;
RestorationType frame_restoration_type;
RestorationType *restoration_type;
// Wiener filter
WienerInfo *wiener_info;
// Selfguided proj filter
SgrprojInfo *sgrproj_info;
RestorationType restoration_type;
WienerInfo wiener_info;
SgrprojInfo sgrproj_info;
} RestorationUnitInfo;
#if CONFIG_STRIPED_LOOP_RESTORATION
// A restoration line buffer needs space for two lines plus a horizontal filter
// margin of RESTORATION_EXTRA_HORZ on each side.
#define RESTORATION_LINEBUFFER_WIDTH \
(RESTORATION_TILESIZE_MAX + 2 * RESTORATION_EXTRA_HORZ)
typedef struct {
// Temporary buffers to save/restore 2 lines above/below the restoration
// stripe.
uint16_t tmp_save_above[2][RESTORATION_LINEBUFFER_WIDTH];
uint16_t tmp_save_below[2][RESTORATION_LINEBUFFER_WIDTH];
} RestorationLineBuffers;
typedef struct {
uint8_t *stripe_boundary_above;
uint8_t *stripe_boundary_below;
int stripe_boundary_stride;
} RestorationStripeBoundaries;
#endif
typedef struct {
RestorationType frame_restoration_type;
int restoration_tilesize;
int procunit_width, procunit_height;
RestorationUnitInfo *unit_info;
#if CONFIG_STRIPED_LOOP_RESTORATION
RestorationStripeBoundaries boundaries;
#endif
} RestorationInfo;
......@@ -290,10 +310,43 @@ void av1_free_restoration_struct(RestorationInfo *rst_info);
void extend_frame(uint8_t *data, int width, int height, int stride,
int border_horz, int border_vert, int highbd);
void decode_xq(int *xqd, int *xq);
void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
RestorationInfo *rsi, int components_pattern,
YV12_BUFFER_CONFIG *dst);
void decode_xq(const int *xqd, int *xq);
// Filter a single loop restoration unit.
//
// limits is the limits of the unit. rui gives the mode to use for this unit
// and its coefficients. If striped loop restoration is enabled, rsb contains
// deblocked pixels to use for stripe boundaries; rlbs is just some space to
// use as a scratch buffer. ss_y is a flag which should be 1 if this is a plane
// with vertical subsampling.
//
// procunit_width and procunit_height are the width and height in which to
// process the data. highbd is a flag which should be 1 in high bit depth mode,
// in which case bit_depth is the bit depth.
//
// data8 is the frame data (pointing at the top-left corner of the frame, not
// the restoration unit) and stride is its stride. dst8 is the buffer where the
// results will be written and has stride dst_stride. Like data8, dst8 should
// point at the top-left corner of the frame.
//
// Finally tmpbuf is a scratch buffer used by the sgrproj filter which should
// be at least SGRPROJ_TMPBUF_SIZE big.
void av1_loop_restoration_filter_unit(const RestorationTileLimits *limits,
const RestorationUnitInfo *rui,
#if CONFIG_STRIPED_LOOP_RESTORATION
const RestorationStripeBoundaries *rsb,
RestorationLineBuffers *rlbs, int ss_y,
#endif
int procunit_height, int procunit_width,
int highbd, int bit_depth, uint8_t *data8,
int stride, uint8_t *dst8, int dst_stride,
int32_t *tmpbuf);
void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame,
struct AV1Common *cm,
RestorationInfo *rsi,
int components_pattern,
YV12_BUFFER_CONFIG *dst);
void av1_loop_restoration_precal();
// Return 1 iff the block at mi_row, mi_col with size bsize is a
......@@ -310,7 +363,7 @@ int av1_loop_restoration_corners_in_sb(const struct AV1Common *cm, int plane,
int *rcol0, int *rcol1, int *rrow0,
int *rrow1, int *nhtiles);
void av1_loop_restoration_save_boundary_lines(YV12_BUFFER_CONFIG *frame,
void av1_loop_restoration_save_boundary_lines(const YV12_BUFFER_CONFIG *frame,
struct AV1Common *cm);
#ifdef __cplusplus
} // extern "C"
......
......@@ -1058,8 +1058,8 @@ void av1_highpass_filter_sse4_1(const uint8_t *dgd, int width, int height,
void apply_selfguided_restoration_sse4_1(const uint8_t *dat, int width,
int height, int stride, int eps,
int *xqd, uint8_t *dst, int dst_stride,
int32_t *tmpbuf) {
const int *xqd, uint8_t *dst,
int dst_stride, int32_t *tmpbuf) {
int xq[2];
int32_t *flt1 = tmpbuf;
int32_t *flt2 = flt1 + RESTORATION_TILEPELS_MAX;
......@@ -1740,7 +1740,7 @@ void av1_highpass_filter_highbd_sse4_1(const uint16_t *dgd, int width,
void apply_selfguided_restoration_highbd_sse4_1(
const uint16_t *dat, int width, int height, int stride, int bit_depth,
int eps, int *xqd, uint16_t *dst, int dst_stride, int32_t *tmpbuf) {
int eps, const int *xqd, uint16_t *dst, int dst_stride, int32_t *tmpbuf) {
int xq[2];
int32_t *flt1 = tmpbuf;
int32_t *flt2 = flt1 + RESTORATION_TILEPELS_MAX;
......
......@@ -1452,6 +1452,9 @@ static void decode_restoration_mode(AV1_COMMON *cm,
static void read_wiener_filter(int wiener_win, WienerInfo *wiener_info,
WienerInfo *ref_wiener_info, aom_reader *rb) {
memset(wiener_info->vfilter, 0, sizeof(wiener_info->vfilter));
memset(wiener_info->hfilter, 0, sizeof(wiener_info->hfilter));
if (wiener_win == WIENER_WIN)
wiener_info->vfilter[0] = wiener_info->vfilter[WIENER_WIN - 1] =
aom_read_primitive_refsubexpfin(
......@@ -1526,7 +1529,8 @@ static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm,
MACROBLOCKD *xd,
aom_reader *const r, int plane,
int rtile_idx) {
const RestorationInfo *rsi = cm->rst_info + plane;
const RestorationInfo *rsi = &cm->rst_info[plane];
RestorationUnitInfo *rui = &rsi->unit_info[rtile_idx];
if (rsi->frame_restoration_type == RESTORE_NONE) return;
const int wiener_win = (plane > 0) ? WIENER_WIN_CHROMA : WIENER_WIN;
......@@ -1534,14 +1538,17 @@ static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm,
SgrprojInfo *sgrproj_info = xd->sgrproj_info + plane;
if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
rsi->restoration_type[rtile_idx] =
rui->restoration_type =
aom_read_symbol(r, xd->tile_ctx->switchable_restore_cdf,
RESTORE_SWITCHABLE_TYPES, ACCT_STR);
if (rsi->restoration_type[rtile_idx] == RESTORE_WIENER) {
read_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], wiener_info,
r);
} else if (rsi->restoration_type[rtile_idx] == RESTORE_SGRPROJ) {
read_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], sgrproj_info, r);
switch (rui->restoration_type) {
case RESTORE_WIENER:
read_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, r);
break;
case RESTORE_SGRPROJ:
read_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, r);
break;
default: assert(rui->restoration_type == RESTORE_NONE); break;
}
} else if (rsi->frame_restoration_type == RESTORE_WIENER) {
#if CONFIG_NEW_MULTISYMBOL
......@@ -1549,11 +1556,10 @@ static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm,
#else
if (aom_read(r, RESTORE_NONE_WIENER_PROB, ACCT_STR)) {
#endif // CONFIG_NEW_MULTISYMBOL
rsi->restoration_type[rtile_idx] = RESTORE_WIENER;
read_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], wiener_info,
r);
rui->restoration_type = RESTORE_WIENER;
read_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, r);
} else {
rsi->restoration_type[rtile_idx] = RESTORE_NONE;
rui->restoration_type = RESTORE_NONE;
}
} else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) {
#if CONFIG_NEW_MULTISYMBOL
......@@ -1561,10 +1567,10 @@ static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm,
#else
if (aom_read(r, RESTORE_NONE_SGRPROJ_PROB, ACCT_STR)) {
#endif // CONFIG_NEW_MULTISYMBOL
rsi->restoration_type[rtile_idx] = RESTORE_SGRPROJ;
read_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], sgrproj_info, r);
rui->restoration_type = RESTORE_SGRPROJ;
read_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, r);
} else {
rsi->restoration_type[rtile_idx] = RESTORE_NONE;
rui->restoration_type = RESTORE_NONE;
}
}
}
......@@ -3970,8 +3976,8 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data,
cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
aom_extend_frame_borders((YV12_BUFFER_CONFIG *)xd->cur_buf);
av1_loop_restoration_frame((YV12_BUFFER_CONFIG *)xd->cur_buf, cm,
cm->rst_info, 7, NULL);
av1_loop_restoration_filter_frame((YV12_BUFFER_CONFIG *)xd->cur_buf, cm,
cm->rst_info, 7, NULL);
}
#endif // CONFIG_LOOP_RESTORATION
......
......@@ -82,8 +82,8 @@ static struct av1_token compound_type_encodings[COMPOUND_TYPES];
#if CONFIG_LOOP_RESTORATION
static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm,
MACROBLOCKD *xd,
aom_writer *const w, int plane,
int rtile_idx);
const RestorationUnitInfo *rui,
aom_writer *const w, int plane);
#endif // CONFIG_LOOP_RESTORATION
#if CONFIG_OBU
static void write_uncompressed_header_obu(AV1_COMP *cpi,
......@@ -2748,7 +2748,9 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
for (int rrow = rrow0; rrow < rrow1; ++rrow) {
for (int rcol = rcol0; rcol < rcol1; ++rcol) {
int rtile_idx = rcol + rrow * nhtiles;
loop_restoration_write_sb_coeffs(cm, xd, w, plane, rtile_idx);
const RestorationUnitInfo *rui =
&cm->rst_info[plane].unit_info[rtile_idx];
loop_restoration_write_sb_coeffs(cm, xd, rui, w, plane);
}
}
}
......@@ -2857,7 +2859,7 @@ static void encode_restoration_mode(AV1_COMMON *cm,
}
}
static void write_wiener_filter(int wiener_win, WienerInfo *wiener_info,
static void write_wiener_filter(int wiener_win, const WienerInfo *wiener_info,
WienerInfo *ref_wiener_info, aom_writer *wb) {
if (wiener_win == WIENER_WIN)
aom_write_primitive_refsubexpfin(
......@@ -2900,7 +2902,7 @@ static void write_wiener_filter(int wiener_win, WienerInfo *wiener_info,
memcpy(ref_wiener_info, wiener_info, sizeof(*wiener_info));
}
static void write_sgrproj_filter(SgrprojInfo *sgrproj_info,
static void write_sgrproj_filter(const SgrprojInfo *sgrproj_info,
SgrprojInfo *ref_sgrproj_info,
aom_writer *wb) {
aom_write_literal(wb, sgrproj_info->ep, SGRPROJ_PARAMS_BITS);
......@@ -2917,47 +2919,48 @@ static void write_sgrproj_filter(SgrprojInfo *sgrproj_info,
static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm,
MACROBLOCKD *xd,
aom_writer *const w, int plane,
int rtile_idx) {
const RestorationUnitInfo *rui,
aom_writer *const w, int plane) {
const RestorationInfo *rsi = cm->rst_info + plane;
if (rsi->frame_restoration_type == RESTORE_NONE) return;
RestorationType frame_rtype = rsi->frame_restoration_type;
if (frame_rtype == RESTORE_NONE) return;
const int wiener_win = (plane > 0) ? WIENER_WIN_CHROMA : WIENER_WIN;
WienerInfo *wiener_info = xd->wiener_info + plane;
SgrprojInfo *sgrproj_info = xd->sgrproj_info + plane;
RestorationType unit_rtype = rui->restoration_type;
if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
aom_write_symbol(w, rsi->restoration_type[rtile_idx],
xd->tile_ctx->switchable_restore_cdf,
if (frame_rtype == RESTORE_SWITCHABLE) {
aom_write_symbol(w, unit_rtype, xd->tile_ctx->switchable_restore_cdf,
RESTORE_SWITCHABLE_TYPES);
if (rsi->restoration_type[rtile_idx] == RESTORE_WIENER) {
write_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], wiener_info,
w);
} else if (rsi->restoration_type[rtile_idx] == RESTORE_SGRPROJ) {
write_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], sgrproj_info, w);
switch (unit_rtype) {
case RESTORE_WIENER:
write_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, w);
break;
case RESTORE_SGRPROJ:
write_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, w);
break;
default: assert(unit_rtype == RESTORE_NONE); break;
}
} else if (rsi->frame_restoration_type == RESTORE_WIENER) {
} else if (frame_rtype == RESTORE_WIENER) {
#if CONFIG_NEW_MULTISYMBOL
aom_write_symbol(w, rsi->restoration_type[rtile_idx] != RESTORE_NONE,
aom_write_symbol(w, unit_rtype != RESTORE_NONE,
xd->tile_ctx->wiener_restore_cdf, 2);
#else
aom_write(w, rsi->restoration_type[rtile_idx] != RESTORE_NONE,
RESTORE_NONE_WIENER_PROB);
aom_write(w, unit_rtype != RESTORE_NONE, RESTORE_NONE_WIENER_PROB);
#endif // CONFIG_NEW_MULTISYMBOL
if (rsi->restoration_type[rtile_idx] != RESTORE_NONE) {
write_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], wiener_info,
w);
if (unit_rtype != RESTORE_NONE) {
write_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, w);
}
} else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) {
} else if (frame_rtype == RESTORE_SGRPROJ) {
#if CONFIG_NEW_MULTISYMBOL
aom_write_symbol(w, rsi->restoration_type[rtile_idx] != RESTORE_NONE,
aom_write_symbol(w, unit_rtype != RESTORE_NONE,
xd->tile_ctx->sgrproj_restore_cdf, 2);
#else
aom_write(w, rsi->restoration_type[rtile_idx] != RESTORE_NONE,
RESTORE_NONE_SGRPROJ_PROB);
aom_write(w, unit_rtype != RESTORE_NONE, RESTORE_NONE_SGRPROJ_PROB);
#endif // CONFIG_NEW_MULTISYMBOL
if (rsi->restoration_type[rtile_idx] != RESTORE_NONE) {
write_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], sgrproj_info, w);
if (unit_rtype != RESTORE_NONE) {
write_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, w);
}
}
}
......
......@@ -4301,9 +4301,7 @@ static void set_frame_size(AV1_COMP *cpi, int width, int height) {
av1_alloc_restoration_struct(cm, search, frame_width, frame_height);
#if CONFIG_STRIPED_LOOP_RESTORATION
// We can share boundary buffers between the search info and the main one
search->stripe_boundary_above = rsi->stripe_boundary_above;
search->stripe_boundary_below = rsi->stripe_boundary_below;
search->stripe_boundary_stride = rsi->stripe_boundary_stride;
search->boundaries = rsi->boundaries;
#endif
}
#endif // CONFIG_LOOP_RESTORATION
......@@ -4671,7 +4669,8 @@ static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
av1_loop_restoration_frame(cm->frame_to_show, cm, cm->rst_info, 7, NULL);
av1_loop_restoration_filter_frame(cm->frame_to_show, cm, cm->rst_info, 7,
NULL);
}
#endif // CONFIG_LOOP_RESTORATION
// TODO(debargha): Fix mv search range on encoder side
......
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