Commit 64b8bbdf authored by Rupert Swarbrick's avatar Rupert Swarbrick Committed by Sebastien Alaiwan

Don't compute rtile width/height in av1_get_rest_ntiles

Restoration units are a fixed square size (in cm->rst_info[plane]) for
almost the entire image. The only special case is for tiles at the
right hand edge or the bottom row, which might expand or be cropped.

The av1_get_rest_ntiles function was implementing the cropping
behaviour when the image happened to be less than one restoration unit
wide or high (but not the expansion behaviour), but the result was
never useful: if you want to get the size of a restoration tile in
order to divide by it to work out what tile you're on, the fixed
square size is what you want. If you need to know how big this
particular tile is, call av1_get_rest_tile_limits.

As well as removing the output arguments from
av1_get_rest_tile_limits, this patch also removes the tile_width and
tile_height fields from the RestorationInternal structure. Note that
the tile size which is what you actually need is accessible as
rst->rsi->restoration_tilesize. (In practice, these were almost always
the same anyway).

This patch also has a couple of other small cleanups. Firstly, it
moves the subsampling_y field out of
CONFIG_STRIPED_LOOP_RESTORATION. It's not actually needed when you're
not doing striped loop restoration, but this gets rid of lots of
horrible #if/#endif lines at callsites for av1_get_rest_tile_limits.

Secondly, it simplifies the code in init_rest_search_ctxt (and fixes
some tautologous assertions). Now that YV12_BUFFER_CONFIG has a more
uniform layout, there's a simpler way to set things up, so we use
that.

