Add a macro to control use of domain txfm filter Allows DomainTxfm filters to be turned off for experimentation. Also expands the parameter set for the Self guided filters. Change-Id: I68fdb8e079a2464d80b3a4a990005c49baaaf0b8
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c index 57ba8c8..5404bcd 100644 --- a/av1/common/entropymode.c +++ b/av1/common/entropymode.c
@@ -1072,6 +1072,7 @@ }; #if CONFIG_LOOP_RESTORATION +#if USE_DOMAINTXFMRF const aom_tree_index av1_switchable_restore_tree[TREE_SIZE( RESTORE_SWITCHABLE_TYPES)] = { -RESTORE_NONE, 2, -RESTORE_WIENER, 4, -RESTORE_SGRPROJ, -RESTORE_DOMAINTXFMRF, @@ -1081,6 +1082,17 @@ default_switchable_restore_prob[RESTORE_SWITCHABLE_TYPES - 1] = { 32, 128, 128, }; +#else +const aom_tree_index + av1_switchable_restore_tree[TREE_SIZE(RESTORE_SWITCHABLE_TYPES)] = { + -RESTORE_NONE, 2, -RESTORE_WIENER, -RESTORE_SGRPROJ, + }; + +static const aom_prob + default_switchable_restore_prob[RESTORE_SWITCHABLE_TYPES - 1] = { + 32, 128, + }; +#endif // USE_DOMAINTXFMRF #endif // CONFIG_LOOP_RESTORATION #if CONFIG_PALETTE
diff --git a/av1/common/enums.h b/av1/common/enums.h index e232ee4..addfc7e 100644 --- a/av1/common/enums.h +++ b/av1/common/enums.h
@@ -504,12 +504,15 @@ #endif // CONFIG_SUPERTX #if CONFIG_LOOP_RESTORATION +#define USE_DOMAINTXFMRF 1 typedef enum { RESTORE_NONE = 0, RESTORE_WIENER = 1, RESTORE_SGRPROJ = 2, +#if USE_DOMAINTXFMRF RESTORE_DOMAINTXFMRF = 3, - RESTORE_SWITCHABLE = 4, +#endif // USE_DOMAINTXFMRF + RESTORE_SWITCHABLE, RESTORE_SWITCHABLE_TYPES = RESTORE_SWITCHABLE, RESTORE_TYPES, } RestorationType;
diff --git a/av1/common/restoration.c b/av1/common/restoration.c index 2b8f565..80619a7 100644 --- a/av1/common/restoration.c +++ b/av1/common/restoration.c
@@ -21,6 +21,7 @@ #include "aom_mem/aom_mem.h" #include "aom_ports/mem.h" +#if USE_DOMAINTXFMRF static int domaintxfmrf_vtable[DOMAINTXFMRF_ITERS][DOMAINTXFMRF_PARAMS][256]; static const int domaintxfmrf_params[DOMAINTXFMRF_PARAMS] = { @@ -30,11 +31,19 @@ 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 130, 132, 134, 136, 138, 140, 142, 146, 150, 154, 158, 162, 166, 170, 174 }; +#endif // USE_DOMAINTXFMRF const sgr_params_type sgr_params[SGRPROJ_PARAMS] = { - // r1, eps1, r2, eps2 +// r1, eps1, r2, eps2 +#if SGRPROJ_PARAMS_BITS == 3 { 2, 25, 1, 11 }, { 2, 35, 1, 12 }, { 2, 45, 1, 13 }, { 2, 55, 1, 14 }, { 2, 65, 1, 15 }, { 3, 50, 2, 25 }, { 3, 60, 2, 35 }, { 3, 70, 2, 45 }, +#elif SGRPROJ_PARAMS_BITS == 4 + { 2, 12, 1, 4 }, { 2, 15, 1, 6 }, { 2, 18, 1, 8 }, { 2, 20, 1, 9 }, + { 2, 22, 1, 10 }, { 2, 25, 1, 11 }, { 2, 35, 1, 12 }, { 2, 45, 1, 13 }, + { 2, 55, 1, 14 }, { 2, 65, 1, 15 }, { 2, 75, 1, 16 }, { 3, 30, 1, 10 }, + { 3, 50, 1, 12 }, { 3, 50, 2, 25 }, { 3, 60, 2, 35 }, { 3, 70, 2, 45 }, +#endif // SGRPROJ_PARAMS_BITS == 3 }; typedef void (*restore_func_type)(uint8_t *data8, int width, int height, @@ -61,6 +70,7 @@ cm, rst_info->sgrproj_info, (SgrprojInfo *)aom_realloc(rst_info->sgrproj_info, sizeof(*rst_info->sgrproj_info) * ntiles)); +#if USE_DOMAINTXFMRF rst_info->domaintxfmrf_info = (DomaintxfmrfInfo *)aom_realloc( rst_info->domaintxfmrf_info, sizeof(*rst_info->domaintxfmrf_info) * ntiles); @@ -68,6 +78,7 @@ (DomaintxfmrfInfo *)aom_realloc( rst_info->domaintxfmrf_info, sizeof(*rst_info->domaintxfmrf_info) * ntiles)); +#endif // USE_DOMAINTXFMRF return ntiles; } @@ -78,10 +89,13 @@ rst_info->wiener_info = NULL; aom_free(rst_info->sgrproj_info); rst_info->sgrproj_info = NULL; +#if USE_DOMAINTXFMRF aom_free(rst_info->domaintxfmrf_info); rst_info->domaintxfmrf_info = NULL; +#endif // USE_DOMAINTXFMRF } +#if USE_DOMAINTXFMRF static void GenDomainTxfmRFVtable() { int i, j; const double sigma_s = sqrt(2.0); @@ -100,8 +114,13 @@ } } } +#endif // USE_DOMAINTXFMRF -void av1_loop_restoration_precal() { GenDomainTxfmRFVtable(); } +void av1_loop_restoration_precal() { +#if USE_DOMAINTXFMRF + GenDomainTxfmRFVtable(); +#endif // USE_DOMAINTXFMRF +} static void loop_restoration_init(RestorationInternal *rst, int kf) { rst->keyframe = kf; @@ -796,6 +815,7 @@ } } +#if USE_DOMAINTXFMRF static void apply_domaintxfmrf(int iter, int param, uint8_t *diff_right, uint8_t *diff_down, int width, int height, int32_t *dat, int dat_stride) { @@ -952,6 +972,7 @@ dst, dst_stride); } } +#endif // USE_DOMAINTXFMRF static void loop_switchable_filter(uint8_t *data, int width, int height, int stride, RestorationInternal *rst, @@ -968,9 +989,11 @@ } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_SGRPROJ) { loop_sgrproj_filter_tile(data, tile_idx, width, height, stride, rst, dst, dst_stride); +#if USE_DOMAINTXFMRF } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_DOMAINTXFMRF) { loop_domaintxfmrf_filter_tile(data, tile_idx, width, height, stride, rst, dst, dst_stride); +#endif // USE_DOMAINTXFMRF } } } @@ -1134,6 +1157,7 @@ } } +#if USE_DOMAINTXFMRF void av1_domaintxfmrf_restoration_highbd(uint16_t *dgd, int width, int height, int stride, int param, int bit_depth, uint16_t *dst, int dst_stride, @@ -1212,6 +1236,7 @@ rst, bit_depth, dst, dst_stride); } } +#endif // USE_DOMAINTXFMRF static void loop_switchable_filter_highbd(uint8_t *data8, int width, int height, int stride, RestorationInternal *rst, @@ -1231,10 +1256,12 @@ } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_SGRPROJ) { loop_sgrproj_filter_tile_highbd(data, tile_idx, width, height, stride, rst, bit_depth, dst, dst_stride); +#if USE_DOMAINTXFMRF } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_DOMAINTXFMRF) { loop_domaintxfmrf_filter_tile_highbd(data, tile_idx, width, height, stride, rst, bit_depth, dst, dst_stride); +#endif // USE_DOMAINTXFMRF } } } @@ -1252,14 +1279,24 @@ const int uvstart = ystart >> cm->subsampling_y; int yend = end_mi_row << MI_SIZE_LOG2; int uvend = yend >> cm->subsampling_y; - restore_func_type restore_funcs[RESTORE_TYPES] = { NULL, loop_wiener_filter, - loop_sgrproj_filter, - loop_domaintxfmrf_filter, - loop_switchable_filter }; + restore_func_type restore_funcs[RESTORE_TYPES] = { + NULL, + loop_wiener_filter, + loop_sgrproj_filter, +#if USE_DOMAINTXFMRF + loop_domaintxfmrf_filter, +#endif // USE_DOMAINTXFMRF + loop_switchable_filter + }; #if CONFIG_AOM_HIGHBITDEPTH restore_func_highbd_type restore_funcs_highbd[RESTORE_TYPES] = { - NULL, loop_wiener_filter_highbd, loop_sgrproj_filter_highbd, - loop_domaintxfmrf_filter_highbd, loop_switchable_filter_highbd + NULL, + loop_wiener_filter_highbd, + loop_sgrproj_filter_highbd, +#if USE_DOMAINTXFMRF + loop_domaintxfmrf_filter_highbd, +#endif // USE_DOMAINTXFMRF + loop_switchable_filter_highbd }; #endif // CONFIG_AOM_HIGHBITDEPTH restore_func_type restore_func;
diff --git a/av1/common/restoration.h b/av1/common/restoration.h index 24455b4..2275c7c 100644 --- a/av1/common/restoration.h +++ b/av1/common/restoration.h
@@ -29,6 +29,7 @@ #define RESTORATION_TILEPELS_MAX \ (RESTORATION_TILESIZE_BIG * RESTORATION_TILESIZE_BIG * 9 / 4) +#if USE_DOMAINTXFMRF #define DOMAINTXFMRF_PARAMS_BITS 6 #define DOMAINTXFMRF_PARAMS (1 << DOMAINTXFMRF_PARAMS_BITS) #define DOMAINTXFMRF_SIGMA_SCALEBITS 4 @@ -49,13 +50,14 @@ #define DOMAINTXFMRF_EXTBUF_SIZE (RESTORATION_TILEPELS_MAX * sizeof(uint8_t)) #endif #define DOMAINTXFMRF_BITS (DOMAINTXFMRF_PARAMS_BITS) +#endif // USE_DOMAINTXFMRF // 4 32-bit buffers needed for the filter: // 2 for the restored versions of the frame and // 2 for each restoration operation #define SGRPROJ_TMPBUF_SIZE (RESTORATION_TILEPELS_MAX * 4 * sizeof(int32_t)) #define SGRPROJ_EXTBUF_SIZE (0) -#define SGRPROJ_PARAMS_BITS 3 +#define SGRPROJ_PARAMS_BITS 4 #define SGRPROJ_PARAMS (1 << SGRPROJ_PARAMS_BITS) // Precision bits for projection @@ -111,8 +113,13 @@ // Max of SGRPROJ_TMPBUF_SIZE, DOMAINTXFMRF_TMPBUF_SIZE, WIENER_TMPBUF_SIZE #define RESTORATION_TMPBUF_SIZE (SGRPROJ_TMPBUF_SIZE) + +#if USE_DOMAINTXFMRF // Max of SGRPROJ_EXTBUF_SIZE, DOMAINTXFMRF_EXTBUF_SIZE, WIENER_EXTBUF_SIZE #define RESTORATION_EXTBUF_SIZE (DOMAINTXFMRF_EXTBUF_SIZE) +#else +#define RESTORATION_EXTBUF_SIZE (WIENER_EXTBUF_SIZE) +#endif // USE_DOMAINTXFMRF // Check the assumptions of the existing code #if SUBPEL_TAPS != WIENER_WIN + 1 @@ -138,7 +145,9 @@ int xqd[2]; } SgrprojInfo; +#if USE_DOMAINTXFMRF typedef struct { int sigma_r; } DomaintxfmrfInfo; +#endif // USE_DOMAINTXFMRF typedef struct { RestorationType frame_restoration_type; @@ -147,8 +156,10 @@ WienerInfo *wiener_info; // Selfguided proj filter SgrprojInfo *sgrproj_info; +#if USE_DOMAINTXFMRF // Domain transform filter DomaintxfmrfInfo *domaintxfmrf_info; +#endif // USE_DOMAINTXFMRF } RestorationInfo; typedef struct { @@ -227,15 +238,19 @@ void extend_frame(uint8_t *data, int width, int height, int stride); void av1_selfguided_restoration(int32_t *dgd, int width, int height, int stride, int bit_depth, int r, int eps, int32_t *tmpbuf); +#if USE_DOMAINTXFMRF void av1_domaintxfmrf_restoration(uint8_t *dgd, int width, int height, int stride, int param, uint8_t *dst, int dst_stride, int32_t *tmpbuf); +#endif // USE_DOMAINTXFMRF #if CONFIG_AOM_HIGHBITDEPTH void extend_frame_highbd(uint16_t *data, int width, int height, int stride); +#if USE_DOMAINTXFMRF void av1_domaintxfmrf_restoration_highbd(uint16_t *dgd, int width, int height, int stride, int param, int bit_depth, uint16_t *dst, int dst_stride, int32_t *tmpbuf); +#endif // USE_DOMAINTXFMRF #endif // CONFIG_AOM_HIGHBITDEPTH void decode_xq(int *xqd, int *xq); void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index cf515c0..6d91cfe 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -2525,11 +2525,16 @@ int p; RestorationInfo *rsi = &cm->rst_info[0]; if (aom_rb_read_bit(rb)) { +#if USE_DOMAINTXFMRF if (aom_rb_read_bit(rb)) rsi->frame_restoration_type = (aom_rb_read_bit(rb) ? RESTORE_DOMAINTXFMRF : RESTORE_SGRPROJ); else rsi->frame_restoration_type = RESTORE_WIENER; +#else + rsi->frame_restoration_type = + aom_rb_read_bit(rb) ? RESTORE_SGRPROJ : RESTORE_WIENER; +#endif // USE_DOMAINTXFMRF } else { rsi->frame_restoration_type = aom_rb_read_bit(rb) ? RESTORE_SWITCHABLE : RESTORE_NONE; @@ -2578,11 +2583,13 @@ aom_read_literal(rb, SGRPROJ_PRJ_BITS, ACCT_STR) + SGRPROJ_PRJ_MIN1; } +#if USE_DOMAINTXFMRF static void read_domaintxfmrf_filter(DomaintxfmrfInfo *domaintxfmrf_info, aom_reader *rb) { domaintxfmrf_info->sigma_r = aom_read_literal(rb, DOMAINTXFMRF_PARAMS_BITS, ACCT_STR); } +#endif // USE_DOMAINTXFMRF static void decode_restoration(AV1_COMMON *cm, aom_reader *rb) { int i, p; @@ -2603,8 +2610,10 @@ read_wiener_filter(&rsi->wiener_info[i], rb); } else if (rsi->restoration_type[i] == RESTORE_SGRPROJ) { read_sgrproj_filter(&rsi->sgrproj_info[i], rb); +#if USE_DOMAINTXFMRF } else if (rsi->restoration_type[i] == RESTORE_DOMAINTXFMRF) { read_domaintxfmrf_filter(&rsi->domaintxfmrf_info[i], rb); +#endif // USE_DOMAINTXFMRF } } } else if (rsi->frame_restoration_type == RESTORE_WIENER) { @@ -2625,6 +2634,7 @@ rsi->restoration_type[i] = RESTORE_NONE; } } +#if USE_DOMAINTXFMRF } else if (rsi->frame_restoration_type == RESTORE_DOMAINTXFMRF) { for (i = 0; i < ntiles; ++i) { if (aom_read(rb, RESTORE_NONE_DOMAINTXFMRF_PROB, ACCT_STR)) { @@ -2634,6 +2644,7 @@ rsi->restoration_type[i] = RESTORE_NONE; } } +#endif // USE_DOMAINTXFMRF } } for (p = 1; p < MAX_MB_PLANE; ++p) {
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 2c87f1f..d218616 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -3324,6 +3324,7 @@ aom_wb_write_bit(wb, 1); aom_wb_write_bit(wb, 0); break; +#if USE_DOMAINTXFMRF case RESTORE_SGRPROJ: aom_wb_write_bit(wb, 1); aom_wb_write_bit(wb, 1); @@ -3334,6 +3335,12 @@ aom_wb_write_bit(wb, 1); aom_wb_write_bit(wb, 1); break; +#else + case RESTORE_SGRPROJ: + aom_wb_write_bit(wb, 1); + aom_wb_write_bit(wb, 1); + break; +#endif // USE_DOMAINTXFMRF case RESTORE_SWITCHABLE: aom_wb_write_bit(wb, 0); aom_wb_write_bit(wb, 1); @@ -3373,10 +3380,12 @@ SGRPROJ_PRJ_BITS); } +#if USE_DOMAINTXFMRF static void write_domaintxfmrf_filter(DomaintxfmrfInfo *domaintxfmrf_info, aom_writer *wb) { aom_write_literal(wb, domaintxfmrf_info->sigma_r, DOMAINTXFMRF_PARAMS_BITS); } +#endif // USE_DOMAINTXFMRF static void encode_restoration(AV1_COMMON *cm, aom_writer *wb) { int i, p; @@ -3398,8 +3407,10 @@ write_wiener_filter(&rsi->wiener_info[i], wb); } else if (rsi->restoration_type[i] == RESTORE_SGRPROJ) { write_sgrproj_filter(&rsi->sgrproj_info[i], wb); +#if USE_DOMAINTXFMRF } else if (rsi->restoration_type[i] == RESTORE_DOMAINTXFMRF) { write_domaintxfmrf_filter(&rsi->domaintxfmrf_info[i], wb); +#endif // USE_DOMAINTXFMRF } } } else if (rsi->frame_restoration_type == RESTORE_WIENER) { @@ -3418,6 +3429,7 @@ write_sgrproj_filter(&rsi->sgrproj_info[i], wb); } } +#if USE_DOMAINTXFMRF } else if (rsi->frame_restoration_type == RESTORE_DOMAINTXFMRF) { for (i = 0; i < ntiles; ++i) { aom_write(wb, rsi->restoration_type[i] != RESTORE_NONE, @@ -3426,6 +3438,7 @@ write_domaintxfmrf_filter(&rsi->domaintxfmrf_info[i], wb); } } +#endif // USE_DOMAINTXFMRF } } for (p = 1; p < MAX_MB_PLANE; ++p) {
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index b0858c0..6e44361 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -714,7 +714,7 @@ static void alloc_util_frame_buffers(AV1_COMP *cpi) { #if CONFIG_LOOP_RESTORATION - int i; + int i, extra_rstbuf_sz; #endif // CONFIG_LOOP_RESTORATION AV1_COMMON *const cm = &cpi->common; if (aom_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height, @@ -746,11 +746,16 @@ NULL, NULL)) aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, "Failed to allocate trial restored frame buffer"); - cpi->extra_rstbuf = - (uint8_t *)aom_realloc(cpi->extra_rstbuf, RESTORATION_EXTBUF_SIZE); - if (!cpi->extra_rstbuf) - aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, - "Failed to allocate extra rstbuf for restoration"); + extra_rstbuf_sz = RESTORATION_EXTBUF_SIZE; + if (extra_rstbuf_sz > 0) { + cpi->extra_rstbuf = + (uint8_t *)aom_realloc(cpi->extra_rstbuf, extra_rstbuf_sz); + if (!cpi->extra_rstbuf) + aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, + "Failed to allocate extra rstbuf for restoration"); + } else { + cpi->extra_rstbuf = NULL; + } for (i = 0; i < MAX_MB_PLANE; ++i) av1_alloc_restoration_struct(cm, &cpi->rst_search[i], cm->width, cm->height);
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c index ab24c90..bf34b77 100644 --- a/av1/encoder/pickrst.c +++ b/av1/encoder/pickrst.c
@@ -37,7 +37,11 @@ double *best_tile_cost, YV12_BUFFER_CONFIG *dst_frame); +#if USE_DOMAINTXFMRF const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 2, 3, 3, 2 }; +#else +const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 2, 2, 2 }; +#endif // USE_DOMAINTXFMRF static int64_t sse_restoration_tile(const YV12_BUFFER_CONFIG *src, const YV12_BUFFER_CONFIG *dst, @@ -418,6 +422,7 @@ return cost_sgrproj; } +#if USE_DOMAINTXFMRF static int64_t compute_sse(uint8_t *dgd, int width, int height, int dgd_stride, uint8_t *src, int src_stride) { int64_t sse = 0; @@ -640,6 +645,7 @@ aom_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show); return cost_domaintxfmrf; } +#endif // USE_DOMAINTXFMRF static double find_average(uint8_t *src, int h_start, int h_end, int v_start, int v_end, int stride) { @@ -1318,7 +1324,12 @@ void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, LPF_PICK_METHOD method) { static search_restore_type search_restore_fun[RESTORE_SWITCHABLE_TYPES] = { - search_norestore, search_wiener, search_sgrproj, search_domaintxfmrf, + search_norestore, + search_wiener, + search_sgrproj, +#if USE_DOMAINTXFMRF + search_domaintxfmrf, +#endif // USE_DOMAINTXFMRF }; AV1_COMMON *const cm = &cpi->common; struct loopfilter *const lf = &cm->lf; @@ -1417,11 +1428,17 @@ cm->rst_info[2].frame_restoration_type); */ /* +#if USE_DOMAINTXFMRF printf("Frame %d/%d frame_restore_type %d : %f %f %f %f %f\n", cm->current_video_frame, cm->show_frame, cm->rst_info[0].frame_restoration_type, cost_restore[0], - cost_restore[1], - cost_restore[2], cost_restore[3], cost_restore[4]); + cost_restore[1], cost_restore[2], cost_restore[3], cost_restore[4]); +#else + printf("Frame %d/%d frame_restore_type %d : %f %f %f %f\n", + cm->current_video_frame, cm->show_frame, + cm->rst_info[0].frame_restoration_type, cost_restore[0], + cost_restore[1], cost_restore[2], cost_restore[3]); +#endif // USE_DOMAINTXFMRF */ for (r = 0; r < RESTORE_SWITCHABLE_TYPES; r++) {