Move tile_ctx init & fix_interp_filter to finalize Move initialisation of tile_ctx and fix_interp_filter() from bitstream writer to finalize_encoded_frame in encoder.c This forms part of my efforts to remove implicit outputs from and side-effects of av1_pack_bitstream. This is part of wider restructuring and refactoring in order to achieve a clean API separation at the entry to the low-level encoder. BUG=aomedia:2244 Change-Id: Idacba15e5d0956772fa66e0b8ae13ae4e64f9d28
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 0adc212..38d5315 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -1178,7 +1178,6 @@ } } } - write_mb_interp_filter(cpi, xd, w); } } @@ -2073,29 +2072,6 @@ aom_wb_write_literal(wb, filter, LOG_SWITCHABLE_FILTERS); } -static void fix_interp_filter(AV1_COMMON *cm, FRAME_COUNTS *counts) { - if (cm->interp_filter == SWITCHABLE) { - // Check to see if only one of the filters is actually used - int count[SWITCHABLE_FILTERS]; - int i, j, c = 0; - for (i = 0; i < SWITCHABLE_FILTERS; ++i) { - count[i] = 0; - for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) - count[i] += counts->switchable_interp[j][i]; - c += (count[i] > 0); - } - if (c == 1) { - // Only one filter is used. So set the filter at frame level - for (i = 0; i < SWITCHABLE_FILTERS; ++i) { - if (count[i]) { - if (i == EIGHTTAP_REGULAR) cm->interp_filter = i; - break; - } - } - } - } -} - // Same function as write_uniform but writing to uncompresses header wb static void wb_write_uniform(struct aom_write_bit_buffer *wb, int n, int v) { const int l = get_unsigned_bits(n); @@ -3041,7 +3017,6 @@ if (!cm->cur_frame_force_integer_mv) aom_wb_write_bit(wb, cm->allow_high_precision_mv); - fix_interp_filter(cm, cpi->td.counts); write_frame_interp_filter(cm->interp_filter, wb); aom_wb_write_bit(wb, cm->switchable_motion_mode); if (frame_might_allow_ref_frame_mvs(cm)) { @@ -3507,8 +3482,6 @@ // Is CONFIG_EXT_TILE = 1, every tile in the row has a header, // even for the last one, unless no tiling is used at all. total_size += data_offset; - // Initialise tile context from the frame context - this_tile->tctx = *cm->fc; cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; mode_bc.allow_update_cdf = !cm->large_scale_tile; mode_bc.allow_update_cdf = @@ -3648,8 +3621,6 @@ // The last tile of the tile group does not have a header. if (!is_last_tile_in_tg) total_size += 4; - // Initialise tile context from the frame context - this_tile->tctx = *cm->fc; cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; mode_bc.allow_update_cdf = 1; mode_bc.allow_update_cdf =
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 2202bbb..af7d6e1 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -4543,6 +4543,29 @@ return refresh_mask; } +static void fix_interp_filter(InterpFilter *const interp_filter, + const FRAME_COUNTS *const counts) { + if (*interp_filter == SWITCHABLE) { + // Check to see if only one of the filters is actually used + int count[SWITCHABLE_FILTERS] = { 0 }; + int num_filters_used = 0; + for (int i = 0; i < SWITCHABLE_FILTERS; ++i) { + for (int j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) + count[i] += counts->switchable_interp[j][i]; + num_filters_used += (count[i] > 0); + } + if (num_filters_used == 1) { + // Only one filter is used. So set the filter at frame level + for (int i = 0; i < SWITCHABLE_FILTERS; ++i) { + if (count[i]) { + if (i == EIGHTTAP_REGULAR) *interp_filter = i; + break; + } + } + } + } +} + static void finalize_encoded_frame(AV1_COMP *const cpi) { AV1_COMMON *const cm = &cpi->common; CurrentFrame *const current_frame = &cm->current_frame; @@ -4602,6 +4625,16 @@ if (cm->film_grain_params.random_seed == 0) cm->film_grain_params.random_seed = 7391; } + + // Initialise all tiles' contexts from the global frame context + for (int tile_col = 0; tile_col < cm->tile_cols; tile_col++) { + for (int tile_row = 0; tile_row < cm->tile_rows; tile_row++) { + const int tile_idx = tile_row * cm->tile_cols + tile_col; + cpi->tile_data[tile_idx].tctx = *cm->fc; + } + } + + fix_interp_filter(&cm->interp_filter, cpi->td.counts); } // Called after encode_with_recode_loop() has just encoded a frame and packed