Commit 33ed9e69 authored by Rupert Swarbrick's avatar Rupert Swarbrick
Browse files

Define av1_foreach_rest_unit_in_frame

This is the last stage in a quest to move all knowledge of the layout
of restoration units across the frame into restoration.c. Now this is
done, we can change how they are laid out (to split them properly at
tile boundaries) without having to change code in any other file.

Change-Id: Id5108d787d342f5070580d0e34d84b5ddcc53a86
parent 1a96c3f5
......@@ -1404,6 +1404,30 @@ static const struct restore_borders restore_borders[RESTORE_TYPES] = {
{ RESTORATION_BORDER_HORZ, RESTORATION_BORDER_VERT }
};
static RestorationTileLimits get_rest_tile_limits(int tile_idx, int nhtiles,
int nvtiles, int rtile_size,
int im_width, int im_height,
int subsampling_y) {
const int htile_idx = tile_idx % nhtiles;
const int vtile_idx = tile_idx / nhtiles;
RestorationTileLimits limits;
limits.h_start = htile_idx * rtile_size;
limits.v_start = vtile_idx * rtile_size;
limits.h_end =
(htile_idx < nhtiles - 1) ? limits.h_start + rtile_size : im_width;
limits.v_end =
(vtile_idx < nvtiles - 1) ? limits.v_start + rtile_size : im_height;
#if CONFIG_STRIPED_LOOP_RESTORATION
// Offset the tile upwards to align with the restoration processing stripe
const int voffset = RESTORATION_TILE_OFFSET >> subsampling_y;
limits.v_start = AOMMAX(0, limits.v_start - voffset);
if (limits.v_end < im_height) limits.v_end -= voffset;
#else
(void)subsampling_y;
#endif
return limits;
}
void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame,
AV1_COMMON *cm, RestorationInfo *rsi,
int components_pattern,
......@@ -1485,7 +1509,7 @@ void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame,
highbd);
for (int tile_idx = 0; tile_idx < ntiles; ++tile_idx) {
RestorationTileLimits limits = av1_get_rest_tile_limits(
RestorationTileLimits limits = get_rest_tile_limits(
tile_idx, nhtiles, nvtiles, prsi->restoration_tilesize, plane_width,
plane_height, ss_y);
......@@ -1510,6 +1534,68 @@ void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame,
}
}
static void foreach_rest_unit_in_tile(const AV1PixelRect *tile_rect,
int nunits_x, int nunits_y, int unit_size,
int plane_w, int plane_h, int ss_y,
rest_unit_visitor_t on_rest_unit,
void *priv) {
const int col0 = (tile_rect->left + unit_size - 1) / unit_size;
const int col1 =
AOMMIN((tile_rect->right + unit_size - 1) / unit_size, nunits_x);
const int row0 = (tile_rect->top + unit_size - 1) / unit_size;
const int row1 =
AOMMIN((tile_rect->bottom + unit_size - 1) / unit_size, nunits_y);
for (int i = row0; i < row1; ++i) {
for (int j = col0; j < col1; ++j) {
const int rtile_idx = i * nunits_x + j;
RestorationTileLimits limits = get_rest_tile_limits(
rtile_idx, nunits_x, nunits_y, unit_size, plane_w, plane_h, ss_y);
on_rest_unit(&limits, rtile_idx, priv);
}
}
}
void av1_foreach_rest_unit_in_frame(const struct AV1Common *cm, int plane,
rest_tile_start_visitor_t on_tile,
rest_unit_visitor_t on_rest_unit,
void *priv) {
const int is_uv = plane > 0;
const int ss_x = is_uv && cm->subsampling_x;
const int ss_y = is_uv && cm->subsampling_y;
#if CONFIG_FRAME_SUPERRES
const int frame_w = cm->superres_upscaled_width;
const int frame_h = cm->superres_upscaled_height;
#else
const int frame_w = cm->width;
const int frame_h = cm->height;
#endif
const int plane_w = (frame_w + ss_x) >> ss_x;
const int plane_h = (frame_h + ss_y) >> ss_y;
const int unit_size = cm->rst_info[plane].restoration_tilesize;
int nunits_x, nunits_y;
av1_get_rest_ntiles(plane_w, plane_h, unit_size, &nunits_x, &nunits_y);
TileInfo tile_info;
for (int tile_row = 0; tile_row < cm->tile_rows; ++tile_row) {
av1_tile_set_row(&tile_info, cm, tile_row);
for (int tile_col = 0; tile_col < cm->tile_cols; ++tile_col) {
av1_tile_set_col(&tile_info, cm, tile_col);
on_tile(tile_row, tile_col, priv);
AV1PixelRect tile_rect = av1_get_tile_rect(&tile_info, cm, is_uv);
foreach_rest_unit_in_tile(&tile_rect, nunits_x, nunits_y, unit_size,
plane_w, plane_h, ss_y, on_rest_unit, priv);
}
}
}
int av1_loop_restoration_corners_in_sb(const struct AV1Common *cm, int plane,
int mi_row, int mi_col, BLOCK_SIZE bsize,
int *rcol0, int *rcol1, int *rrow0,
......
......@@ -275,29 +275,6 @@ static INLINE int av1_get_rest_ntiles(int width, int height, int tilesize,
typedef struct { int h_start, h_end, v_start, v_end; } RestorationTileLimits;
static INLINE RestorationTileLimits
av1_get_rest_tile_limits(int tile_idx, int nhtiles, int nvtiles, int rtile_size,
int im_width, int im_height, int subsampling_y) {
const int htile_idx = tile_idx % nhtiles;
const int vtile_idx = tile_idx / nhtiles;
RestorationTileLimits limits;
limits.h_start = htile_idx * rtile_size;
limits.v_start = vtile_idx * rtile_size;
limits.h_end =
(htile_idx < nhtiles - 1) ? limits.h_start + rtile_size : im_width;
limits.v_end =
(vtile_idx < nvtiles - 1) ? limits.v_start + rtile_size : im_height;
#if CONFIG_STRIPED_LOOP_RESTORATION
// Offset the tile upwards to align with the restoration processing stripe
const int voffset = RESTORATION_TILE_OFFSET >> subsampling_y;
limits.v_start = AOMMAX(0, limits.v_start - voffset);
if (limits.v_end < im_height) limits.v_end -= voffset;
#else
(void)subsampling_y;
#endif
return limits;
}
extern const sgr_params_type sgr_params[SGRPROJ_PARAMS];
extern int sgrproj_mtable[MAX_EPS][MAX_NELEM];
extern const int32_t x_by_xplus1[256];
......@@ -349,6 +326,19 @@ void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame,
YV12_BUFFER_CONFIG *dst);
void av1_loop_restoration_precal();
typedef void (*rest_unit_visitor_t)(const RestorationTileLimits *limits,
int rest_unit_idx, void *priv);
typedef void (*rest_tile_start_visitor_t)(int tile_row, int tile_col,
void *priv);
// Call on_rest_unit for each loop restoration unit in the frame. At the start
// of each tile, call on_tile.
void av1_foreach_rest_unit_in_frame(const struct AV1Common *cm, int plane,
rest_tile_start_visitor_t on_tile,
rest_unit_visitor_t on_rest_unit,
void *priv);
// Return 1 iff the block at mi_row, mi_col with size bsize is a
// top-level superblock containing the top-left corner of at least one
// loop restoration tile.
......
......@@ -11,6 +11,9 @@
#include "av1/common/tile_common.h"
#include "av1/common/onyxc_int.h"
#if CONFIG_FRAME_SUPERRES
#include "av1/common/resize.h"
#endif
#include "aom_dsp/aom_dsp_common.h"
#if CONFIG_DEPENDENT_HORZTILES
......@@ -236,6 +239,38 @@ int get_tile_size(int mi_frame_size, int log2_tile_num, int *ntiles) {
return mi_tile_size;
}
AV1PixelRect av1_get_tile_rect(const TileInfo *tile_info, const AV1_COMMON *cm,
int is_uv) {
AV1PixelRect r;
const int ss_x = is_uv && cm->subsampling_x;
const int ss_y = is_uv && cm->subsampling_y;
r.left = (tile_info->mi_col_start * MI_SIZE + ss_x) >> ss_x;
r.right = (tile_info->mi_col_end * MI_SIZE + ss_x) >> ss_x;
r.top = (tile_info->mi_row_start * MI_SIZE + ss_y) >> ss_y;
r.bottom = (tile_info->mi_row_end * MI_SIZE + ss_y) >> ss_y;
#if CONFIG_FRAME_SUPERRES
// If upscaling is enabled, the tile limits need scaling to match the
// upscaled frame where the restoration tiles live. To do this, scale up the
// top-left and bottom-right of the tile.
if (!av1_superres_unscaled(cm)) {
av1_calculate_unscaled_superres_size(&r.left, &r.top,
cm->superres_scale_denominator);
av1_calculate_unscaled_superres_size(&r.right, &r.bottom,
cm->superres_scale_denominator);
// Make sure we don't fall off the bottom-right of the frame.
const int plane_width = (cm->superres_upscaled_width + ss_x) >> ss_x;
const int plane_height = (cm->superres_upscaled_height + ss_y) >> ss_y;
r.right = AOMMIN(r.right, plane_width);
r.bottom = AOMMIN(r.bottom, plane_height);
}
#endif // CONFIG_FRAME_SUPERRES
return r;
}
#if CONFIG_LOOPFILTERING_ACROSS_TILES
void av1_setup_across_tile_boundary_info(const AV1_COMMON *const cm,
const TileInfo *const tile_info) {
......
......@@ -48,6 +48,12 @@ void av1_setup_frame_boundary_info(const struct AV1Common *const cm);
// tiles horizontally or vertically in the frame.
int get_tile_size(int mi_frame_size, int log2_tile_num, int *ntiles);
typedef struct { int left, top, right, bottom; } AV1PixelRect;
// Return the pixel extents of the given tile
AV1PixelRect av1_get_tile_rect(const TileInfo *tile_info,
const struct AV1Common *cm, int is_uv);
#if CONFIG_LOOPFILTERING_ACROSS_TILES
void av1_setup_across_tile_boundary_info(const struct AV1Common *const cm,
const TileInfo *const tile_info);
......
......@@ -410,125 +410,60 @@ typedef struct {
const uint8_t *src_buffer;
int src_stride;
int nrtiles_x;
int nrtiles_y;
} RestSearchInfo;
static INLINE int init_rest_search_info(const YV12_BUFFER_CONFIG *src,
const AV1_COMMON *cm,
const MACROBLOCK *x, int plane,
RestUnitSearchInfo *rusi,
YV12_BUFFER_CONFIG *dst_frame,
RestSearchInfo *info) {
info->src = src;
info->cm = cm;
info->x = x;
info->plane = plane;
info->rusi = rusi;
info->dst_frame = dst_frame;
const YV12_BUFFER_CONFIG *dgd = cm->frame_to_show;
const int is_uv = plane != AOM_PLANE_Y;
info->plane_width = src->crop_widths[is_uv];
info->plane_height = src->crop_heights[is_uv];
info->src_buffer = src->buffers[plane];
info->src_stride = src->strides[is_uv];
info->dgd_buffer = dgd->buffers[plane];
info->dgd_stride = dgd->strides[is_uv];
assert(src->crop_widths[is_uv] == dgd->crop_widths[is_uv]);
assert(src->crop_heights[is_uv] == dgd->crop_heights[is_uv]);
return av1_get_rest_ntiles(info->plane_width, info->plane_height,
cm->rst_info[plane].restoration_tilesize,
&info->nrtiles_x, &info->nrtiles_y);
}
// sse and bits are initialised by reset_rsc in search_rest_type
int64_t sse;
int64_t bits;
typedef struct {
// sgrproj and wiener are initialised by rsc_on_tile when starting the first
// tile in the frame.
SgrprojInfo sgrproj;
WienerInfo wiener;
int64_t sse;
int64_t bits;
} RestSearchCtxt;
static void rsc_on_tile(RestSearchCtxt *rsc) {
static void rsc_on_tile(int tile_row, int tile_col, void *priv) {
(void)tile_row;
(void)tile_col;
RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
set_default_sgrproj(&rsc->sgrproj);
set_default_wiener(&rsc->wiener);
}
static void rsc_init(RestSearchCtxt *rsc) {
rsc->sse = rsc->bits = 0;
rsc_on_tile(rsc);
}
static double rsc_cost(const RestSearchCtxt *rsc, int rdmult) {
return RDCOST_DBL(rdmult, rsc->bits >> 4, rsc->sse);
static void reset_rsc(RestSearchCtxt *rsc) {
rsc->sse = 0;
rsc->bits = 0;
}
typedef void (*on_rest_unit_fun)(const RestSearchInfo *info,
const RestorationTileLimits *limits,
RestUnitSearchInfo *rusi, RestSearchCtxt *rsc);
static void foreach_rtile_in_tile(const RestSearchInfo *info, int tile_row,
int tile_col, on_rest_unit_fun fun,
RestSearchCtxt *rsc) {
const AV1_COMMON *const cm = info->cm;
TileInfo tile_info;
av1_tile_set_row(&tile_info, cm, tile_row);
av1_tile_set_col(&tile_info, cm, tile_col);
int tile_col_start = tile_info.mi_col_start * MI_SIZE;
int tile_col_end = tile_info.mi_col_end * MI_SIZE;
int tile_row_start = tile_info.mi_row_start * MI_SIZE;
int tile_row_end = tile_info.mi_row_end * MI_SIZE;
if (info->plane > 0) {
tile_col_start = ROUND_POWER_OF_TWO(tile_col_start, cm->subsampling_x);
tile_col_end = ROUND_POWER_OF_TWO(tile_col_end, cm->subsampling_x);
tile_row_start = ROUND_POWER_OF_TWO(tile_row_start, cm->subsampling_y);
tile_row_end = ROUND_POWER_OF_TWO(tile_row_end, cm->subsampling_y);
}
static void init_rsc(const YV12_BUFFER_CONFIG *src, const AV1_COMMON *cm,
const MACROBLOCK *x, int plane, RestUnitSearchInfo *rusi,
YV12_BUFFER_CONFIG *dst_frame, RestSearchCtxt *rsc) {
rsc->src = src;
rsc->cm = cm;
rsc->x = x;
rsc->plane = plane;
rsc->rusi = rusi;
rsc->dst_frame = dst_frame;
#if CONFIG_FRAME_SUPERRES
// If upscaling is enabled, the tile limits need scaling to match the
// upscaled frame where the restoration tiles live. To do this, scale up the
// top-left and bottom-right of the tile.
if (!av1_superres_unscaled(cm)) {
av1_calculate_unscaled_superres_size(&tile_col_start, &tile_row_start,
cm->superres_scale_denominator);
av1_calculate_unscaled_superres_size(&tile_col_end, &tile_row_end,
cm->superres_scale_denominator);
// Make sure we don't fall off the bottom-right of the frame.
tile_col_end = AOMMIN(tile_col_end, info->plane_width);
tile_row_end = AOMMIN(tile_row_end, info->plane_height);
}
#endif // CONFIG_FRAME_SUPERRES
const int rtile_size = cm->rst_info[info->plane].restoration_tilesize;
const int rtile_col0 = (tile_col_start + rtile_size - 1) / rtile_size;
const int rtile_col1 =
AOMMIN((tile_col_end + rtile_size - 1) / rtile_size, info->nrtiles_x);
const int rtile_row0 = (tile_row_start + rtile_size - 1) / rtile_size;
const int rtile_row1 =
AOMMIN((tile_row_end + rtile_size - 1) / rtile_size, info->nrtiles_y);
const int ss_y = info->plane > 0 && cm->subsampling_y;
for (int rtile_row = rtile_row0; rtile_row < rtile_row1; ++rtile_row) {
for (int rtile_col = rtile_col0; rtile_col < rtile_col1; ++rtile_col) {
const int rtile_idx = rtile_row * info->nrtiles_x + rtile_col;
RestorationTileLimits limits = av1_get_rest_tile_limits(
rtile_idx, info->nrtiles_x, info->nrtiles_y, rtile_size,
info->plane_width, info->plane_height, ss_y);
fun(info, &limits, &info->rusi[rtile_idx], rsc);
}
}
const YV12_BUFFER_CONFIG *dgd = cm->frame_to_show;
const int is_uv = plane != AOM_PLANE_Y;
rsc->plane_width = src->crop_widths[is_uv];
rsc->plane_height = src->crop_heights[is_uv];
rsc->src_buffer = src->buffers[plane];
rsc->src_stride = src->strides[is_uv];
rsc->dgd_buffer = dgd->buffers[plane];
rsc->dgd_stride = dgd->strides[is_uv];
assert(src->crop_widths[is_uv] == dgd->crop_widths[is_uv]);
assert(src->crop_heights[is_uv] == dgd->crop_heights[is_uv]);
}
static void search_sgrproj(const RestSearchInfo *info,
const RestorationTileLimits *limits,
RestUnitSearchInfo *rusi, RestSearchCtxt *rsc) {
const MACROBLOCK *const x = info->x;
const AV1_COMMON *const cm = info->cm;
const RestorationInfo *rsi = &cm->rst_info[info->plane];
static void search_sgrproj(const RestorationTileLimits *limits,
int rest_unit_idx, void *priv) {
RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
RestUnitSearchInfo *rusi = &rsc->rusi[rest_unit_idx];
const MACROBLOCK *const x = rsc->x;
const AV1_COMMON *const cm = rsc->cm;
const RestorationInfo *rsi = &cm->rst_info[rsc->plane];
#if CONFIG_HIGHBITDEPTH
const int highbd = cm->use_highbitdepth;
......@@ -539,22 +474,22 @@ static void search_sgrproj(const RestSearchInfo *info,
#endif // CONFIG_HIGHBITDEPTH
uint8_t *dgd_start =
info->dgd_buffer + limits->v_start * info->dgd_stride + limits->h_start;
rsc->dgd_buffer + limits->v_start * rsc->dgd_stride + limits->h_start;
const uint8_t *src_start =
info->src_buffer + limits->v_start * info->src_stride + limits->h_start;
rsc->src_buffer + limits->v_start * rsc->src_stride + limits->h_start;
rusi->sgrproj = search_selfguided_restoration(
dgd_start, limits->h_end - limits->h_start,
limits->v_end - limits->v_start, info->dgd_stride, src_start,
info->src_stride, highbd, bit_depth, rsi->procunit_width,
limits->v_end - limits->v_start, rsc->dgd_stride, src_start,
rsc->src_stride, highbd, bit_depth, rsi->procunit_width,
rsi->procunit_height, cm->rst_tmpbuf);
RestorationUnitInfo rui;
rui.restoration_type = RESTORE_SGRPROJ;
rui.sgrproj_info = rusi->sgrproj;
rusi->sse[RESTORE_SGRPROJ] = try_restoration_tile(
cm, info->src, limits, &rui, info->dst_frame, info->plane);
rusi->sse[RESTORE_SGRPROJ] = try_restoration_tile(cm, rsc->src, limits, &rui,
rsc->dst_frame, rsc->plane);
const int64_t bits_none = x->sgrproj_restore_cost[0];
const int64_t bits_sgr = x->sgrproj_restore_cost[1] +
......@@ -1037,30 +972,31 @@ static int64_t finer_tile_search_wiener(
return err;
}
static void search_wiener(const RestSearchInfo *info,
const RestorationTileLimits *limits,
RestUnitSearchInfo *rusi, RestSearchCtxt *rsc) {
static void search_wiener(const RestorationTileLimits *limits,
int rest_unit_idx, void *priv) {
RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
RestUnitSearchInfo *rusi = &rsc->rusi[rest_unit_idx];
const int wiener_win =
(info->plane == AOM_PLANE_Y) ? WIENER_WIN : WIENER_WIN_CHROMA;
(rsc->plane == AOM_PLANE_Y) ? WIENER_WIN : WIENER_WIN_CHROMA;
double M[WIENER_WIN2];
double H[WIENER_WIN2 * WIENER_WIN2];
double vfilterd[WIENER_WIN], hfilterd[WIENER_WIN];
#if CONFIG_HIGHBITDEPTH
const AV1_COMMON *const cm = info->cm;
const AV1_COMMON *const cm = rsc->cm;
if (cm->use_highbitdepth)
compute_stats_highbd(wiener_win, info->dgd_buffer, info->src_buffer,
compute_stats_highbd(wiener_win, rsc->dgd_buffer, rsc->src_buffer,
limits->h_start, limits->h_end, limits->v_start,
limits->v_end, info->dgd_stride, info->src_stride, M,
H);
limits->v_end, rsc->dgd_stride, rsc->src_stride, M, H);
else
#endif // CONFIG_HIGHBITDEPTH
compute_stats(wiener_win, info->dgd_buffer, info->src_buffer,
limits->h_start, limits->h_end, limits->v_start,
limits->v_end, info->dgd_stride, info->src_stride, M, H);
compute_stats(wiener_win, rsc->dgd_buffer, rsc->src_buffer, limits->h_start,
limits->h_end, limits->v_start, limits->v_end,
rsc->dgd_stride, rsc->src_stride, M, H);
const MACROBLOCK *const x = info->x;
const MACROBLOCK *const x = rsc->x;
const int64_t bits_none = x->wiener_restore_cost[0];
if (!wiener_decompose_sep_sym(wiener_win, M, H, vfilterd, hfilterd)) {
......@@ -1092,8 +1028,8 @@ static void search_wiener(const RestSearchInfo *info,
aom_clear_system_state();
rusi->sse[RESTORE_WIENER] =
finer_tile_search_wiener(info->cm, info->src, limits, &rui, 4,
info->plane, wiener_win, info->dst_frame);
finer_tile_search_wiener(rsc->cm, rsc->src, limits, &rui, 4, rsc->plane,
wiener_win, rsc->dst_frame);
rusi->wiener = rui.wiener_info;
if (wiener_win != WIENER_WIN) {
......@@ -1122,30 +1058,33 @@ static void search_wiener(const RestSearchInfo *info,
if (cost_wiener < cost_none) rsc->wiener = rusi->wiener;
}
static void search_norestore(const RestSearchInfo *info,
const RestorationTileLimits *limits,
RestUnitSearchInfo *rusi, RestSearchCtxt *rsc) {
static void search_norestore(const RestorationTileLimits *limits,
int rest_unit_idx, void *priv) {
RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
RestUnitSearchInfo *rusi = &rsc->rusi[rest_unit_idx];
#if CONFIG_HIGHBITDEPTH
const int highbd = info->cm->use_highbitdepth;
const int highbd = rsc->cm->use_highbitdepth;
#else
const int highbd = 0;
#endif // CONFIG_HIGHBITDEPTH
rusi->sse[RESTORE_NONE] = sse_restoration_tile(
limits, info->src, info->cm->frame_to_show, info->plane, highbd);
limits, rsc->src, rsc->cm->frame_to_show, rsc->plane, highbd);
rsc->sse += rusi->sse[RESTORE_NONE];
}
static void search_switchable(const RestSearchInfo *info,
const RestorationTileLimits *limits,
RestUnitSearchInfo *rusi, RestSearchCtxt *rsc) {
static void search_switchable(const RestorationTileLimits *limits,
int rest_unit_idx, void *priv) {
(void)limits;
RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
RestUnitSearchInfo *rusi = &rsc->rusi[rest_unit_idx];
const MACROBLOCK *const x = info->x;
const MACROBLOCK *const x = rsc->x;
const int wiener_win =
(info->plane == AOM_PLANE_Y) ? WIENER_WIN : WIENER_WIN_CHROMA;
(rsc->plane == AOM_PLANE_Y) ? WIENER_WIN : WIENER_WIN_CHROMA;
double best_cost = 0;
int64_t best_bits = 0;
......@@ -1194,9 +1133,8 @@ static void copy_unit_info(RestorationType frame_rtype,
rui->sgrproj_info = rusi->sgrproj;
}
static double search_rest_type(const RestSearchInfo *info,
RestorationType rtype) {
static const on_rest_unit_fun funs[RESTORE_TYPES] = {
static double search_rest_type(RestSearchCtxt *rsc, RestorationType rtype) {
static const rest_unit_visitor_t funs[RESTORE_TYPES] = {
search_norestore, search_wiener, search_sgrproj, search_switchable
};
static const int hborders[RESTORE_TYPES] = { 0, WIENER_HALFWIN,
......@@ -1204,29 +1142,20 @@ static double search_rest_type(const RestSearchInfo *info,
static const int vborders[RESTORE_TYPES] = { 0, WIENER_HALFWIN,
SGRPROJ_BORDER_VERT, 0 };
const AV1_COMMON *const cm = info->cm;
if (hborders[rtype] || vborders[rtype]) {
#if CONFIG_HIGHBITDEPTH
const int highbd = cm->use_highbitdepth;
const int highbd = rsc->cm->use_highbitdepth;
#else
const int highbd = 0;
#endif
extend_frame(info->dgd_buffer, info->plane_width, info->plane_height,
info->dgd_stride, hborders[rtype], vborders[rtype], highbd);
}
RestSearchCtxt rsc;
rsc_init(&rsc);
rsc.bits = frame_level_restore_bits[rtype] << AV1_PROB_COST_SHIFT;
for (int tile_row = 0; tile_row < cm->tile_rows; ++tile_row) {
for (int tile_col = 0; tile_col < cm->tile_cols; ++tile_col) {
if (tile_row || tile_col) rsc_on_tile(&rsc);
foreach_rtile_in_tile(info, tile_row, tile_col, funs[rtype], &rsc);
}
extend_frame(rsc->dgd_buffer, rsc->plane_width, rsc->plane_height,
rsc->dgd_stride, hborders[rtype], vborders[rtype], highbd);
}
return rsc_cost(&rsc, info->x->rdmult);
reset_rsc(rsc);
av1_foreach_rest_unit_in_frame(rsc->cm, rsc->plane, rsc_on_tile, funs[rtype],
rsc);
return RDCOST_DBL(rsc->x->rdmult, rsc->bits >> 4, rsc->sse);
}
void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi) {
......@@ -1242,10 +1171,10 @@ void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi) {
RestUnitSearchInfo *rusi =
(RestUnitSearchInfo *)aom_malloc(sizeof(*rusi) * ntiles[0]);
RestSearchCtxt rsc;
for (int plane = AOM_PLANE_Y; plane <= AOM_PLANE_V; ++plane) {
RestSearchInfo info;
init_rest_search_info(src, &cpi->common, &cpi->td.mb, plane, rusi,
&cpi->trial_frame_rst, &info);
init_rsc(src, &cpi->common, &cpi->td.mb, plane, rusi, &cpi->trial_frame_rst,
&rsc);
const int plane_ntiles = ntiles[plane > 0];
const RestorationType num_rtypes =
......@@ -1259,7 +1188,7 @@ void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi) {
(r != force_restore_type))
continue;
double cost = search_rest_type(&info, r);
double cost = search_rest_type(&rsc, r);
if (r == 0 || cost < best_cost) {
best_cost = cost;
......
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