Add finer search for wiener filter parameters Improves coding efficiency a little Change-Id: I1d5b3e3925e7fb640ea4da76b529672c4183a71c
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c index 0cd72c0..b4b2310 100644 --- a/av1/encoder/pickrst.c +++ b/av1/encoder/pickrst.c
@@ -38,7 +38,7 @@ const RestorationType force_restore_type = RESTORE_NONE; // Number of Wiener iterations -#define NUM_WIENER_ITERS 10 +#define NUM_WIENER_ITERS 5 typedef double (*search_restore_type)(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, int partial_frame, @@ -775,6 +775,88 @@ return bits; } +#define USE_WIENER_REFINEMENT_SEARCH 1 +static int64_t finer_tile_search_wiener(const YV12_BUFFER_CONFIG *src, + AV1_COMP *cpi, RestorationInfo *rsi, + int plane, int tile_idx, + int partial_frame, + YV12_BUFFER_CONFIG *dst_frame) { + int64_t err = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, + tile_idx, 0, 0, dst_frame); +#if USE_WIENER_REFINEMENT_SEARCH + int64_t err2; + int tap_min[] = { WIENER_FILT_TAP0_MINV, WIENER_FILT_TAP1_MINV, + WIENER_FILT_TAP2_MINV }; + int tap_max[] = { WIENER_FILT_TAP0_MAXV, WIENER_FILT_TAP1_MAXV, + WIENER_FILT_TAP2_MAXV }; + // printf("err pre = %"PRId64"\n", err); + for (int p = 0; p < WIENER_HALFWIN; ++p) { + if (rsi[plane].wiener_info[tile_idx].hfilter[p] != tap_min[p]) { + rsi[plane].wiener_info[tile_idx].hfilter[p] -= 1; + rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] -= 1; + rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] += 2; + err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, + tile_idx, 0, 0, dst_frame); + if (err2 > err) { + rsi[plane].wiener_info[tile_idx].hfilter[p] += 1; + rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] += 1; + rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] -= 2; + } else { + err = err2; + continue; + } + } + if (rsi[plane].wiener_info[tile_idx].hfilter[p] != tap_max[p]) { + rsi[plane].wiener_info[tile_idx].hfilter[p] += 1; + rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] += 1; + rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] -= 2; + err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, + tile_idx, 0, 0, dst_frame); + if (err2 > err) { + rsi[plane].wiener_info[tile_idx].hfilter[p] -= 1; + rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] -= 1; + rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] += 2; + } else { + err = err2; + } + } + } + for (int p = 0; p < WIENER_HALFWIN; ++p) { + if (rsi[plane].wiener_info[tile_idx].vfilter[p] != tap_min[p]) { + rsi[plane].wiener_info[tile_idx].vfilter[p] -= 1; + rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] -= 1; + rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] += 2; + err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, + tile_idx, 0, 0, dst_frame); + if (err2 > err) { + rsi[plane].wiener_info[tile_idx].vfilter[p] += 1; + rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] += 1; + rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] -= 2; + } else { + err = err2; + continue; + } + } + if (rsi[plane].wiener_info[tile_idx].vfilter[p] != tap_max[p]) { + rsi[plane].wiener_info[tile_idx].vfilter[p] += 1; + rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] += 1; + rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] -= 2; + err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, + tile_idx, 0, 0, dst_frame); + if (err2 > err) { + rsi[plane].wiener_info[tile_idx].vfilter[p] -= 1; + rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] -= 1; + rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] += 2; + } else { + err = err2; + } + } + } +// printf("err post = %"PRId64"\n", err); +#endif // USE_WIENER_REFINEMENT_SEARCH + return err; +} + static double search_wiener_uv(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, int partial_frame, int plane, RestorationInfo *info, RestorationType *type, @@ -815,6 +897,17 @@ for (tile_idx = 0; tile_idx < ntiles; ++tile_idx) { rsi[plane].restoration_type[tile_idx] = RESTORE_NONE; } +// Construct a (WIENER_HALFWIN)-pixel border around the frame +#if CONFIG_HIGHBITDEPTH + if (cm->use_highbitdepth) + extend_frame_highbd( + CONVERT_TO_SHORTPTR(plane == AOM_PLANE_U ? dgd->u_buffer + : dgd->v_buffer), + width, height, dgd_stride); + else +#endif + extend_frame((plane == AOM_PLANE_U ? dgd->u_buffer : dgd->v_buffer), width, + height, dgd_stride); // Compute best Wiener filters for each tile for (tile_idx = 0; tile_idx < ntiles; ++tile_idx) { @@ -830,9 +923,8 @@ // best_tile_cost[tile_idx] = DBL_MAX; av1_get_rest_tile_limits(tile_idx, 0, 0, nhtiles, nvtiles, tile_width, - tile_height, width, height, WIENER_HALFWIN, - WIENER_HALFWIN, &h_start, &h_end, &v_start, - &v_end); + tile_height, width, height, 0, 0, &h_start, &h_end, + &v_start, &v_end); if (plane == AOM_PLANE_U) { #if CONFIG_HIGHBITDEPTH if (cm->use_highbitdepth) @@ -876,8 +968,8 @@ aom_clear_system_state(); rsi[plane].restoration_type[tile_idx] = RESTORE_WIENER; - err = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, - tile_idx, 0, 0, dst_frame); + err = finer_tile_search_wiener(src, cpi, rsi, plane, tile_idx, + partial_frame, dst_frame); bits = count_wiener_bits(&rsi[plane].wiener_info[tile_idx], &ref_wiener_info) << AV1_PROB_COST_SHIFT; @@ -1019,8 +1111,8 @@ aom_clear_system_state(); rsi->restoration_type[tile_idx] = RESTORE_WIENER; - err = try_restoration_tile(src, cpi, rsi, 1, partial_frame, tile_idx, 0, 0, - dst_frame); + err = finer_tile_search_wiener(src, cpi, rsi, 0, tile_idx, partial_frame, + dst_frame); bits = count_wiener_bits(&rsi->wiener_info[tile_idx], &ref_wiener_info) << AV1_PROB_COST_SHIFT; bits += av1_cost_bit(RESTORE_NONE_WIENER_PROB, 1); @@ -1216,9 +1308,8 @@ cm->rst_info[AOM_PLANE_V].restoration_type, &cpi->trial_frame_rst); /* - printf("Frame %d/%d restore types: %d %d %d\n", - cm->current_video_frame, cm->show_frame, - cm->rst_info[0].frame_restoration_type, + printf("Frame %d/%d restore types: %d %d %d\n", cm->current_video_frame, + cm->show_frame, cm->rst_info[0].frame_restoration_type, cm->rst_info[1].frame_restoration_type, cm->rst_info[2].frame_restoration_type); printf("Frame %d/%d frame_restore_type %d : %f %f %f %f\n",