diff --git a/av1/common/blockd.h b/av1/common/blockd.h index 57bf41ab5bc3f338f54193ebcd0a65de747f6fd6..a5aa4d8fb870ac4a7b3f0d1fda4a0e5cb0f25ed8 100644 --- a/av1/common/blockd.h +++ b/av1/common/blockd.h @@ -670,6 +670,18 @@ typedef struct RefBuffer { typedef int16_t EobThresholdMD[TX_TYPES][EOB_THRESHOLD_NUM]; #endif +#if CONFIG_LOOP_RESTORATION +typedef struct { + DECLARE_ALIGNED(16, InterpKernel, vfilter); + DECLARE_ALIGNED(16, InterpKernel, hfilter); +} WienerInfo; + +typedef struct { + int ep; + int xqd[2]; +} SgrprojInfo; +#endif // CONFIG_LOOP_RESTORATION + typedef struct macroblockd { struct macroblockd_plane plane[MAX_MB_PLANE]; uint8_t bmode_blocks_wl; @@ -731,6 +743,11 @@ typedef struct macroblockd { #endif #endif +#if CONFIG_LOOP_RESTORATION + WienerInfo wiener_info[MAX_MB_PLANE]; + SgrprojInfo sgrproj_info[MAX_MB_PLANE]; +#endif // CONFIG_LOOP_RESTORATION + // block dimension in the unit of mode_info. uint8_t n8_w, n8_h; diff --git a/av1/common/restoration.c b/av1/common/restoration.c index 910ecc33abea50dfd1c7ff3139263d9de838d78f..11ee1d367e746b234a8398c26881d48d8cd999ea 100644 --- a/av1/common/restoration.c +++ b/av1/common/restoration.c @@ -1426,3 +1426,67 @@ void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, loop_restoration_rows(frame, cm, start_mi_row, end_mi_row, components_pattern, rsi, dst); } + +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, + int *rrow1, int *nhtiles) { + assert(rcol0 && rcol1 && rrow0 && rrow1 && nhtiles); + + if (bsize != cm->sb_size) return 0; + +#if CONFIG_FRAME_SUPERRES + const int frame_w = cm->superres_upscaled_width; + const int frame_h = cm->superres_upscaled_height; + const int mi_to_px = MI_SIZE * cm->superres_scale_numerator; + const int denom = SCALE_DENOMINATOR; +#else + const int frame_w = cm->width; + const int frame_h = cm->height; + const int mi_to_px = MI_SIZE; + const int denom = 1; +#endif // CONFIG_FRAME_SUPERRES + + const int ss_frame_w = frame_w >> (plane > 0 && cm->subsampling_x != 0); + const int ss_frame_h = frame_h >> (plane > 0 && cm->subsampling_y != 0); + + int rtile_w, rtile_h, nvtiles; + av1_get_rest_ntiles(ss_frame_w, ss_frame_h, + cm->rst_info[0].restoration_tilesize, &rtile_w, &rtile_h, + nhtiles, &nvtiles); + + const int rnd_w = rtile_w * denom - 1; + const int rnd_h = rtile_h * denom - 1; + + // rcol0/rrow0 should be the first column/row of rtiles that doesn't start + // left/below of mi_col/mi_row. For this calculation, we need to round up the + // division (if the sb starts at rtile column 10.1, the first matching rtile + // has column index 11) + *rcol0 = (mi_col * mi_to_px + rnd_w) / (rtile_w * denom); + *rrow0 = (mi_row * mi_to_px + rnd_h) / (rtile_h * denom); + + // rcol1/rrow1 is the equivalent calculation, but for the superblock + // below-right. There are some slightly strange boundary effects. First, we + // need to clamp to nhtiles/nvtiles for the case where it appears there are, + // say, 2.4 restoration tiles horizontally. There we need a maximum mi_row1 + // of 2 because tile 1 gets extended. + // + // Second, if mi_col1 >= cm->mi_cols then we must manually set *rcol1 to + // nhtiles. This is needed whenever the frame's width rounded up to the next + // toplevel superblock is smaller than nhtiles * rtile_w. The same logic is + // needed for rows. + const int mi_row1 = mi_row + mi_size_high[bsize]; + const int mi_col1 = mi_col + mi_size_wide[bsize]; + + if (mi_col1 >= cm->mi_cols) + *rcol1 = *nhtiles; + else + *rcol1 = AOMMIN(*nhtiles, (mi_col1 * mi_to_px + rnd_w) / (rtile_w * denom)); + + if (mi_row1 >= cm->mi_rows) + *rrow1 = nvtiles; + else + *rrow1 = AOMMIN(nvtiles, (mi_row1 * mi_to_px + rnd_h) / (rtile_h * denom)); + + return *rcol0 < *rcol1 && *rrow0 < *rrow1; +} diff --git a/av1/common/restoration.h b/av1/common/restoration.h index b71853974a1939834bc8e948e20a1c56598a8937..4a9ade9775cfc81ceef0540e2f4ed2e602f39fd9 100644 --- a/av1/common/restoration.h +++ b/av1/common/restoration.h @@ -135,10 +135,6 @@ extern "C" { #if WIENER_FILT_PREC_BITS != 7 #error "Wiener filter currently only works if WIENER_FILT_PREC_BITS == 7" #endif -typedef struct { - DECLARE_ALIGNED(16, InterpKernel, vfilter); - DECLARE_ALIGNED(16, InterpKernel, hfilter); -} WienerInfo; typedef struct { #if USE_HIGHPASS_IN_SGRPROJ @@ -152,11 +148,6 @@ typedef struct { int e2; } sgr_params_type; -typedef struct { - int ep; - int xqd[2]; -} SgrprojInfo; - typedef struct { int restoration_tilesize; RestorationType frame_restoration_type; @@ -261,6 +252,20 @@ void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm, RestorationInfo *rsi, int components_pattern, int partial_frame, YV12_BUFFER_CONFIG *dst); void av1_loop_restoration_precal(); + +// 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. +// +// If the block is a top-level superblock, the function writes to +// *rcol0, *rcol1, *rrow0, *rrow1. The rectangle of indices given by +// [*rcol0, *rcol1) x [*rrow0, *rrow1) will point at the set of rtiles +// whose top left corners lie in the superblock. Note that the set is +// only nonempty if *rcol0 < *rcol1 and *rrow0 < *rrow1. +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, + int *rrow1, int *nhtiles); #ifdef __cplusplus } // extern "C" #endif diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index fb0dbd7c3d25c184ad885c7f058394a83b8ff644..9978a9fe567c4a504f2f177c154c14523898847c 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -86,6 +86,13 @@ #include "av1/common/cfl.h" #endif +#if CONFIG_LOOP_RESTORATION +static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm, + MACROBLOCKD *xd, + aom_reader *const r, int plane, + int rtile_idx); +#endif + static struct aom_read_bit_buffer *init_read_bit_buffer( AV1Decoder *pbi, struct aom_read_bit_buffer *rb, const uint8_t *data, const uint8_t *data_end, uint8_t clear_data[MAX_AV1_HEADER_SIZE]); @@ -2549,6 +2556,21 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd, } } #endif // CONFIG_CDEF +#if CONFIG_LOOP_RESTORATION + for (int plane = 0; plane < MAX_MB_PLANE; ++plane) { + int rcol0, rcol1, rrow0, rrow1, nhtiles; + if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize, + &rcol0, &rcol1, &rrow0, &rrow1, + &nhtiles)) { + for (int rrow = rrow0; rrow < rrow1; ++rrow) { + for (int rcol = rcol0; rcol < rcol1; ++rcol) { + int rtile_idx = rcol + rrow * nhtiles; + loop_restoration_read_sb_coeffs(cm, xd, r, plane, rtile_idx); + } + } + } + } +#endif } static void setup_bool_decoder(const uint8_t *data, const uint8_t *data_end, @@ -2739,97 +2761,43 @@ static void read_sgrproj_filter(SgrprojInfo *sgrproj_info, memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info)); } -static void decode_restoration_for_tile(AV1_COMMON *cm, aom_reader *rb, - int tile_row, int tile_col, - const int nrtiles_x[2], - const int nrtiles_y[2]) { - for (int p = 0; p < MAX_MB_PLANE; ++p) { - RestorationInfo *rsi = &cm->rst_info[p]; - if (rsi->frame_restoration_type == RESTORE_NONE) continue; - - const int tile_width = - (p > 0) ? ROUND_POWER_OF_TWO(cm->tile_width, cm->subsampling_x) - : cm->tile_width; - const int tile_height = - (p > 0) ? ROUND_POWER_OF_TWO(cm->tile_height, cm->subsampling_y) - : cm->tile_height; - const int rtile_size = rsi->restoration_tilesize; - const int rtiles_per_tile_x = tile_width * MI_SIZE / rtile_size; - const int rtiles_per_tile_y = tile_height * MI_SIZE / rtile_size; - - const int rtile_row0 = rtiles_per_tile_y * tile_row; - const int rtile_row1 = - AOMMIN(rtile_row0 + rtiles_per_tile_y, nrtiles_y[p > 0]); - - const int rtile_col0 = rtiles_per_tile_x * tile_col; - const int rtile_col1 = - AOMMIN(rtile_col0 + rtiles_per_tile_x, nrtiles_x[p > 0]); - - WienerInfo wiener_info; - SgrprojInfo sgrproj_info; - set_default_wiener(&wiener_info); - set_default_sgrproj(&sgrproj_info); - - const int wiener_win = (p > 0) ? WIENER_WIN_CHROMA : WIENER_WIN; - - 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 * nrtiles_x[p > 0] + rtile_col; - if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) { - assert(p == 0); - rsi->restoration_type[rtile_idx] = - aom_read_tree(rb, av1_switchable_restore_tree, - cm->fc->switchable_restore_prob, ACCT_STR); - if (rsi->restoration_type[rtile_idx] == RESTORE_WIENER) { - read_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], - &wiener_info, rb); - } else if (rsi->restoration_type[rtile_idx] == RESTORE_SGRPROJ) { - read_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], &sgrproj_info, - rb); - } - } else if (rsi->frame_restoration_type == RESTORE_WIENER) { - if (aom_read(rb, RESTORE_NONE_WIENER_PROB, ACCT_STR)) { - rsi->restoration_type[rtile_idx] = RESTORE_WIENER; - read_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], - &wiener_info, rb); - } else { - rsi->restoration_type[rtile_idx] = RESTORE_NONE; - } - } else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) { - if (aom_read(rb, RESTORE_NONE_SGRPROJ_PROB, ACCT_STR)) { - rsi->restoration_type[rtile_idx] = RESTORE_SGRPROJ; - read_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], &sgrproj_info, - rb); - } else { - rsi->restoration_type[rtile_idx] = RESTORE_NONE; - } - } - } +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; + if (rsi->frame_restoration_type == 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; + + if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) { + assert(plane == 0); + rsi->restoration_type[rtile_idx] = + aom_read_tree(r, av1_switchable_restore_tree, + cm->fc->switchable_restore_prob, 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); } - } -} - -static void decode_restoration(AV1_COMMON *cm, aom_reader *rb) { -#if CONFIG_FRAME_SUPERRES - const int width = cm->superres_upscaled_width; - const int height = cm->superres_upscaled_height; -#else - const int width = cm->width; - const int height = cm->height; -#endif // CONFIG_FRAME_SUPERRES - - int nrtiles_x[2], nrtiles_y[2]; - av1_get_rest_ntiles(width, height, cm->rst_info[0].restoration_tilesize, NULL, - NULL, &nrtiles_x[0], &nrtiles_y[0]); - av1_get_rest_ntiles(ROUND_POWER_OF_TWO(width, cm->subsampling_x), - ROUND_POWER_OF_TWO(height, cm->subsampling_y), - cm->rst_info[1].restoration_tilesize, NULL, NULL, - &nrtiles_x[1], &nrtiles_y[1]); - - for (int tile_row = 0; tile_row < cm->tile_rows; ++tile_row) { - for (int tile_col = 0; tile_col < cm->tile_cols; ++tile_col) { - decode_restoration_for_tile(cm, rb, tile_row, tile_col, nrtiles_x, - nrtiles_y); + } else if (rsi->frame_restoration_type == RESTORE_WIENER) { + if (aom_read(r, RESTORE_NONE_WIENER_PROB, ACCT_STR)) { + rsi->restoration_type[rtile_idx] = RESTORE_WIENER; + read_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], wiener_info, + r); + } else { + rsi->restoration_type[rtile_idx] = RESTORE_NONE; + } + } else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) { + if (aom_read(r, RESTORE_NONE_SGRPROJ_PROB, ACCT_STR)) { + rsi->restoration_type[rtile_idx] = RESTORE_SGRPROJ; + read_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], sgrproj_info, r); + } else { + rsi->restoration_type[rtile_idx] = RESTORE_NONE; } } } @@ -3740,6 +3708,12 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, #else av1_zero_above_context(cm, tile_info.mi_col_start, tile_info.mi_col_end); #endif +#if CONFIG_LOOP_RESTORATION + for (int p = 0; p < MAX_MB_PLANE; ++p) { + set_default_wiener(td->xd.wiener_info + p); + set_default_sgrproj(td->xd.sgrproj_info + p); + } +#endif // CONFIG_LOOP_RESTORATION #if CONFIG_LOOPFILTERING_ACROSS_TILES dec_setup_across_tile_boundary_info(cm, &tile_info); @@ -4902,15 +4876,6 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data, aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, "Failed to allocate bool decoder 0"); -#if CONFIG_LOOP_RESTORATION - 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_alloc_restoration_buffers(cm); - decode_restoration(cm, &r); - } -#endif - #if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX) if (cm->tx_mode == TX_MODE_SELECT) av1_diff_update_prob(&r, &fc->quarter_tx_size_prob, ACCT_STR); @@ -5303,6 +5268,14 @@ void av1_decode_frame(AV1Decoder *pbi, const uint8_t *data, aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, "Decode failed. Frame data header is corrupted."); +#if CONFIG_LOOP_RESTORATION + 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_alloc_restoration_buffers(cm); + } +#endif + #if CONFIG_LOOPFILTER_LEVEL if ((cm->lf.filter_level[0] || cm->lf.filter_level[1]) && !cm->skip_loop_filter) { diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index be8073c19b435c9daffa03665d4a90cf1f63d6a6..da7951d43c5ccd980ebbac028d3f5132c25cb6dc 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c @@ -102,6 +102,10 @@ static struct av1_token ncobmc_mode_encodings[MAX_NCOBMC_MODES]; #endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION #if CONFIG_LOOP_RESTORATION static struct av1_token switchable_restore_encodings[RESTORE_SWITCHABLE_TYPES]; +static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm, + MACROBLOCKD *xd, + aom_writer *const w, int plane, + int rtile_idx); #endif // CONFIG_LOOP_RESTORATION static void write_uncompressed_header(AV1_COMP *cpi, struct aom_write_bit_buffer *wb); @@ -3126,6 +3130,21 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, } } #endif +#if CONFIG_LOOP_RESTORATION + for (int plane = 0; plane < MAX_MB_PLANE; ++plane) { + int rcol0, rcol1, rrow0, rrow1, nhtiles; + if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize, + &rcol0, &rcol1, &rrow0, &rrow1, + &nhtiles)) { + 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); + } + } + } + } +#endif } static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile, @@ -3307,98 +3326,44 @@ static void write_sgrproj_filter(SgrprojInfo *sgrproj_info, memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info)); } -static void encode_restoration_for_tile(AV1_COMMON *cm, aom_writer *wb, - int tile_row, int tile_col, - const int nrtiles_x[2], - const int nrtiles_y[2]) { - for (int p = 0; p < MAX_MB_PLANE; ++p) { - RestorationInfo *rsi = &cm->rst_info[p]; - if (rsi->frame_restoration_type == RESTORE_NONE) continue; - - const int tile_width = - (p > 0) ? ROUND_POWER_OF_TWO(cm->tile_width, cm->subsampling_x) - : cm->tile_width; - const int tile_height = - (p > 0) ? ROUND_POWER_OF_TWO(cm->tile_height, cm->subsampling_y) - : cm->tile_height; - const int rtile_size = rsi->restoration_tilesize; - const int rtiles_per_tile_x = tile_width * MI_SIZE / rtile_size; - const int rtiles_per_tile_y = tile_height * MI_SIZE / rtile_size; - - const int rtile_row0 = rtiles_per_tile_y * tile_row; - const int rtile_row1 = - AOMMIN(rtile_row0 + rtiles_per_tile_y, nrtiles_y[p > 0]); - - const int rtile_col0 = rtiles_per_tile_x * tile_col; - const int rtile_col1 = - AOMMIN(rtile_col0 + rtiles_per_tile_x, nrtiles_x[p > 0]); - - WienerInfo wiener_info; - SgrprojInfo sgrproj_info; - set_default_wiener(&wiener_info); - set_default_sgrproj(&sgrproj_info); - - const int wiener_win = (p > 0) ? WIENER_WIN_CHROMA : WIENER_WIN; - - 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 * nrtiles_x[p > 0] + rtile_col; - if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) { - assert(p == 0); - av1_write_token( - wb, av1_switchable_restore_tree, cm->fc->switchable_restore_prob, - &switchable_restore_encodings[rsi->restoration_type[rtile_idx]]); - if (rsi->restoration_type[rtile_idx] == RESTORE_WIENER) { - write_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], - &wiener_info, wb); - } else if (rsi->restoration_type[rtile_idx] == RESTORE_SGRPROJ) { - write_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], &sgrproj_info, - wb); - } - } else if (rsi->frame_restoration_type == RESTORE_WIENER) { - aom_write(wb, rsi->restoration_type[rtile_idx] != RESTORE_NONE, - RESTORE_NONE_WIENER_PROB); - if (rsi->restoration_type[rtile_idx] != RESTORE_NONE) { - write_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], - &wiener_info, wb); - } - } else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) { - aom_write(wb, rsi->restoration_type[rtile_idx] != RESTORE_NONE, - RESTORE_NONE_SGRPROJ_PROB); - if (rsi->restoration_type[rtile_idx] != RESTORE_NONE) { - write_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], &sgrproj_info, - wb); - } - } - } +static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm, + MACROBLOCKD *xd, + aom_writer *const w, int plane, + int rtile_idx) { + const RestorationInfo *rsi = cm->rst_info + plane; + if (rsi->frame_restoration_type == 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; + + if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) { + assert(plane == 0); + av1_write_token( + w, av1_switchable_restore_tree, cm->fc->switchable_restore_prob, + &switchable_restore_encodings[rsi->restoration_type[rtile_idx]]); + 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); } - } -} - -static void encode_restoration(AV1_COMMON *cm, aom_writer *wb) { -#if CONFIG_FRAME_SUPERRES - const int width = cm->superres_upscaled_width; - const int height = cm->superres_upscaled_height; -#else - const int width = cm->width; - const int height = cm->height; -#endif // CONFIG_FRAME_SUPERRES - - int nrtiles_x[2], nrtiles_y[2]; - av1_get_rest_ntiles(width, height, cm->rst_info[0].restoration_tilesize, NULL, - NULL, &nrtiles_x[0], &nrtiles_y[0]); - av1_get_rest_ntiles(ROUND_POWER_OF_TWO(width, cm->subsampling_x), - ROUND_POWER_OF_TWO(height, cm->subsampling_y), - cm->rst_info[1].restoration_tilesize, NULL, NULL, - &nrtiles_x[1], &nrtiles_y[1]); - - for (int tile_row = 0; tile_row < cm->tile_rows; ++tile_row) { - for (int tile_col = 0; tile_col < cm->tile_cols; ++tile_col) { - encode_restoration_for_tile(cm, wb, tile_row, tile_col, nrtiles_x, - nrtiles_y); + } else if (rsi->frame_restoration_type == RESTORE_WIENER) { + aom_write(w, rsi->restoration_type[rtile_idx] != RESTORE_NONE, + RESTORE_NONE_WIENER_PROB); + if (rsi->restoration_type[rtile_idx] != RESTORE_NONE) { + write_wiener_filter(wiener_win, &rsi->wiener_info[rtile_idx], wiener_info, + w); + } + } else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) { + aom_write(w, rsi->restoration_type[rtile_idx] != RESTORE_NONE, + RESTORE_NONE_SGRPROJ_PROB); + if (rsi->restoration_type[rtile_idx] != RESTORE_NONE) { + write_sgrproj_filter(&rsi->sgrproj_info[rtile_idx], sgrproj_info, w); } } } + #endif // CONFIG_LOOP_RESTORATION static void encode_loopfilter(AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { @@ -4009,6 +3974,13 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, #if CONFIG_ANS mode_bc.size = 1 << cpi->common.ans_window_size_log2; #endif // CONFIG_ANS +#if CONFIG_LOOP_RESTORATION + for (int p = 0; p < MAX_MB_PLANE; ++p) { + set_default_wiener(cpi->td.mb.e_mbd.wiener_info + p); + set_default_sgrproj(cpi->td.mb.e_mbd.sgrproj_info + p); + } +#endif // CONFIG_LOOP_RESTORATION + aom_start_encode(&mode_bc, dst + total_size); write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end); #if !CONFIG_LV_MAP @@ -4640,9 +4612,6 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { #endif aom_start_encode(header_bc, data); -#if CONFIG_LOOP_RESTORATION - encode_restoration(cm, header_bc); -#endif // CONFIG_LOOP_RESTORATION #if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX) if (cm->tx_mode == TX_MODE_SELECT) av1_cond_prob_diff_update(header_bc, &cm->fc->quarter_tx_size_prob,