Change-Id: I3c32d8ea0abe119dc86b9efa7564b27dde2151dc
parent bc2e897d
This diff is collapsed.
......@@ -221,12 +221,11 @@ typedef struct {
RestorationInfo *rsi;
int keyframe;
int ntiles;
int tile_width, tile_height;
int nhtiles, nvtiles;
int32_t *tmpbuf;
int subsampling_y;
#if CONFIG_STRIPED_LOOP_RESTORATION
int component;
int subsampling_y;
uint8_t *stripe_boundary_above[MAX_MB_PLANE];
uint8_t *stripe_boundary_below[MAX_MB_PLANE];
int stripe_boundary_stride[MAX_MB_PLANE];
......@@ -258,18 +257,14 @@ static INLINE void set_default_wiener(WienerInfo *wiener_info) {
}
static INLINE int av1_get_rest_ntiles(int width, int height, int tilesize,
int *tile_width, int *tile_height,
int *nhtiles, int *nvtiles) {
int nhtiles_, nvtiles_;
int tile_width_, tile_height_;
tile_width_ = (tilesize < 0) ? width : AOMMIN(tilesize, width);
tile_height_ = (tilesize < 0) ? height : AOMMIN(tilesize, height);
assert(tile_width_ > 0 && tile_height_ > 0);
nhtiles_ = (width + (tile_width_ >> 1)) / tile_width_;
nvtiles_ = (height + (tile_height_ >> 1)) / tile_height_;
if (tile_width) *tile_width = tile_width_;
if (tile_height) *tile_height = tile_height_;
const int tile_width = (tilesize < 0) ? width : AOMMIN(tilesize, width);
const int tile_height = (tilesize < 0) ? height : AOMMIN(tilesize, height);
assert(tile_width > 0 && tile_height > 0);
nhtiles_ = (width + (tile_width >> 1)) / tile_width;
nvtiles_ = (height + (tile_height >> 1)) / tile_height;
if (nhtiles) *nhtiles = nhtiles_;
if (nvtiles) *nvtiles = nvtiles_;
return (nhtiles_ * nvtiles_);
......@@ -278,28 +273,24 @@ 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 tile_width,
int tile_height, int im_width,
#if CONFIG_STRIPED_LOOP_RESTORATION
int im_height, int subsampling_y) {
#else
int im_height) {
#endif
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 * tile_width;
limits.v_start = vtile_idx * tile_height;
limits.h_start = htile_idx * rtile_size;
limits.v_start = vtile_idx * rtile_size;
limits.h_end =
(htile_idx < nhtiles - 1) ? limits.h_start + tile_width : im_width;
(htile_idx < nhtiles - 1) ? limits.h_start + rtile_size : im_width;
limits.v_end =
(vtile_idx < nvtiles - 1) ? limits.v_start + tile_height : im_height;
(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
limits.v_start -= RESTORATION_TILE_OFFSET >> subsampling_y;
if (limits.v_start < 0) limits.v_start = 0;
if (limits.v_end < im_height)
limits.v_end -= RESTORATION_TILE_OFFSET >> subsampling_y;
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;
}
......
......@@ -127,36 +127,26 @@ static int64_t try_restoration_tile(const YV12_BUFFER_CONFIG *src,
int tile_idx,
YV12_BUFFER_CONFIG *dst_frame) {
AV1_COMMON *const cm = &cpi->common;
int64_t filt_err;
int tile_width, tile_height, nhtiles, nvtiles;
int ntiles, width, height;
// Y and UV components cannot be mixed
assert(components_pattern == 1 || components_pattern == 2 ||
components_pattern == 4 || components_pattern == 6);
if (components_pattern == 1) { // Y only
width = src->y_crop_width;
height = src->y_crop_height;
} else { // Color
width = src->uv_crop_width;
height = src->uv_crop_height;
}
ntiles = av1_get_rest_ntiles(
width, height, cm->rst_info[components_pattern > 1].restoration_tilesize,
&tile_width, &tile_height, &nhtiles, &nvtiles);
(void)ntiles;
const int is_uv = components_pattern > 1;
const int width = src->crop_widths[is_uv];
const int height = src->crop_heights[is_uv];
const int rtile_size = cm->rst_info[is_uv].restoration_tilesize;
const int ss_y = is_uv && cm->subsampling_y;
int nhtiles, nvtiles;
av1_get_rest_ntiles(width, height, rtile_size, &nhtiles, &nvtiles);
av1_loop_restoration_frame(cm->frame_to_show, cm, rsi, components_pattern,
partial_frame, dst_frame);
RestorationTileLimits limits = av1_get_rest_tile_limits(
tile_idx, nhtiles, nvtiles, tile_width, tile_height, width,
#if CONFIG_STRIPED_LOOP_RESTORATION
height, components_pattern > 1 ? cm->subsampling_y : 0);
#else
height);
#endif
filt_err = sse_restoration_tile(
tile_idx, nhtiles, nvtiles, rtile_size, width, height, ss_y);
int64_t filt_err = sse_restoration_tile(
src, dst_frame, cm, limits.h_start, limits.h_end - limits.h_start,
limits.v_start, limits.v_end - limits.v_start, components_pattern);
......@@ -488,31 +478,19 @@ static INLINE int init_rest_search_ctxt(
ctxt->dst_frame = dst_frame;
const YV12_BUFFER_CONFIG *dgd = cm->frame_to_show;
if (plane == AOM_PLANE_Y) {
ctxt->plane_width = src->y_crop_width;
ctxt->plane_height = src->y_crop_height;
ctxt->src_buffer = src->y_buffer;
ctxt->src_stride = src->y_stride;
ctxt->dgd_buffer = dgd->y_buffer;
ctxt->dgd_stride = dgd->y_stride;
assert(ctxt->plane_width == dgd->y_crop_width);
assert(ctxt->plane_height == dgd->y_crop_height);
assert(ctxt->plane_width == src->y_crop_width);
assert(ctxt->plane_height == src->y_crop_height);
} else {
ctxt->plane_width = src->uv_crop_width;
ctxt->plane_height = src->uv_crop_height;
ctxt->src_stride = src->uv_stride;
ctxt->dgd_stride = dgd->uv_stride;
ctxt->src_buffer = plane == AOM_PLANE_U ? src->u_buffer : src->v_buffer;
ctxt->dgd_buffer = plane == AOM_PLANE_U ? dgd->u_buffer : dgd->v_buffer;
assert(ctxt->plane_width == dgd->uv_crop_width);
assert(ctxt->plane_height == dgd->uv_crop_height);
}
const int is_uv = plane != AOM_PLANE_Y;
ctxt->plane_width = src->crop_widths[is_uv];
ctxt->plane_height = src->crop_heights[is_uv];
ctxt->src_buffer = src->buffers[plane];
ctxt->src_stride = src->strides[is_uv];
ctxt->dgd_buffer = dgd->buffers[plane];
ctxt->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(ctxt->plane_width, ctxt->plane_height,
cm->rst_info[plane].restoration_tilesize, NULL,
NULL, &ctxt->nrtiles_x, &ctxt->nrtiles_y);
cm->rst_info[plane].restoration_tilesize,
&ctxt->nrtiles_x, &ctxt->nrtiles_y);
}
typedef void (*rtile_visitor_t)(const struct rest_search_ctxt *search_ctxt,
......@@ -562,21 +540,14 @@ static void foreach_rtile_in_tile(const struct rest_search_ctxt *ctxt,
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, ctxt->nrtiles_y);
const int rtile_width = AOMMIN(tile_col_end - tile_col_start, rtile_size);
const int rtile_height = AOMMIN(tile_row_end - tile_row_start, rtile_size);
const int ss_y = ctxt->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 * ctxt->nrtiles_x + rtile_col;
RestorationTileLimits limits = av1_get_rest_tile_limits(
rtile_idx, ctxt->nrtiles_x, ctxt->nrtiles_y, rtile_width,
rtile_height, ctxt->plane_width,
#if CONFIG_STRIPED_LOOP_RESTORATION
ctxt->plane_height, ctxt->plane > 0 ? cm->subsampling_y : 0);
#else
ctxt->plane_height);
#endif
rtile_idx, ctxt->nrtiles_x, ctxt->nrtiles_y, rtile_size,
ctxt->plane_width, ctxt->plane_height, ss_y);
fun(ctxt, rtile_idx, &limits, arg);
}
}
......@@ -1334,18 +1305,17 @@ static double search_norestore(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
int bits;
MACROBLOCK *x = &cpi->td.mb;
AV1_COMMON *const cm = &cpi->common;
int tile_idx, tile_width, tile_height, nhtiles, nvtiles;
int width, height;
if (plane == AOM_PLANE_Y) {
width = src->y_crop_width;
height = src->y_crop_height;
} else {
width = src->uv_crop_width;
height = src->uv_crop_height;
}
const int ntiles = av1_get_rest_ntiles(
width, height, cm->rst_info[plane].restoration_tilesize, &tile_width,
&tile_height, &nhtiles, &nvtiles);
int tile_idx, nhtiles, nvtiles;
const int is_uv = plane > 0;
const int ss_y = plane > 0 && cm->subsampling_y;
const int width = src->crop_widths[is_uv];
const int height = src->crop_heights[is_uv];
const int rtile_size = cm->rst_info[plane].restoration_tilesize;
const int ntiles =
av1_get_rest_ntiles(width, height, rtile_size, &nhtiles, &nvtiles);
(void)info;
(void)dst_frame;
(void)partial_frame;
......@@ -1353,12 +1323,7 @@ static double search_norestore(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
info->frame_restoration_type = RESTORE_NONE;
for (tile_idx = 0; tile_idx < ntiles; ++tile_idx) {
RestorationTileLimits limits = av1_get_rest_tile_limits(
tile_idx, nhtiles, nvtiles, tile_width, tile_height, width,
#if CONFIG_STRIPED_LOOP_RESTORATION
height, plane != AOM_PLANE_Y ? cm->subsampling_y : 0);
#else
height);
#endif
tile_idx, nhtiles, nvtiles, rtile_size, width, height, ss_y);
err = sse_restoration_tile(src, cm->frame_to_show, cm, limits.h_start,
limits.h_end - limits.h_start, limits.v_start,
limits.v_end - limits.v_start, 1 << plane);
......@@ -1472,14 +1437,13 @@ void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
const int uvwidth = src->uv_crop_width;
const int uvheight = src->uv_crop_height;
const int ntiles_y =
av1_get_rest_ntiles(ywidth, yheight, cm->rst_info[0].restoration_tilesize,
NULL, NULL, NULL, NULL);
const int ntiles_y = av1_get_rest_ntiles(
ywidth, yheight, cm->rst_info[0].restoration_tilesize, NULL, NULL);
const int ntiles_uv = av1_get_rest_ntiles(
uvwidth, uvheight, cm->rst_info[1].restoration_tilesize, NULL, NULL, NULL,
NULL);
uvwidth, uvheight, cm->rst_info[1].restoration_tilesize, NULL, NULL);
// Assume ntiles_uv is never larger that ntiles_y and so the same arrays work.
assert(ntiles_uv <= ntiles_y);
for (r = 0; r < RESTORE_SWITCHABLE_TYPES; r++) {
tile_cost[r] = (int64_t *)aom_malloc(sizeof(*tile_cost[0]) * ntiles_y);
restore_types[r] =
......
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