diff options
Diffstat (limited to 'third_party/aom/av1/encoder/bitstream.c')
-rw-r--r-- | third_party/aom/av1/encoder/bitstream.c | 2604 |
1 files changed, 1262 insertions, 1342 deletions
diff --git a/third_party/aom/av1/encoder/bitstream.c b/third_party/aom/av1/encoder/bitstream.c index f8378b14d..2e0abc186 100644 --- a/third_party/aom/av1/encoder/bitstream.c +++ b/third_party/aom/av1/encoder/bitstream.c @@ -26,7 +26,6 @@ #if CONFIG_CDEF #include "av1/common/cdef.h" -#include "av1/common/clpf.h" #endif // CONFIG_CDEF #include "av1/common/entropy.h" #include "av1/common/entropymode.h" @@ -61,21 +60,12 @@ #include "av1/encoder/pvq_encoder.h" #endif -static struct av1_token intra_mode_encodings[INTRA_MODES]; -static struct av1_token switchable_interp_encodings[SWITCHABLE_FILTERS]; -static struct av1_token partition_encodings[PARTITION_TYPES]; -#if CONFIG_EXT_INTER -static const struct av1_token - inter_compound_mode_encodings[INTER_COMPOUND_MODES] = { - { 2, 2 }, { 12, 4 }, { 52, 6 }, { 53, 6 }, - { 54, 6 }, { 55, 6 }, { 0, 1 }, { 7, 3 } - }; -#endif // CONFIG_EXT_INTER -#if CONFIG_PALETTE -static struct av1_token palette_size_encodings[PALETTE_SIZES]; -static struct av1_token palette_color_index_encodings[PALETTE_SIZES] - [PALETTE_COLORS]; -#endif // CONFIG_PALETTE +#define ENC_MISMATCH_DEBUG 0 + +#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF +static struct av1_token + inter_singleref_comp_mode_encodings[INTER_SINGLEREF_COMP_MODES]; +#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF #if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE static INLINE void write_uniform(aom_writer *w, int n, int v) { @@ -97,9 +87,6 @@ static struct av1_token ext_tx_intra_encodings[EXT_TX_SETS_INTRA][TX_TYPES]; #else static struct av1_token ext_tx_encodings[TX_TYPES]; #endif // CONFIG_EXT_TX -#if CONFIG_GLOBAL_MOTION -static struct av1_token global_motion_types_encodings[GLOBAL_TRANS_TYPES]; -#endif // CONFIG_GLOBAL_MOTION #if CONFIG_EXT_INTRA #if CONFIG_INTRA_INTERP static struct av1_token intra_filter_encodings[INTRA_FILTERS]; @@ -114,7 +101,9 @@ static struct av1_token compound_type_encodings[COMPOUND_TYPES]; #endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE #endif // CONFIG_EXT_INTER #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION -static struct av1_token motion_mode_encodings[MOTION_MODES]; +#if CONFIG_NCOBMC_ADAPT_WEIGHT +static struct av1_token ncobmc_mode_encodings[MAX_NCOBMC_MODES]; +#endif #endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION #if CONFIG_LOOP_RESTORATION static struct av1_token switchable_restore_encodings[RESTORE_SWITCHABLE_TYPES]; @@ -129,9 +118,9 @@ static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst, int *const tile_col_size_bytes); void av1_encode_token_init(void) { -#if CONFIG_EXT_TX || CONFIG_PALETTE +#if CONFIG_EXT_TX int s; -#endif // CONFIG_EXT_TX || CONFIG_PALETTE +#endif // CONFIG_EXT_TX #if CONFIG_EXT_TX for (s = 1; s < EXT_TX_SETS_INTER; ++s) { av1_tokens_from_tree(ext_tx_inter_encodings[s], av1_ext_tx_inter_tree[s]); @@ -142,17 +131,6 @@ void av1_encode_token_init(void) { #else av1_tokens_from_tree(ext_tx_encodings, av1_ext_tx_tree); #endif // CONFIG_EXT_TX - av1_tokens_from_tree(intra_mode_encodings, av1_intra_mode_tree); - av1_tokens_from_tree(switchable_interp_encodings, av1_switchable_interp_tree); - av1_tokens_from_tree(partition_encodings, av1_partition_tree); - -#if CONFIG_PALETTE - av1_tokens_from_tree(palette_size_encodings, av1_palette_size_tree); - for (s = 0; s < PALETTE_SIZES; ++s) { - av1_tokens_from_tree(palette_color_index_encodings[s], - av1_palette_color_index_tree[s]); - } -#endif // CONFIG_PALETTE #if CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP av1_tokens_from_tree(intra_filter_encodings, av1_intra_filter_tree); @@ -161,17 +139,19 @@ void av1_encode_token_init(void) { #if CONFIG_INTERINTRA av1_tokens_from_tree(interintra_mode_encodings, av1_interintra_mode_tree); #endif // CONFIG_INTERINTRA +#if CONFIG_COMPOUND_SINGLEREF + av1_tokens_from_tree(inter_singleref_comp_mode_encodings, + av1_inter_singleref_comp_mode_tree); +#endif // CONFIG_COMPOUND_SINGLEREF #if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE av1_tokens_from_tree(compound_type_encodings, av1_compound_type_tree); #endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE #endif // CONFIG_EXT_INTER #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION - av1_tokens_from_tree(motion_mode_encodings, av1_motion_mode_tree); +#if CONFIG_NCOBMC_ADAPT_WEIGHT + av1_tokens_from_tree(ncobmc_mode_encodings, av1_ncobmc_mode_tree); +#endif #endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION -#if CONFIG_GLOBAL_MOTION - av1_tokens_from_tree(global_motion_types_encodings, - av1_global_motion_types_tree); -#endif // CONFIG_GLOBAL_MOTION #if CONFIG_LOOP_RESTORATION av1_tokens_from_tree(switchable_restore_encodings, av1_switchable_restore_tree); @@ -195,10 +175,6 @@ void av1_encode_token_init(void) { #else av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, av1_ext_tx_tree); #endif - av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv, - av1_intra_mode_tree); - av1_indices_from_tree(av1_inter_mode_ind, av1_inter_mode_inv, - av1_inter_mode_tree); } static void write_intra_mode_kf(const AV1_COMMON *cm, FRAME_CONTEXT *frame_ctx, @@ -214,65 +190,72 @@ static void write_intra_mode_kf(const AV1_COMMON *cm, FRAME_CONTEXT *frame_ctx, (void)cm; } -#if CONFIG_EXT_INTER && CONFIG_INTERINTRA -static void write_interintra_mode(aom_writer *w, INTERINTRA_MODE mode, - const aom_prob *probs) { - av1_write_token(w, av1_interintra_mode_tree, probs, - &interintra_mode_encodings[mode]); -} -#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA - static void write_inter_mode(aom_writer *w, PREDICTION_MODE mode, FRAME_CONTEXT *ec_ctx, const int16_t mode_ctx) { const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK; - const aom_prob newmv_prob = ec_ctx->newmv_prob[newmv_ctx]; - aom_write(w, mode != NEWMV, newmv_prob); +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, mode != NEWMV, ec_ctx->newmv_cdf[newmv_ctx], 2); +#else + aom_write(w, mode != NEWMV, ec_ctx->newmv_prob[newmv_ctx]); +#endif if (mode != NEWMV) { - const int16_t zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK; - const aom_prob zeromv_prob = ec_ctx->zeromv_prob[zeromv_ctx]; - if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) { assert(mode == ZEROMV); return; } - aom_write(w, mode != ZEROMV, zeromv_prob); + const int16_t zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK; +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, mode != ZEROMV, ec_ctx->zeromv_cdf[zeromv_ctx], 2); +#else + aom_write(w, mode != ZEROMV, ec_ctx->zeromv_prob[zeromv_ctx]); +#endif if (mode != ZEROMV) { int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK; - aom_prob refmv_prob; if (mode_ctx & (1 << SKIP_NEARESTMV_OFFSET)) refmv_ctx = 6; if (mode_ctx & (1 << SKIP_NEARMV_OFFSET)) refmv_ctx = 7; if (mode_ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) refmv_ctx = 8; - - refmv_prob = ec_ctx->refmv_prob[refmv_ctx]; - aom_write(w, mode != NEARESTMV, refmv_prob); +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, mode != NEARESTMV, ec_ctx->refmv_cdf[refmv_ctx], 2); +#else + aom_write(w, mode != NEARESTMV, ec_ctx->refmv_prob[refmv_ctx]); +#endif } } } -static void write_drl_idx(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi, +static void write_drl_idx(FRAME_CONTEXT *ec_ctx, const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext, aom_writer *w) { uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame); assert(mbmi->ref_mv_idx < 3); #if CONFIG_EXT_INTER +#if CONFIG_COMPOUND_SINGLEREF + if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV || + mbmi->mode == SR_NEW_NEWMV) { +#else // !CONFIG_COMPOUND_SINGLEREF if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) { -#else +#endif // CONFIG_COMPOUND_SINGLEREF +#else // !CONFIG_EXT_INTER if (mbmi->mode == NEWMV) { -#endif +#endif // CONFIG_EXT_INTER int idx; for (idx = 0; idx < 2; ++idx) { if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) { uint8_t drl_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx); - aom_prob drl_prob = cm->fc->drl_prob[drl_ctx]; - aom_write(w, mbmi->ref_mv_idx != idx, drl_prob); +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, mbmi->ref_mv_idx != idx, ec_ctx->drl_cdf[drl_ctx], + 2); +#else + aom_write(w, mbmi->ref_mv_idx != idx, ec_ctx->drl_prob[drl_ctx]); +#endif if (mbmi->ref_mv_idx == idx) return; } } @@ -286,9 +269,12 @@ static void write_drl_idx(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi, if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) { uint8_t drl_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx); - aom_prob drl_prob = cm->fc->drl_prob[drl_ctx]; - - aom_write(w, mbmi->ref_mv_idx != (idx - 1), drl_prob); +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, mbmi->ref_mv_idx != (idx - 1), + ec_ctx->drl_cdf[drl_ctx], 2); +#else + aom_write(w, mbmi->ref_mv_idx != (idx - 1), ec_ctx->drl_prob[drl_ctx]); +#endif if (mbmi->ref_mv_idx == (idx - 1)) return; } } @@ -297,16 +283,28 @@ static void write_drl_idx(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi, } #if CONFIG_EXT_INTER -static void write_inter_compound_mode(AV1_COMMON *cm, aom_writer *w, - PREDICTION_MODE mode, +static void write_inter_compound_mode(AV1_COMMON *cm, MACROBLOCKD *xd, + aom_writer *w, PREDICTION_MODE mode, const int16_t mode_ctx) { - const aom_prob *const inter_compound_probs = - cm->fc->inter_compound_mode_probs[mode_ctx]; - assert(is_inter_compound_mode(mode)); - av1_write_token(w, av1_inter_compound_mode_tree, inter_compound_probs, - &inter_compound_mode_encodings[INTER_COMPOUND_OFFSET(mode)]); + (void)cm; + aom_write_symbol(w, INTER_COMPOUND_OFFSET(mode), + xd->tile_ctx->inter_compound_mode_cdf[mode_ctx], + INTER_COMPOUND_MODES); +} + +#if CONFIG_COMPOUND_SINGLEREF +static void write_inter_singleref_comp_mode(MACROBLOCKD *xd, aom_writer *w, + PREDICTION_MODE mode, + const int16_t mode_ctx) { + assert(is_inter_singleref_comp_mode(mode)); + aom_cdf_prob *const inter_singleref_comp_cdf = + xd->tile_ctx->inter_singleref_comp_mode_cdf[mode_ctx]; + + aom_write_symbol(w, INTER_SINGLEREF_COMP_OFFSET(mode), + inter_singleref_comp_cdf, INTER_SINGLEREF_COMP_MODES); } +#endif // CONFIG_COMPOUND_SINGLEREF #endif // CONFIG_EXT_INTER static void encode_unsigned_max(struct aom_write_bit_buffer *wb, int data, @@ -314,11 +312,10 @@ static void encode_unsigned_max(struct aom_write_bit_buffer *wb, int data, aom_wb_write_literal(wb, data, get_unsigned_bits(max)); } -#if !CONFIG_EC_ADAPT || \ - (CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION || CONFIG_EXT_INTER) +#if CONFIG_NCOBMC_ADAPT_WEIGHT static void prob_diff_update(const aom_tree_index *tree, aom_prob probs[/*n - 1*/], - const unsigned int counts[/*n - 1*/], int n, + const unsigned int counts[/* n */], int n, int probwt, aom_writer *w) { int i; unsigned int branch_ct[32][2]; @@ -332,31 +329,15 @@ static void prob_diff_update(const aom_tree_index *tree, } #endif -#if CONFIG_EXT_INTER || !CONFIG_EC_ADAPT -static int prob_diff_update_savings(const aom_tree_index *tree, - aom_prob probs[/*n - 1*/], - const unsigned int counts[/*n - 1*/], int n, - int probwt) { - int i; - unsigned int branch_ct[32][2]; - int savings = 0; - - // Assuming max number of probabilities <= 32 - assert(n <= 32); - av1_tree_probs_from_distribution(tree, branch_ct, counts); - for (i = 0; i < n - 1; ++i) { - savings += - av1_cond_prob_diff_update_savings(&probs[i], branch_ct[i], probwt); - } - return savings; -} -#endif // CONFIG_EXT_INTER || !CONFIG_EC_ADAPT - #if CONFIG_VAR_TX -static void write_tx_size_vartx(const AV1_COMMON *cm, const MACROBLOCKD *xd, +static void write_tx_size_vartx(const AV1_COMMON *cm, MACROBLOCKD *xd, const MB_MODE_INFO *mbmi, TX_SIZE tx_size, int depth, int blk_row, int blk_col, aom_writer *w) { +#if CONFIG_NEW_MULTISYMBOL + FRAME_CONTEXT *ec_ctx = xd->tile_ctx; + (void)cm; +#endif const int tx_row = blk_row >> 1; const int tx_col = blk_col >> 1; const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0); @@ -374,16 +355,31 @@ static void write_tx_size_vartx(const AV1_COMMON *cm, const MACROBLOCKD *xd, return; } +#if CONFIG_RECT_TX_EXT + if (tx_size == mbmi->inter_tx_size[tx_row][tx_col] || + mbmi->tx_size == quarter_txsize_lookup[mbmi->sb_type]) { +#else if (tx_size == mbmi->inter_tx_size[tx_row][tx_col]) { +#endif +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, 0, ec_ctx->txfm_partition_cdf[ctx], 2); +#else aom_write(w, 0, cm->fc->txfm_partition_prob[ctx]); +#endif + txfm_partition_update(xd->above_txfm_context + blk_col, xd->left_txfm_context + blk_row, tx_size, tx_size); + // TODO(yuec): set correct txfm partition update for qttx } else { const TX_SIZE sub_txs = sub_tx_size_map[tx_size]; const int bsl = tx_size_wide_unit[sub_txs]; int i; +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, 1, ec_ctx->txfm_partition_cdf[ctx], 2); +#else aom_write(w, 1, cm->fc->txfm_partition_prob[ctx]); +#endif if (tx_size == TX_8X8) { txfm_partition_update(xd->above_txfm_context + blk_col, @@ -401,6 +397,7 @@ static void write_tx_size_vartx(const AV1_COMMON *cm, const MACROBLOCKD *xd, } } +#if !CONFIG_NEW_MULTISYMBOL static void update_txfm_partition_probs(AV1_COMMON *cm, aom_writer *w, FRAME_COUNTS *counts, int probwt) { int k; @@ -408,18 +405,15 @@ static void update_txfm_partition_probs(AV1_COMMON *cm, aom_writer *w, av1_cond_prob_diff_update(w, &cm->fc->txfm_partition_prob[k], counts->txfm_partition[k], probwt); } +#endif // CONFIG_NEW_MULTISYMBOL #endif static void write_selected_tx_size(const AV1_COMMON *cm, const MACROBLOCKD *xd, aom_writer *w) { const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const BLOCK_SIZE bsize = mbmi->sb_type; -#if CONFIG_EC_ADAPT FRAME_CONTEXT *ec_ctx = xd->tile_ctx; (void)cm; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; -#endif // For sub8x8 blocks the tx_size symbol does not need to be sent #if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX if (bsize > BLOCK_4X4) { @@ -439,22 +433,19 @@ static void write_selected_tx_size(const AV1_COMMON *cm, const MACROBLOCKD *xd, aom_write_symbol(w, depth, ec_ctx->tx_size_cdf[tx_size_cat][tx_size_ctx], tx_size_cat + 2); -#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT +#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX) if (is_quarter_tx_allowed(xd, mbmi, is_inter) && tx_size != coded_tx_size) aom_write(w, tx_size == quarter_txsize_lookup[bsize], cm->fc->quarter_tx_size_prob); -#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT +#endif } } +#if !CONFIG_NEW_MULTISYMBOL static void update_inter_mode_probs(AV1_COMMON *cm, aom_writer *w, FRAME_COUNTS *counts) { int i; -#if CONFIG_TILE_GROUPS const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i) av1_cond_prob_diff_update(w, &cm->fc->newmv_prob[i], counts->newmv_mode[i], probwt); @@ -468,31 +459,7 @@ static void update_inter_mode_probs(AV1_COMMON *cm, aom_writer *w, av1_cond_prob_diff_update(w, &cm->fc->drl_prob[i], counts->drl_mode[i], probwt); } - -#if CONFIG_EXT_INTER -static void update_inter_compound_mode_probs(AV1_COMMON *cm, int probwt, - aom_writer *w) { - const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) - - av1_cost_zero(GROUP_DIFF_UPDATE_PROB); - int i; - int savings = 0; - int do_update = 0; - for (i = 0; i < INTER_MODE_CONTEXTS; ++i) { - savings += prob_diff_update_savings( - av1_inter_compound_mode_tree, cm->fc->inter_compound_mode_probs[i], - cm->counts.inter_compound_mode[i], INTER_COMPOUND_MODES, probwt); - } - do_update = savings > savings_thresh; - aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB); - if (do_update) { - for (i = 0; i < INTER_MODE_CONTEXTS; ++i) { - prob_diff_update( - av1_inter_compound_mode_tree, cm->fc->inter_compound_mode_probs[i], - cm->counts.inter_compound_mode[i], INTER_COMPOUND_MODES, probwt, w); - } - } -} -#endif // CONFIG_EXT_INTER +#endif static int write_skip(const AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id, const MODE_INFO *mi, aom_writer *w) { @@ -500,35 +467,100 @@ static int write_skip(const AV1_COMMON *cm, const MACROBLOCKD *xd, return 1; } else { const int skip = mi->mbmi.skip; +#if CONFIG_NEW_MULTISYMBOL + FRAME_CONTEXT *ec_ctx = xd->tile_ctx; + const int ctx = av1_get_skip_context(xd); + aom_write_symbol(w, skip, ec_ctx->skip_cdfs[ctx], 2); +#else aom_write(w, skip, av1_get_skip_prob(cm, xd)); +#endif return skip; } } +static void write_is_inter(const AV1_COMMON *cm, const MACROBLOCKD *xd, + int segment_id, aom_writer *w, const int is_inter) { + if (!segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { +#if CONFIG_NEW_MULTISYMBOL + FRAME_CONTEXT *ec_ctx = xd->tile_ctx; + const int ctx = av1_get_intra_inter_context(xd); + aom_write_symbol(w, is_inter, ec_ctx->intra_inter_cdf[ctx], 2); +#else + aom_write(w, is_inter, av1_get_intra_inter_prob(cm, xd)); +#endif + } +} + #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION -static void write_motion_mode(const AV1_COMMON *cm, const MODE_INFO *mi, - aom_writer *w) { +static void write_motion_mode(const AV1_COMMON *cm, MACROBLOCKD *xd, + const MODE_INFO *mi, aom_writer *w) { const MB_MODE_INFO *mbmi = &mi->mbmi; + +#if CONFIG_NCOBMC_ADAPT_WEIGHT + MOTION_MODE last_motion_mode_allowed = + motion_mode_allowed_wrapper(0, +#if CONFIG_GLOBAL_MOTION + 0, cm->global_motion, +#endif // CONFIG_GLOBAL_MOTION + mi); +#else MOTION_MODE last_motion_mode_allowed = motion_mode_allowed( -#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION +#if CONFIG_GLOBAL_MOTION 0, cm->global_motion, -#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION +#endif // CONFIG_GLOBAL_MOTION +#if CONFIG_WARPED_MOTION + xd, +#endif mi); - +#endif // CONFIG_NCOBMC_ADAPT_WEIGHT if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return; #if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION if (last_motion_mode_allowed == OBMC_CAUSAL) { +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, mbmi->motion_mode == OBMC_CAUSAL, + xd->tile_ctx->obmc_cdf[mbmi->sb_type], 2); +#else aom_write(w, mbmi->motion_mode == OBMC_CAUSAL, cm->fc->obmc_prob[mbmi->sb_type]); +#endif } else { #endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION - av1_write_token(w, av1_motion_mode_tree, - cm->fc->motion_mode_prob[mbmi->sb_type], - &motion_mode_encodings[mbmi->motion_mode]); + aom_write_symbol(w, mbmi->motion_mode, + xd->tile_ctx->motion_mode_cdf[mbmi->sb_type], + MOTION_MODES); #if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION } #endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION } + +#if CONFIG_NCOBMC_ADAPT_WEIGHT +static void write_ncobmc_mode(MACROBLOCKD *xd, const MODE_INFO *mi, + aom_writer *w) { + const MB_MODE_INFO *mbmi = &mi->mbmi; + ADAPT_OVERLAP_BLOCK ao_block = adapt_overlap_block_lookup[mbmi->sb_type]; + if (mbmi->motion_mode != NCOBMC_ADAPT_WEIGHT) return; + +#ifndef TRAINING_WEIGHTS + aom_write_symbol(w, mbmi->ncobmc_mode[0], + xd->tile_ctx->ncobmc_mode_cdf[ao_block], MAX_NCOBMC_MODES); + if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) { + aom_write_symbol(w, mbmi->ncobmc_mode[1], + xd->tile_ctx->ncobmc_mode_cdf[ao_block], MAX_NCOBMC_MODES); + } +#else + int block; + for (block = 0; block < 4; ++block) + aom_write_symbol(w, mbmi->ncobmc_mode[0][block], + xd->tile_ctx->ncobmc_mode_cdf[ao_block], MAX_NCOBMC_MODES); + if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) { + for (block = 0; block < 4; ++block) + aom_write_symbol(w, mbmi->ncobmc_mode[1][block], + xd->tile_ctx->ncobmc_mode_cdf[ao_block], + MAX_NCOBMC_MODES); + } +#endif +} +#endif #endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION #if CONFIG_DELTA_Q @@ -538,13 +570,8 @@ static void write_delta_qindex(const AV1_COMMON *cm, const MACROBLOCKD *xd, int abs = sign ? -delta_qindex : delta_qindex; int rem_bits, thr; int smallval = abs < DELTA_Q_SMALL ? 1 : 0; -#if CONFIG_EC_ADAPT FRAME_CONTEXT *ec_ctx = xd->tile_ctx; (void)cm; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; - (void)xd; -#endif aom_write_symbol(w, AOMMIN(abs, DELTA_Q_SMALL), ec_ctx->delta_q_cdf, DELTA_Q_PROBS + 1); @@ -560,25 +587,6 @@ static void write_delta_qindex(const AV1_COMMON *cm, const MACROBLOCKD *xd, } } -#if !CONFIG_EC_ADAPT -static void update_delta_q_probs(AV1_COMMON *cm, aom_writer *w, - FRAME_COUNTS *counts) { - int k; -#if CONFIG_TILE_GROUPS - const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif -#if CONFIG_EXT_DELTA_Q - if (!cm->delta_q_present_flag) return; -#endif // CONFIG_EXT_DELTA_Q - for (k = 0; k < DELTA_Q_PROBS; ++k) { - av1_cond_prob_diff_update(w, &cm->fc->delta_q_prob[k], counts->delta_q[k], - probwt); - } -} -#endif // CONFIG_EC_ADAPT - #if CONFIG_EXT_DELTA_Q static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd, int delta_lflevel, aom_writer *w) { @@ -586,13 +594,8 @@ static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd, int abs = sign ? -delta_lflevel : delta_lflevel; int rem_bits, thr; int smallval = abs < DELTA_LF_SMALL ? 1 : 0; -#if CONFIG_EC_ADAPT FRAME_CONTEXT *ec_ctx = xd->tile_ctx; (void)cm; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; - (void)xd; -#endif aom_write_symbol(w, AOMMIN(abs, DELTA_LF_SMALL), ec_ctx->delta_lf_cdf, DELTA_LF_PROBS + 1); @@ -607,178 +610,32 @@ static void write_delta_lflevel(const AV1_COMMON *cm, const MACROBLOCKD *xd, aom_write_bit(w, sign); } } - -#if !CONFIG_EC_ADAPT -static void update_delta_lf_probs(AV1_COMMON *cm, aom_writer *w, - FRAME_COUNTS *counts) { - int k; -#if CONFIG_TILE_GROUPS - const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif - if (!cm->delta_lf_present_flag) return; - for (k = 0; k < DELTA_LF_PROBS; ++k) { - av1_cond_prob_diff_update(w, &cm->fc->delta_lf_prob[k], counts->delta_lf[k], - probwt); - } -} -#endif // CONFIG_EC_ADAPT #endif // CONFIG_EXT_DELTA_Q #endif // CONFIG_DELTA_Q +#if !CONFIG_NEW_MULTISYMBOL static void update_skip_probs(AV1_COMMON *cm, aom_writer *w, FRAME_COUNTS *counts) { int k; -#if CONFIG_TILE_GROUPS const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif for (k = 0; k < SKIP_CONTEXTS; ++k) { av1_cond_prob_diff_update(w, &cm->fc->skip_probs[k], counts->skip[k], probwt); } } - -#if !CONFIG_EC_ADAPT -static void update_switchable_interp_probs(AV1_COMMON *cm, aom_writer *w, - FRAME_COUNTS *counts) { - int j; - for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) { -#if CONFIG_TILE_GROUPS - const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif - prob_diff_update( - av1_switchable_interp_tree, cm->fc->switchable_interp_prob[j], - counts->switchable_interp[j], SWITCHABLE_FILTERS, probwt, w); - } -} -#endif - -#if !CONFIG_EC_ADAPT -#if CONFIG_EXT_TX -static void update_ext_tx_probs(AV1_COMMON *cm, aom_writer *w) { - const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) - - av1_cost_zero(GROUP_DIFF_UPDATE_PROB); - int i, j; - int s; -#if CONFIG_TILE_GROUPS - const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif - for (s = 1; s < EXT_TX_SETS_INTER; ++s) { - int savings = 0; - int do_update = 0; - for (i = TX_4X4; i < EXT_TX_SIZES; ++i) { - if (!use_inter_ext_tx_for_txsize[s][i]) continue; - savings += prob_diff_update_savings( - av1_ext_tx_inter_tree[s], cm->fc->inter_ext_tx_prob[s][i], - cm->counts.inter_ext_tx[s][i], - num_ext_tx_set[ext_tx_set_type_inter[s]], probwt); - } - do_update = savings > savings_thresh; - aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB); - if (do_update) { - for (i = TX_4X4; i < EXT_TX_SIZES; ++i) { - if (!use_inter_ext_tx_for_txsize[s][i]) continue; - prob_diff_update(av1_ext_tx_inter_tree[s], - cm->fc->inter_ext_tx_prob[s][i], - cm->counts.inter_ext_tx[s][i], - num_ext_tx_set[ext_tx_set_type_inter[s]], probwt, w); - } - } - } - - for (s = 1; s < EXT_TX_SETS_INTRA; ++s) { - int savings = 0; - int do_update = 0; - for (i = TX_4X4; i < EXT_TX_SIZES; ++i) { - if (!use_intra_ext_tx_for_txsize[s][i]) continue; - for (j = 0; j < INTRA_MODES; ++j) - savings += prob_diff_update_savings( - av1_ext_tx_intra_tree[s], cm->fc->intra_ext_tx_prob[s][i][j], - cm->counts.intra_ext_tx[s][i][j], - num_ext_tx_set[ext_tx_set_type_intra[s]], probwt); - } - do_update = savings > savings_thresh; - aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB); - if (do_update) { - for (i = TX_4X4; i < EXT_TX_SIZES; ++i) { - if (!use_intra_ext_tx_for_txsize[s][i]) continue; - for (j = 0; j < INTRA_MODES; ++j) - prob_diff_update(av1_ext_tx_intra_tree[s], - cm->fc->intra_ext_tx_prob[s][i][j], - cm->counts.intra_ext_tx[s][i][j], - num_ext_tx_set[ext_tx_set_type_intra[s]], probwt, w); - } - } - } -} - -#else -static void update_ext_tx_probs(AV1_COMMON *cm, aom_writer *w) { - const int savings_thresh = av1_cost_one(GROUP_DIFF_UPDATE_PROB) - - av1_cost_zero(GROUP_DIFF_UPDATE_PROB); - int i, j; - - int savings = 0; - int do_update = 0; -#if CONFIG_TILE_GROUPS - const int probwt = cm->num_tg; -#else - const int probwt = 1; #endif - for (i = TX_4X4; i < EXT_TX_SIZES; ++i) { - for (j = 0; j < TX_TYPES; ++j) - savings += prob_diff_update_savings( - av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j], - cm->counts.intra_ext_tx[i][j], TX_TYPES, probwt); - } - do_update = savings > savings_thresh; - aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB); - if (do_update) { - for (i = TX_4X4; i < EXT_TX_SIZES; ++i) { - for (j = 0; j < TX_TYPES; ++j) { - prob_diff_update(av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j], - cm->counts.intra_ext_tx[i][j], TX_TYPES, probwt, w); - } - } - } - savings = 0; - for (i = TX_4X4; i < EXT_TX_SIZES; ++i) { - savings += - prob_diff_update_savings(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i], - cm->counts.inter_ext_tx[i], TX_TYPES, probwt); - } - do_update = savings > savings_thresh; - aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB); - if (do_update) { - for (i = TX_4X4; i < EXT_TX_SIZES; ++i) { - prob_diff_update(av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[i], - cm->counts.inter_ext_tx[i], TX_TYPES, probwt, w); - } - } -} -#endif // CONFIG_EXT_TX -#endif // !CONFIG_EC_ADAPT #if CONFIG_PALETTE static void pack_palette_tokens(aom_writer *w, const TOKENEXTRA **tp, int n, int num) { - int i; const TOKENEXTRA *p = *tp; - - for (i = 0; i < num; ++i) { - av1_write_token( - w, av1_palette_color_index_tree[n - PALETTE_MIN_SIZE], p->context_tree, - &palette_color_index_encodings[n - PALETTE_MIN_SIZE][p->token]); + write_uniform(w, n, p->token); // The first color index. + ++p; + --num; + for (int i = 0; i < num; ++i) { + aom_write_symbol(w, p->token, p->palette_cdf, n); ++p; } - *tp = p; } #endif // CONFIG_PALETTE @@ -930,8 +787,16 @@ static void pack_pvq_tokens(aom_writer *w, MACROBLOCK *const x, int max_blocks_wide; int max_blocks_high; int step = (1 << tx_size); + +#if CONFIG_CHROMA_SUB8X8 + const BLOCK_SIZE plane_bsize = + AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd)); +#elif CONFIG_CB4X4 + const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); +#else const BLOCK_SIZE plane_bsize = - get_plane_block_size(AOMMAX(bsize, BLOCK_8X8), pd); + get_plane_block_size(AOMMAX(BLOCK_8X8, bsize), pd); +#endif adapt = x->daala_enc.state.adapt; @@ -1030,7 +895,8 @@ static void pack_txb_tokens(aom_writer *w, uint16_t eob = x->mbmi_ext->eobs[plane][block]; TXB_CTX txb_ctx = { x->mbmi_ext->txb_skip_ctx[plane][block], x->mbmi_ext->dc_sign_ctx[plane][block] }; - av1_write_coeffs_txb(cm, xd, w, block, plane, tcoeff, eob, &txb_ctx); + av1_write_coeffs_txb(cm, xd, w, blk_row, blk_col, block, plane, tx_size, + tcoeff, eob, &txb_ctx); #else pack_pvq_tokens(w, x, xd, plane, bsize, tx_size); #endif @@ -1103,15 +969,30 @@ static void pack_txb_tokens(aom_writer *w, const TOKENEXTRA **tp, token_stats->cost += tmp_token_stats.cost; #endif } else { +#if CONFIG_RECT_TX_EXT + int is_qttx = plane_tx_size == quarter_txsize_lookup[plane_bsize]; + const TX_SIZE sub_txs = is_qttx ? plane_tx_size : sub_tx_size_map[tx_size]; +#else const TX_SIZE sub_txs = sub_tx_size_map[tx_size]; +#endif const int bsl = tx_size_wide_unit[sub_txs]; int i; assert(bsl > 0); for (i = 0; i < 4; ++i) { +#if CONFIG_RECT_TX_EXT + int is_wide_tx = tx_size_wide_unit[sub_txs] > tx_size_high_unit[sub_txs]; + const int offsetr = + is_qttx ? (is_wide_tx ? i * tx_size_high_unit[sub_txs] : 0) + : blk_row + (i >> 1) * bsl; + const int offsetc = + is_qttx ? (is_wide_tx ? 0 : i * tx_size_wide_unit[sub_txs]) + : blk_col + (i & 0x01) * bsl; +#else const int offsetr = blk_row + (i >> 1) * bsl; const int offsetc = blk_col + (i & 0x01) * bsl; +#endif const int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs]; if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue; @@ -1136,6 +1017,14 @@ static void write_segment_id(aom_writer *w, const struct segmentation *seg, } } +#if CONFIG_NEW_MULTISYMBOL +#define WRITE_REF_BIT(bname, pname) \ + aom_write_symbol(w, bname, av1_get_pred_cdf_##pname(cm, xd), 2) +#else +#define WRITE_REF_BIT(bname, pname) \ + aom_write(w, bname, av1_get_pred_prob_##pname(cm, xd)) +#endif + // This function encodes the reference frame static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd, aom_writer *w) { @@ -1153,66 +1042,183 @@ static void write_ref_frames(const AV1_COMMON *cm, const MACROBLOCKD *xd, // does the feature use compound prediction or not // (if not specified at the frame/segment level) if (cm->reference_mode == REFERENCE_MODE_SELECT) { -#if SUB8X8_COMP_REF - aom_write(w, is_compound, av1_get_reference_mode_prob(cm, xd)); -#else +#if !SUB8X8_COMP_REF if (mbmi->sb_type != BLOCK_4X4) - aom_write(w, is_compound, av1_get_reference_mode_prob(cm, xd)); +#endif +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, is_compound, av1_get_reference_mode_cdf(cm, xd), 2); +#else + aom_write(w, is_compound, av1_get_reference_mode_prob(cm, xd)); #endif } else { assert((!is_compound) == (cm->reference_mode == SINGLE_REFERENCE)); } if (is_compound) { +#if CONFIG_EXT_COMP_REFS + const COMP_REFERENCE_TYPE comp_ref_type = has_uni_comp_refs(mbmi) + ? UNIDIR_COMP_REFERENCE + : BIDIR_COMP_REFERENCE; +#if USE_UNI_COMP_REFS +#if CONFIG_VAR_REFS + if ((L_OR_L2(cm) || L3_OR_G(cm)) && BWD_OR_ALT(cm)) + if (L_AND_L2(cm) || L_AND_L3(cm) || L_AND_G(cm) || BWD_AND_ALT(cm)) +#endif // CONFIG_VAR_REFS + aom_write(w, comp_ref_type, av1_get_comp_reference_type_prob(cm, xd)); +#if CONFIG_VAR_REFS + else + assert(comp_ref_type == BIDIR_COMP_REFERENCE); + else + assert(comp_ref_type == UNIDIR_COMP_REFERENCE); +#endif // CONFIG_VAR_REFS +#else // !USE_UNI_COMP_REFS + // NOTE: uni-directional comp refs disabled + assert(comp_ref_type == BIDIR_COMP_REFERENCE); +#endif // USE_UNI_COMP_REFS + + if (comp_ref_type == UNIDIR_COMP_REFERENCE) { + const int bit = mbmi->ref_frame[0] == BWDREF_FRAME; +#if CONFIG_VAR_REFS + if ((L_AND_L2(cm) || L_AND_L3(cm) || L_AND_G(cm)) && BWD_AND_ALT(cm)) +#endif // CONFIG_VAR_REFS + aom_write(w, bit, av1_get_pred_prob_uni_comp_ref_p(cm, xd)); + + if (!bit) { + assert(mbmi->ref_frame[0] == LAST_FRAME); +#if CONFIG_VAR_REFS + if (L_AND_L2(cm) && (L_AND_L3(cm) || L_AND_G(cm))) { +#endif // CONFIG_VAR_REFS + const int bit1 = mbmi->ref_frame[1] == LAST3_FRAME || + mbmi->ref_frame[1] == GOLDEN_FRAME; + aom_write(w, bit1, av1_get_pred_prob_uni_comp_ref_p1(cm, xd)); + + if (bit1) { +#if CONFIG_VAR_REFS + if (L_AND_L3(cm) && L_AND_G(cm)) { +#endif // CONFIG_VAR_REFS + const int bit2 = mbmi->ref_frame[1] == GOLDEN_FRAME; + aom_write(w, bit2, av1_get_pred_prob_uni_comp_ref_p2(cm, xd)); +#if CONFIG_VAR_REFS + } +#endif // CONFIG_VAR_REFS + } +#if CONFIG_VAR_REFS + } +#endif // CONFIG_VAR_REFS + } else { + assert(mbmi->ref_frame[1] == ALTREF_FRAME); + } + + return; + } + + assert(comp_ref_type == BIDIR_COMP_REFERENCE); +#endif // CONFIG_EXT_COMP_REFS + #if CONFIG_EXT_REFS const int bit = (mbmi->ref_frame[0] == GOLDEN_FRAME || mbmi->ref_frame[0] == LAST3_FRAME); - const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME; -#else // CONFIG_EXT_REFS - const int bit = mbmi->ref_frame[0] == GOLDEN_FRAME; -#endif // CONFIG_EXT_REFS - - aom_write(w, bit, av1_get_pred_prob_comp_ref_p(cm, xd)); +#if CONFIG_VAR_REFS + // Test need to explicitly code (L,L2) vs (L3,G) branch node in tree + if (L_OR_L2(cm) && L3_OR_G(cm)) +#endif // CONFIG_VAR_REFS + WRITE_REF_BIT(bit, comp_ref_p); -#if CONFIG_EXT_REFS if (!bit) { - const int bit1 = mbmi->ref_frame[0] == LAST_FRAME; - aom_write(w, bit1, av1_get_pred_prob_comp_ref_p1(cm, xd)); +#if CONFIG_VAR_REFS + // Test need to explicitly code (L) vs (L2) branch node in tree + if (L_AND_L2(cm)) { +#endif // CONFIG_VAR_REFS + const int bit1 = mbmi->ref_frame[0] == LAST_FRAME; + WRITE_REF_BIT(bit1, comp_ref_p1); +#if CONFIG_VAR_REFS + } +#endif // CONFIG_VAR_REFS } else { - const int bit2 = mbmi->ref_frame[0] == GOLDEN_FRAME; - aom_write(w, bit2, av1_get_pred_prob_comp_ref_p2(cm, xd)); +#if CONFIG_VAR_REFS + // Test need to explicitly code (L3) vs (G) branch node in tree + if (L3_AND_G(cm)) { +#endif // CONFIG_VAR_REFS + const int bit2 = mbmi->ref_frame[0] == GOLDEN_FRAME; + WRITE_REF_BIT(bit2, comp_ref_p2); +#if CONFIG_VAR_REFS + } +#endif // CONFIG_VAR_REFS } - aom_write(w, bit_bwd, av1_get_pred_prob_comp_bwdref_p(cm, xd)); + +#if CONFIG_VAR_REFS + // Test need to explicitly code (BWD) vs (ALT) branch node in tree + if (BWD_AND_ALT(cm)) { +#endif // CONFIG_VAR_REFS + const int bit_bwd = mbmi->ref_frame[1] == ALTREF_FRAME; + WRITE_REF_BIT(bit_bwd, comp_bwdref_p); +#if CONFIG_VAR_REFS + } +#endif // CONFIG_VAR_REFS + +#else // !CONFIG_EXT_REFS + const int bit = mbmi->ref_frame[0] == GOLDEN_FRAME; + WRITE_REF_BIT(bit, comp_ref_p); #endif // CONFIG_EXT_REFS } else { #if CONFIG_EXT_REFS const int bit0 = (mbmi->ref_frame[0] == ALTREF_FRAME || mbmi->ref_frame[0] == BWDREF_FRAME); - aom_write(w, bit0, av1_get_pred_prob_single_ref_p1(cm, xd)); +#if CONFIG_VAR_REFS + // Test need to explicitly code (L,L2,L3,G) vs (BWD,ALT) branch node in + // tree + if ((L_OR_L2(cm) || L3_OR_G(cm)) && BWD_OR_ALT(cm)) +#endif // CONFIG_VAR_REFS + WRITE_REF_BIT(bit0, single_ref_p1); if (bit0) { - const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME; - aom_write(w, bit1, av1_get_pred_prob_single_ref_p2(cm, xd)); +#if CONFIG_VAR_REFS + // Test need to explicitly code (BWD) vs (ALT) branch node in tree + if (BWD_AND_ALT(cm)) { +#endif // CONFIG_VAR_REFS + const int bit1 = mbmi->ref_frame[0] == ALTREF_FRAME; + WRITE_REF_BIT(bit1, single_ref_p2); +#if CONFIG_VAR_REFS + } +#endif // CONFIG_VAR_REFS } else { const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME || mbmi->ref_frame[0] == GOLDEN_FRAME); - aom_write(w, bit2, av1_get_pred_prob_single_ref_p3(cm, xd)); +#if CONFIG_VAR_REFS + // Test need to explicitly code (L,L2) vs (L3,G) branch node in tree + if (L_OR_L2(cm) && L3_OR_G(cm)) +#endif // CONFIG_VAR_REFS + WRITE_REF_BIT(bit2, single_ref_p3); if (!bit2) { - const int bit3 = mbmi->ref_frame[0] != LAST_FRAME; - aom_write(w, bit3, av1_get_pred_prob_single_ref_p4(cm, xd)); +#if CONFIG_VAR_REFS + // Test need to explicitly code (L) vs (L2) branch node in tree + if (L_AND_L2(cm)) { +#endif // CONFIG_VAR_REFS + const int bit3 = mbmi->ref_frame[0] != LAST_FRAME; + WRITE_REF_BIT(bit3, single_ref_p4); +#if CONFIG_VAR_REFS + } +#endif // CONFIG_VAR_REFS } else { - const int bit4 = mbmi->ref_frame[0] != LAST3_FRAME; - aom_write(w, bit4, av1_get_pred_prob_single_ref_p5(cm, xd)); +#if CONFIG_VAR_REFS + // Test need to explicitly code (L3) vs (G) branch node in tree + if (L3_AND_G(cm)) { +#endif // CONFIG_VAR_REFS + const int bit4 = mbmi->ref_frame[0] != LAST3_FRAME; + WRITE_REF_BIT(bit4, single_ref_p5); +#if CONFIG_VAR_REFS + } +#endif // CONFIG_VAR_REFS } } -#else // CONFIG_EXT_REFS +#else // !CONFIG_EXT_REFS const int bit0 = mbmi->ref_frame[0] != LAST_FRAME; - aom_write(w, bit0, av1_get_pred_prob_single_ref_p1(cm, xd)); + WRITE_REF_BIT(bit0, single_ref_p1); if (bit0) { const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME; - aom_write(w, bit1, av1_get_pred_prob_single_ref_p2(cm, xd)); + WRITE_REF_BIT(bit1, single_ref_p2); } #endif // CONFIG_EXT_REFS } @@ -1250,7 +1256,7 @@ static void write_filter_intra_mode_info(const AV1_COMMON *const cm, (void)mi_col; #endif // CONFIG_CB4X4 - if (mbmi->uv_mode == DC_PRED + if (mbmi->uv_mode == UV_DC_PRED #if CONFIG_PALETTE && mbmi->palette_mode_info.palette_size[1] == 0 #endif // CONFIG_PALETTE @@ -1277,7 +1283,7 @@ static void write_intra_angle_info(const MACROBLOCKD *xd, #endif // CONFIG_INTRA_INTERP (void)ec_ctx; - if (bsize < BLOCK_8X8) return; + if (!av1_use_angle_delta(bsize)) return; if (av1_is_directional_mode(mbmi->mode, bsize)) { write_uniform(w, 2 * MAX_ANGLE_DELTA + 1, @@ -1292,7 +1298,7 @@ static void write_intra_angle_info(const MACROBLOCKD *xd, #endif // CONFIG_INTRA_INTERP } - if (av1_is_directional_mode(mbmi->uv_mode, bsize)) { + if (av1_is_directional_mode(get_uv_mode(mbmi->uv_mode), bsize)) { write_uniform(w, 2 * MAX_ANGLE_DELTA + 1, MAX_ANGLE_DELTA + mbmi->angle_delta[1]); } @@ -1303,11 +1309,7 @@ static void write_mb_interp_filter(AV1_COMP *cpi, const MACROBLOCKD *xd, aom_writer *w) { AV1_COMMON *const cm = &cpi->common; const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; -#if CONFIG_EC_ADAPT FRAME_CONTEXT *ec_ctx = xd->tile_ctx; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; -#endif if (!av1_is_interp_needed(xd)) { #if CONFIG_DUAL_FILTER @@ -1485,19 +1487,21 @@ static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd, if (mbmi->mode == DC_PRED) { const int n = pmi->palette_size[0]; int palette_y_mode_ctx = 0; - if (above_mi) + if (above_mi) { palette_y_mode_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0); - if (left_mi) + } + if (left_mi) { palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0); + } aom_write( w, n > 0, av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_y_mode_ctx]); if (n > 0) { - av1_write_token(w, av1_palette_size_tree, - av1_default_palette_y_size_prob[bsize - BLOCK_8X8], - &palette_size_encodings[n - PALETTE_MIN_SIZE]); + aom_write_symbol(w, n - PALETTE_MIN_SIZE, + xd->tile_ctx->palette_y_size_cdf[bsize - BLOCK_8X8], + PALETTE_SIZES); #if CONFIG_PALETTE_DELTA_ENCODING write_palette_colors_y(xd, pmi, cm->bit_depth, w); #else @@ -1506,18 +1510,17 @@ static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd, aom_write_literal(w, pmi->palette_colors[i], cm->bit_depth); } #endif // CONFIG_PALETTE_DELTA_ENCODING - write_uniform(w, n, pmi->palette_first_color_idx[0]); } } - if (mbmi->uv_mode == DC_PRED) { + if (mbmi->uv_mode == UV_DC_PRED) { const int n = pmi->palette_size[1]; const int palette_uv_mode_ctx = (pmi->palette_size[0] > 0); aom_write(w, n > 0, av1_default_palette_uv_mode_prob[palette_uv_mode_ctx]); if (n > 0) { - av1_write_token(w, av1_palette_size_tree, - av1_default_palette_uv_size_prob[bsize - BLOCK_8X8], - &palette_size_encodings[n - PALETTE_MIN_SIZE]); + aom_write_symbol(w, n - PALETTE_MIN_SIZE, + xd->tile_ctx->palette_uv_size_cdf[bsize - BLOCK_8X8], + PALETTE_SIZES); #if CONFIG_PALETTE_DELTA_ENCODING write_palette_colors_uv(xd, pmi, cm->bit_depth, w); #else @@ -1532,7 +1535,6 @@ static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd, cm->bit_depth); } #endif // CONFIG_PALETTE_DELTA_ENCODING - write_uniform(w, n, pmi->palette_first_color_idx[1]); } } } @@ -1543,21 +1545,20 @@ void av1_write_tx_type(const AV1_COMMON *const cm, const MACROBLOCKD *xd, const int supertx_enabled, #endif #if CONFIG_TXK_SEL - int block, int plane, + int blk_row, int blk_col, int block, int plane, + TX_SIZE tx_size, #endif aom_writer *w) { MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; const int is_inter = is_inter_block(mbmi); +#if !CONFIG_TXK_SEL #if CONFIG_VAR_TX const TX_SIZE tx_size = is_inter ? mbmi->min_tx_size : mbmi->tx_size; #else const TX_SIZE tx_size = mbmi->tx_size; #endif // CONFIG_VAR_TX -#if CONFIG_EC_ADAPT +#endif // !CONFIG_TXK_SEL FRAME_CONTEXT *ec_ctx = xd->tile_ctx; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; -#endif #if !CONFIG_TXK_SEL TX_TYPE tx_type = mbmi->tx_type; @@ -1565,7 +1566,8 @@ void av1_write_tx_type(const AV1_COMMON *const cm, const MACROBLOCKD *xd, // Only y plane's tx_type is transmitted if (plane > 0) return; PLANE_TYPE plane_type = get_plane_type(plane); - TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size); + TX_TYPE tx_type = + av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size); #endif if (!FIXED_TX_TYPE) { @@ -1583,21 +1585,20 @@ void av1_write_tx_type(const AV1_COMMON *const cm, const MACROBLOCKD *xd, !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { const int eset = get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used); + // eset == 0 should correspond to a set with only DCT_DCT and there + // is no need to send the tx_type + assert(eset > 0); if (is_inter) { assert(ext_tx_used_inter[eset][tx_type]); - if (eset > 0) { - aom_write_symbol(w, av1_ext_tx_inter_ind[eset][tx_type], - ec_ctx->inter_ext_tx_cdf[eset][square_tx_size], - ext_tx_cnt_inter[eset]); - } + aom_write_symbol(w, av1_ext_tx_inter_ind[eset][tx_type], + ec_ctx->inter_ext_tx_cdf[eset][square_tx_size], + ext_tx_cnt_inter[eset]); } else if (ALLOW_INTRA_EXT_TX) { assert(ext_tx_used_intra[eset][tx_type]); - if (eset > 0) { - aom_write_symbol( - w, av1_ext_tx_intra_ind[eset][tx_type], - ec_ctx->intra_ext_tx_cdf[eset][square_tx_size][mbmi->mode], - ext_tx_cnt_intra[eset]); - } + aom_write_symbol( + w, av1_ext_tx_intra_ind[eset][tx_type], + ec_ctx->intra_ext_tx_cdf[eset][square_tx_size][mbmi->mode], + ext_tx_cnt_intra[eset]); } } #else @@ -1632,36 +1633,30 @@ static void write_intra_mode(FRAME_CONTEXT *frame_ctx, BLOCK_SIZE bsize, } static void write_intra_uv_mode(FRAME_CONTEXT *frame_ctx, - PREDICTION_MODE uv_mode, PREDICTION_MODE y_mode, - aom_writer *w) { - aom_write_symbol(w, av1_intra_mode_ind[uv_mode], - frame_ctx->uv_mode_cdf[y_mode], INTRA_MODES); + UV_PREDICTION_MODE uv_mode, + PREDICTION_MODE y_mode, aom_writer *w) { + aom_write_symbol(w, av1_intra_mode_ind[get_uv_mode(uv_mode)], + frame_ctx->uv_mode_cdf[y_mode], UV_INTRA_MODES); } #if CONFIG_CFL -static void write_cfl_alphas(FRAME_CONTEXT *const frame_ctx, int skip, int ind, +static void write_cfl_alphas(FRAME_CONTEXT *const frame_ctx, int ind, const CFL_SIGN_TYPE signs[CFL_SIGNS], aom_writer *w) { - if (skip) { - assert(ind == 0); + // Check for uninitialized signs + if (cfl_alpha_codes[ind][CFL_PRED_U] == 0) assert(signs[CFL_PRED_U] == CFL_SIGN_POS); + if (cfl_alpha_codes[ind][CFL_PRED_V] == 0) assert(signs[CFL_PRED_V] == CFL_SIGN_POS); - } else { - // Check for uninitialized signs - if (cfl_alpha_codes[ind][CFL_PRED_U] == 0) - assert(signs[CFL_PRED_U] == CFL_SIGN_POS); - if (cfl_alpha_codes[ind][CFL_PRED_V] == 0) - assert(signs[CFL_PRED_V] == CFL_SIGN_POS); - - // Write a symbol representing a combination of alpha Cb and alpha Cr. - aom_write_symbol(w, ind, frame_ctx->cfl_alpha_cdf, CFL_ALPHABET_SIZE); - - // Signs are only signaled for nonzero codes. - if (cfl_alpha_codes[ind][CFL_PRED_U] != 0) - aom_write_bit(w, signs[CFL_PRED_U]); - if (cfl_alpha_codes[ind][CFL_PRED_V] != 0) - aom_write_bit(w, signs[CFL_PRED_V]); - } + + // Write a symbol representing a combination of alpha Cb and alpha Cr. + aom_write_symbol(w, ind, frame_ctx->cfl_alpha_cdf, CFL_ALPHABET_SIZE); + + // Signs are only signaled for nonzero codes. + if (cfl_alpha_codes[ind][CFL_PRED_U] != 0) + aom_write_bit(w, signs[CFL_PRED_U]); + if (cfl_alpha_codes[ind][CFL_PRED_V] != 0) + aom_write_bit(w, signs[CFL_PRED_V]); } #endif @@ -1672,22 +1667,13 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, #endif aom_writer *w) { AV1_COMMON *const cm = &cpi->common; -#if CONFIG_DELTA_Q || CONFIG_EC_ADAPT MACROBLOCK *const x = &cpi->td.mb; MACROBLOCKD *const xd = &x->e_mbd; -#else - const MACROBLOCK *x = &cpi->td.mb; - const MACROBLOCKD *xd = &x->e_mbd; -#endif -#if CONFIG_EC_ADAPT FRAME_CONTEXT *ec_ctx = xd->tile_ctx; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; -#endif const MODE_INFO *mi = xd->mi[0]; const struct segmentation *const seg = &cm->seg; - struct segmentation_probs *const segp = &cm->fc->seg; + struct segmentation_probs *const segp = &ec_ctx->seg; const MB_MODE_INFO *const mbmi = &mi->mbmi; const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; const PREDICTION_MODE mode = mbmi->mode; @@ -1708,8 +1694,13 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, if (seg->update_map) { if (seg->temporal_update) { const int pred_flag = mbmi->seg_id_predicted; +#if CONFIG_NEW_MULTISYMBOL + aom_cdf_prob *pred_cdf = av1_get_pred_cdf_seg_id(segp, xd); + aom_write_symbol(w, pred_flag, pred_cdf, 2); +#else aom_prob pred_prob = av1_get_pred_prob_seg_id(segp, xd); aom_write(w, pred_flag, pred_prob); +#endif if (!pred_flag) write_segment_id(w, seg, segp, segment_id); } else { write_segment_id(w, seg, segp, segment_id); @@ -1750,8 +1741,7 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, #if CONFIG_SUPERTX if (!supertx_enabled) #endif // CONFIG_SUPERTX - if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) - aom_write(w, is_inter, av1_get_intra_inter_prob(cm, xd)); + write_is_inter(cm, xd, mbmi->segment_id, w, is_inter); if (cm->tx_mode == TX_MODE_SELECT && #if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_RECT_TX) @@ -1779,6 +1769,15 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, for (idx = 0; idx < width; idx += bw) write_tx_size_vartx(cm, xd, mbmi, max_tx_size, height != width, idy, idx, w); +#if CONFIG_RECT_TX_EXT + if (is_quarter_tx_allowed(xd, mbmi, is_inter_block(mbmi)) && + quarter_txsize_lookup[bsize] != max_tx_size && + (mbmi->tx_size == quarter_txsize_lookup[bsize] || + mbmi->tx_size == max_tx_size)) { + aom_write(w, mbmi->tx_size != max_tx_size, + cm->fc->quarter_tx_size_prob); + } +#endif } else { set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, skip, xd); write_selected_tx_size(cm, xd, w); @@ -1813,9 +1812,8 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, #endif // CONFIG_CB4X4 #if CONFIG_CFL - if (mbmi->uv_mode == DC_PRED) { - write_cfl_alphas(ec_ctx, mbmi->skip, mbmi->cfl_alpha_idx, - mbmi->cfl_alpha_signs, w); + if (mbmi->uv_mode == UV_DC_PRED) { + write_cfl_alphas(ec_ctx, mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs, w); } #endif @@ -1838,11 +1836,25 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, int16_t mode_ctx; write_ref_frames(cm, xd, w); +#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF + if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) { + // NOTE: Handle single ref comp mode + if (!is_compound) + aom_write(w, is_inter_singleref_comp_mode(mode), + av1_get_inter_mode_prob(cm, xd)); + } +#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF + #if CONFIG_EXT_INTER +#if CONFIG_COMPOUND_SINGLEREF + if (is_compound || is_inter_singleref_comp_mode(mode)) +#else // !CONFIG_COMPOUND_SINGLEREF if (is_compound) +#endif // CONFIG_COMPOUND_SINGLEREF mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]]; else #endif // CONFIG_EXT_INTER + mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context, mbmi->ref_frame, bsize, -1); @@ -1851,18 +1863,25 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, if (bsize >= BLOCK_8X8 || unify_bsize) { #if CONFIG_EXT_INTER if (is_inter_compound_mode(mode)) - write_inter_compound_mode(cm, w, mode, mode_ctx); + write_inter_compound_mode(cm, xd, w, mode, mode_ctx); +#if CONFIG_COMPOUND_SINGLEREF + else if (is_inter_singleref_comp_mode(mode)) + write_inter_singleref_comp_mode(xd, w, mode, mode_ctx); +#endif // CONFIG_COMPOUND_SINGLEREF else if (is_inter_singleref_mode(mode)) #endif // CONFIG_EXT_INTER write_inter_mode(w, mode, ec_ctx, mode_ctx); #if CONFIG_EXT_INTER if (mode == NEWMV || mode == NEW_NEWMV || +#if CONFIG_COMPOUND_SINGLEREF + mbmi->mode == SR_NEW_NEWMV || +#endif // CONFIG_COMPOUND_SINGLEREF have_nearmv_in_inter_mode(mode)) -#else +#else // !CONFIG_EXT_INTER if (mode == NEARMV || mode == NEWMV) -#endif - write_drl_idx(cm, mbmi, mbmi_ext, w); +#endif // CONFIG_EXT_INTER + write_drl_idx(ec_ctx, mbmi, mbmi_ext, w); else assert(mbmi->ref_mv_idx == 0); } @@ -1873,6 +1892,10 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, #endif // !CONFIG_DUAL_FILTER && !CONFIG_WARPED_MOTION if (bsize < BLOCK_8X8 && !unify_bsize) { +#if CONFIG_COMPOUND_SINGLEREF + /// NOTE: Single ref comp mode does not support sub8x8. + assert(is_compound || !is_inter_singleref_comp_mode(mbmi->mode)); +#endif // CONFIG_COMPOUND_SINGLEREF const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; int idx, idy; @@ -1887,7 +1910,7 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, mbmi->ref_frame, bsize, j); #if CONFIG_EXT_INTER if (is_inter_compound_mode(b_mode)) - write_inter_compound_mode(cm, w, b_mode, mode_ctx); + write_inter_compound_mode(cm, xd, w, b_mode, mode_ctx); else if (is_inter_singleref_mode(b_mode)) #endif // CONFIG_EXT_INTER write_inter_mode(w, b_mode, ec_ctx, mode_ctx); @@ -1969,6 +1992,22 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, av1_encode_mv(cpi, w, &mbmi->mv[0].as_mv, &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv, nmvc, allow_hp); +#if CONFIG_COMPOUND_SINGLEREF + } else if ( // mode == SR_NEAREST_NEWMV || + mode == SR_NEAR_NEWMV || mode == SR_ZERO_NEWMV || + mode == SR_NEW_NEWMV) { + int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame); + int nmv_ctx = + av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type], + mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx); + nmv_context *nmvc = &ec_ctx->nmvc[nmv_ctx]; + int_mv ref_mv = mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0]; + if (mode == SR_NEW_NEWMV) + av1_encode_mv(cpi, w, &mbmi->mv[0].as_mv, &ref_mv.as_mv, nmvc, + allow_hp); + av1_encode_mv(cpi, w, &mbmi->mv[1].as_mv, &ref_mv.as_mv, nmvc, + allow_hp); +#endif // CONFIG_COMPOUND_SINGLEREF #endif // CONFIG_EXT_INTER } } @@ -1981,13 +2020,23 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, cpi->common.allow_interintra_compound && is_interintra_allowed(mbmi)) { const int interintra = mbmi->ref_frame[1] == INTRA_FRAME; const int bsize_group = size_group_lookup[bsize]; +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, interintra, ec_ctx->interintra_cdf[bsize_group], 2); +#else aom_write(w, interintra, cm->fc->interintra_prob[bsize_group]); +#endif if (interintra) { - write_interintra_mode(w, mbmi->interintra_mode, - cm->fc->interintra_mode_prob[bsize_group]); + aom_write_symbol(w, mbmi->interintra_mode, + ec_ctx->interintra_mode_cdf[bsize_group], + INTERINTRA_MODES); if (is_interintra_wedge_used(bsize)) { +#if CONFIG_NEW_MULTISYMBOL + aom_write_symbol(w, mbmi->use_wedge_interintra, + ec_ctx->wedge_interintra_cdf[bsize], 2); +#else aom_write(w, mbmi->use_wedge_interintra, cm->fc->wedge_interintra_prob[bsize]); +#endif if (mbmi->use_wedge_interintra) { aom_write_literal(w, mbmi->interintra_wedge_index, get_wedge_bits_lookup(bsize)); @@ -2005,21 +2054,28 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, #if CONFIG_EXT_INTER if (mbmi->ref_frame[1] != INTRA_FRAME) #endif // CONFIG_EXT_INTER - write_motion_mode(cm, mi, w); + write_motion_mode(cm, xd, mi, w); +#if CONFIG_NCOBMC_ADAPT_WEIGHT + write_ncobmc_mode(xd, mi, w); +#endif #endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION #if CONFIG_EXT_INTER - if (cpi->common.reference_mode != SINGLE_REFERENCE && - is_inter_compound_mode(mbmi->mode) + if ( +#if CONFIG_COMPOUND_SINGLEREF + is_inter_anyref_comp_mode(mbmi->mode) && +#else // !CONFIG_COMPOUND_SINGLEREF + cpi->common.reference_mode != SINGLE_REFERENCE && + is_inter_compound_mode(mbmi->mode) && +#endif // CONFIG_COMPOUND_SINGLEREF #if CONFIG_MOTION_VAR - && mbmi->motion_mode == SIMPLE_TRANSLATION + mbmi->motion_mode == SIMPLE_TRANSLATION && #endif // CONFIG_MOTION_VAR - && is_any_masked_compound_used(bsize)) { + is_any_masked_compound_used(bsize)) { #if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE if (cm->allow_masked_compound) { - av1_write_token( - w, av1_compound_type_tree, cm->fc->compound_type_prob[bsize], - &compound_type_encodings[mbmi->interinter_compound_type]); + aom_write_symbol(w, mbmi->interinter_compound_type, + ec_ctx->compound_type_cdf[bsize], COMPOUND_TYPES); #if CONFIG_WEDGE if (mbmi->interinter_compound_type == COMPOUND_WEDGE) { aom_write_literal(w, mbmi->wedge_index, get_wedge_bits_lookup(bsize)); @@ -2061,8 +2117,9 @@ static void write_mb_modes_kf(AV1_COMMON *cm, #endif // CONFIG_INTRABC const int mi_row, const int mi_col, aom_writer *w) { + FRAME_CONTEXT *ec_ctx = xd->tile_ctx; const struct segmentation *const seg = &cm->seg; - struct segmentation_probs *const segp = &cm->fc->seg; + struct segmentation_probs *const segp = &ec_ctx->seg; const MODE_INFO *const mi = xd->mi[0]; const MODE_INFO *const above_mi = xd->above_mi; const MODE_INFO *const left_mi = xd->left_mi; @@ -2076,12 +2133,6 @@ static void write_mb_modes_kf(AV1_COMMON *cm, (void)mi_row; (void)mi_col; -#if CONFIG_EC_ADAPT - FRAME_CONTEXT *ec_ctx = xd->tile_ctx; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; -#endif - if (seg->update_map) write_segment_id(w, seg, segp, mbmi->segment_id); #if CONFIG_DELTA_Q @@ -2110,18 +2161,17 @@ static void write_mb_modes_kf(AV1_COMMON *cm, write_skip(cm, xd, mbmi->segment_id, mi, w); #endif - if (cm->tx_mode == TX_MODE_SELECT && + int enable_tx_size = cm->tx_mode == TX_MODE_SELECT && #if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_RECT_TX) #if CONFIG_RECT_TX - bsize > BLOCK_4X4 && + bsize > BLOCK_4X4 && #else - bsize >= BLOCK_8X8 && + bsize >= BLOCK_8X8 && #endif // CONFIG_RECT_TX #else - bsize >= BLOCK_8X8 && + bsize >= BLOCK_8X8 && #endif - !xd->lossless[mbmi->segment_id]) - write_selected_tx_size(cm, xd, w); + !xd->lossless[mbmi->segment_id]; #if CONFIG_INTRABC if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools) { @@ -2129,7 +2179,8 @@ static void write_mb_modes_kf(AV1_COMMON *cm, aom_write(w, use_intrabc, ec_ctx->intrabc_prob); if (use_intrabc) { assert(mbmi->mode == DC_PRED); - assert(mbmi->uv_mode == DC_PRED); + assert(mbmi->uv_mode == UV_DC_PRED); + if (enable_tx_size && !mbmi->skip) write_selected_tx_size(cm, xd, w); int_mv dv_ref = mbmi_ext->ref_mvs[INTRA_FRAME][0]; av1_encode_dv(w, &mbmi->mv[0].as_mv, &dv_ref.as_mv, &ec_ctx->ndvc); #if CONFIG_EXT_TX && !CONFIG_TXK_SEL @@ -2143,6 +2194,7 @@ static void write_mb_modes_kf(AV1_COMMON *cm, } } #endif // CONFIG_INTRABC + if (enable_tx_size) write_selected_tx_size(cm, xd, w); if (bsize >= BLOCK_8X8 || unify_bsize) { write_intra_mode_kf(cm, ec_ctx, mi, above_mi, left_mi, 0, mbmi->mode, w); @@ -2169,9 +2221,8 @@ static void write_mb_modes_kf(AV1_COMMON *cm, #endif // CONFIG_CB4X4 #if CONFIG_CFL - if (mbmi->uv_mode == DC_PRED) { - write_cfl_alphas(ec_ctx, mbmi->skip, mbmi->cfl_alpha_idx, - mbmi->cfl_alpha_signs, w); + if (mbmi->uv_mode == UV_DC_PRED) { + write_cfl_alphas(ec_ctx, mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs, w); } #endif @@ -2252,6 +2303,89 @@ static int rd_token_stats_mismatch(RD_STATS *rd_stats, TOKEN_STATS *token_stats, } #endif +#if ENC_MISMATCH_DEBUG +static void enc_dump_logs(AV1_COMP *cpi, int mi_row, int mi_col) { + AV1_COMMON *const cm = &cpi->common; + MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; + MODE_INFO *m; + xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col); + m = xd->mi[0]; + if (is_inter_block(&m->mbmi)) { +#define FRAME_TO_CHECK 1 + if (cm->current_video_frame == FRAME_TO_CHECK /* && cm->show_frame == 1*/) { + const MB_MODE_INFO *const mbmi = &m->mbmi; + const BLOCK_SIZE bsize = mbmi->sb_type; + + int_mv mv[2]; + int is_comp_ref = has_second_ref(&m->mbmi); + int ref; + + for (ref = 0; ref < 1 + is_comp_ref; ++ref) + mv[ref].as_mv = m->mbmi.mv[ref].as_mv; + + if (!is_comp_ref) { +#if CONFIG_COMPOUND_SINGLEREF + if (is_inter_singleref_comp_mode(m->mbmi.mode)) + mv[1].as_mv = m->mbmi.mv[1].as_mv; + else +#endif // CONFIG_COMPOUND_SINGLEREF + mv[1].as_int = 0; + } + int interp_ctx[2] = { -1 }; + int interp_filter[2] = { cm->interp_filter }; + if (cm->interp_filter == SWITCHABLE) { + int dir; + for (dir = 0; dir < 2; ++dir) { + if (has_subpel_mv_component(xd->mi[0], xd, dir) || + (mbmi->ref_frame[1] > INTRA_FRAME && + has_subpel_mv_component(xd->mi[0], xd, dir + 2))) { + interp_ctx[dir] = av1_get_pred_context_switchable_interp(xd, dir); + interp_filter[dir] = mbmi->interp_filter[dir]; + } else { + interp_filter[dir] = EIGHTTAP_REGULAR; + } + } + } + + MACROBLOCK *const x = &cpi->td.mb; + const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; + const int16_t mode_ctx = av1_mode_context_analyzer( + mbmi_ext->mode_context, mbmi->ref_frame, bsize, -1); + const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK; + int16_t zeromv_ctx = -1; + int16_t refmv_ctx = -1; + if (mbmi->mode != NEWMV) { + zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK; + if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) { + assert(mbmi->mode == ZEROMV); + } + if (mbmi->mode != ZEROMV) { + refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK; + if (mode_ctx & (1 << SKIP_NEARESTMV_OFFSET)) refmv_ctx = 6; + if (mode_ctx & (1 << SKIP_NEARMV_OFFSET)) refmv_ctx = 7; + if (mode_ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) refmv_ctx = 8; + } + } + + int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame); + printf( + "=== ENCODER ===: " + "Frame=%d, (mi_row,mi_col)=(%d,%d), mode=%d, bsize=%d, " + "show_frame=%d, mv[0]=(%d,%d), mv[1]=(%d,%d), ref[0]=%d, " + "ref[1]=%d, motion_mode=%d, inter_mode_ctx=%d, mode_ctx=%d, " + "interp_ctx=(%d,%d), interp_filter=(%d,%d), newmv_ctx=%d, " + "zeromv_ctx=%d, refmv_ctx=%d\n", + cm->current_video_frame, mi_row, mi_col, mbmi->mode, bsize, + cm->show_frame, mv[0].as_mv.row, mv[0].as_mv.col, mv[1].as_mv.row, + mv[1].as_mv.col, mbmi->ref_frame[0], mbmi->ref_frame[1], + mbmi->motion_mode, mbmi_ext->mode_context[ref_frame_type], mode_ctx, + interp_ctx[0], interp_ctx[1], interp_filter[0], interp_filter[1], + newmv_ctx, zeromv_ctx, refmv_ctx); + } + } +} +#endif // ENC_MISMATCH_DEBUG + static void write_mbmi_b(AV1_COMP *cpi, const TileInfo *const tile, aom_writer *w, #if CONFIG_SUPERTX @@ -2265,7 +2399,8 @@ static void write_mbmi_b(AV1_COMP *cpi, const TileInfo *const tile, xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col); m = xd->mi[0]; - assert(m->mbmi.sb_type <= cm->sb_size); + assert(m->mbmi.sb_type <= cm->sb_size || + (m->mbmi.sb_type >= BLOCK_4X16 && m->mbmi.sb_type <= BLOCK_32X8)); bh = mi_size_high[m->mbmi.sb_type]; bw = mi_size_wide[m->mbmi.sb_type]; @@ -2291,36 +2426,22 @@ static void write_mbmi_b(AV1_COMP *cpi, const TileInfo *const tile, xd->left_txfm_context = xd->left_txfm_context_buffer + ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2); #endif -#if CONFIG_DUAL_FILTER +#if CONFIG_DUAL_FILTER || CONFIG_WARPED_MOTION // has_subpel_mv_component needs the ref frame buffers set up to look // up if they are scaled. has_subpel_mv_component is in turn needed by // write_switchable_interp_filter, which is called by pack_inter_mode_mvs. set_ref_ptrs(cm, xd, m->mbmi.ref_frame[0], m->mbmi.ref_frame[1]); -#endif // CONFIG_DUAL_FILTER -#if 0 +#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF + if (!has_second_ref(&m->mbmi) && is_inter_singleref_comp_mode(m->mbmi.mode)) + xd->block_refs[1] = xd->block_refs[0]; +#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF +#endif // CONFIG_DUAL_FILTER || CONFIG_WARPED_MOTION + +#if ENC_MISMATCH_DEBUG // NOTE(zoeliu): For debug - if (cm->current_video_frame == FRAME_TO_CHECK && cm->show_frame == 1) { - const PREDICTION_MODE mode = m->mbmi.mode; - const int segment_id = m->mbmi.segment_id; - const BLOCK_SIZE bsize = m->mbmi.sb_type; - - // For sub8x8, simply dump out the first sub8x8 block info - const PREDICTION_MODE b_mode = - (bsize < BLOCK_8X8) ? m->bmi[0].as_mode : -1; - const int mv_x = (bsize < BLOCK_8X8) ? - m->bmi[0].as_mv[0].as_mv.row : m->mbmi.mv[0].as_mv.row; - const int mv_y = (bsize < BLOCK_8X8) ? - m->bmi[0].as_mv[0].as_mv.col : m->mbmi.mv[0].as_mv.col; - - printf("Before pack_inter_mode_mvs(): " - "Frame=%d, (mi_row,mi_col)=(%d,%d), " - "mode=%d, segment_id=%d, bsize=%d, b_mode=%d, " - "mv[0]=(%d, %d), ref[0]=%d, ref[1]=%d\n", - cm->current_video_frame, mi_row, mi_col, - mode, segment_id, bsize, b_mode, mv_x, mv_y, - m->mbmi.ref_frame[0], m->mbmi.ref_frame[1]); - } -#endif // 0 + enc_dump_logs(cpi, mi_row, mi_col); +#endif // ENC_MISMATCH_DEBUG + pack_inter_mode_mvs(cpi, mi_row, mi_col, #if CONFIG_SUPERTX supertx_enabled, @@ -2335,7 +2456,8 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, int mi_col) { AV1_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; - MODE_INFO *const m = xd->mi[0]; + const int mi_offset = mi_row * cm->mi_stride + mi_col; + MODE_INFO *const m = *(cm->mi_grid_visible + mi_offset); MB_MODE_INFO *const mbmi = &m->mbmi; int plane; int bh, bw; @@ -2344,9 +2466,10 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, (void)tok; (void)tok_end; #endif - xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col); + xd->mi = cm->mi_grid_visible + mi_offset; - assert(mbmi->sb_type <= cm->sb_size); + assert(mbmi->sb_type <= cm->sb_size || + (mbmi->sb_type >= BLOCK_4X16 && mbmi->sb_type <= BLOCK_32X8)); bh = mi_size_high[mbmi->sb_type]; bw = mi_size_wide[mbmi->sb_type]; @@ -2371,7 +2494,7 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, av1_get_block_dimensions(mbmi->sb_type, plane, xd, NULL, NULL, &rows, &cols); assert(*tok < tok_end); - pack_palette_tokens(w, tok, palette_size_plane, rows * cols - 1); + pack_palette_tokens(w, tok, palette_size_plane, rows * cols); assert(*tok < tok_end + mbmi->skip); } } @@ -2382,7 +2505,7 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, const struct macroblockd_plane *const pd_y = &xd->plane[0]; const struct macroblockd_plane *const pd_c = &xd->plane[1]; const TX_SIZE tx_log2_y = mbmi->tx_size; - const TX_SIZE tx_log2_c = get_uv_tx_size(mbmi, pd_c); + const TX_SIZE tx_log2_c = av1_get_uv_tx_size(mbmi, pd_c); const int tx_sz_y = (1 << tx_log2_y); const int tx_sz_c = (1 << tx_log2_c); @@ -2469,13 +2592,11 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, #if CONFIG_VAR_TX const struct macroblockd_plane *const pd = &xd->plane[plane]; BLOCK_SIZE bsize = mbmi->sb_type; -#if CONFIG_CB4X4 -#if CONFIG_CHROMA_2X2 - const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); -#else +#if CONFIG_CHROMA_SUB8X8 const BLOCK_SIZE plane_bsize = AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd)); -#endif +#elif CONFIG_CB4X4 + const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); #else const BLOCK_SIZE plane_bsize = get_plane_block_size(AOMMAX(bsize, BLOCK_8X8), pd); @@ -2489,6 +2610,15 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, TOKEN_STATS token_stats; init_token_stats(&token_stats); + const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd); + int mu_blocks_wide = + block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0]; + int mu_blocks_high = + block_size_high[max_unit_bsize] >> tx_size_high_log2[0]; + + mu_blocks_wide = AOMMIN(num_4x4_w, mu_blocks_wide); + mu_blocks_high = AOMMIN(num_4x4_h, mu_blocks_high); + if (is_inter_block(mbmi)) { const TX_SIZE max_tx_size = get_vartx_max_txsize(mbmi, plane_bsize); int block = 0; @@ -2496,19 +2626,27 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size]; const int bkw = tx_size_wide_unit[max_tx_size]; const int bkh = tx_size_high_unit[max_tx_size]; - for (row = 0; row < num_4x4_h; row += bkh) { - for (col = 0; col < num_4x4_w; col += bkw) { - pack_txb_tokens(w, + for (row = 0; row < num_4x4_h; row += mu_blocks_high) { + const int unit_height = AOMMIN(mu_blocks_high + row, num_4x4_h); + for (col = 0; col < num_4x4_w; col += mu_blocks_wide) { + int blk_row, blk_col; + const int unit_width = AOMMIN(mu_blocks_wide + col, num_4x4_w); + for (blk_row = row; blk_row < unit_height; blk_row += bkh) { + for (blk_col = col; blk_col < unit_width; blk_col += bkw) { + pack_txb_tokens(w, #if CONFIG_LV_MAP - cm, + cm, #endif - tok, tok_end, + tok, tok_end, #if CONFIG_PVQ || CONFIG_LV_MAP - x, + x, #endif - xd, mbmi, plane, plane_bsize, cm->bit_depth, block, - row, col, max_tx_size, &token_stats); - block += step; + xd, mbmi, plane, plane_bsize, cm->bit_depth, + block, blk_row, blk_col, max_tx_size, + &token_stats); + block += step; + } + } } } #if CONFIG_RD_DEBUG @@ -2522,22 +2660,32 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, #if CONFIG_LV_MAP av1_write_coeffs_mb(cm, x, w, plane); #else - TX_SIZE tx = get_tx_size(plane, xd); + const TX_SIZE tx = av1_get_tx_size(plane, xd); const int bkw = tx_size_wide_unit[tx]; const int bkh = tx_size_high_unit[tx]; - for (row = 0; row < num_4x4_h; row += bkh) { - for (col = 0; col < num_4x4_w; col += bkw) { + int blk_row, blk_col; + + for (row = 0; row < num_4x4_h; row += mu_blocks_high) { + for (col = 0; col < num_4x4_w; col += mu_blocks_wide) { + const int unit_height = AOMMIN(mu_blocks_high + row, num_4x4_h); + const int unit_width = AOMMIN(mu_blocks_wide + col, num_4x4_w); + + for (blk_row = row; blk_row < unit_height; blk_row += bkh) { + for (blk_col = col; blk_col < unit_width; blk_col += bkw) { #if !CONFIG_PVQ - pack_mb_tokens(w, tok, tok_end, cm->bit_depth, tx, &token_stats); + pack_mb_tokens(w, tok, tok_end, cm->bit_depth, tx, + &token_stats); #else - pack_pvq_tokens(w, x, xd, plane, bsize, tx); + pack_pvq_tokens(w, x, xd, plane, bsize, tx); #endif + } + } } } #endif // CONFIG_LV_MAP } #else - TX_SIZE tx = get_tx_size(plane, xd); + const TX_SIZE tx = av1_get_tx_size(plane, xd); TOKEN_STATS token_stats; #if !CONFIG_PVQ init_token_stats(&token_stats); @@ -2570,7 +2718,7 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, #endif // CONFIG_COEF_INTERLEAVE } -#if CONFIG_MOTION_VAR && CONFIG_NCOBMC +#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT) static void write_tokens_sb(AV1_COMP *cpi, const TileInfo *const tile, aom_writer *w, const TOKENEXTRA **tok, const TOKENEXTRA *const tok_end, int mi_row, @@ -2656,7 +2804,7 @@ static void write_modes_b(AV1_COMP *cpi, const TileInfo *const tile, supertx_enabled, #endif mi_row, mi_col); -#if CONFIG_MOTION_VAR && CONFIG_NCOBMC +#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT) (void)tok; (void)tok_end; #else @@ -2688,12 +2836,8 @@ static void write_partition(const AV1_COMMON *const cm, const aom_prob *const probs = cm->fc->partition_prob[ctx]; #endif -#if CONFIG_EC_ADAPT FRAME_CONTEXT *ec_ctx = xd->tile_ctx; (void)cm; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; -#endif if (!is_partition_point) return; @@ -2738,6 +2882,10 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, const AV1_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; const int hbs = mi_size_wide[bsize] / 2; +#if CONFIG_EXT_PARTITION_TYPES + const int quarter_step = mi_size_wide[bsize] / 4; + int i; +#endif const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize); const BLOCK_SIZE subsize = get_subsize(bsize, partition); #if CONFIG_CB4X4 @@ -2843,6 +2991,24 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled, mi_row + hbs, mi_col + hbs); break; + case PARTITION_HORZ_4: + for (i = 0; i < 4; ++i) { + int this_mi_row = mi_row + i * quarter_step; + if (i > 0 && this_mi_row >= cm->mi_rows) break; + + write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled, + this_mi_row, mi_col); + } + break; + case PARTITION_VERT_4: + for (i = 0; i < 4; ++i) { + int this_mi_col = mi_col + i * quarter_step; + if (i > 0 && this_mi_col >= cm->mi_cols) break; + + write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled, + mi_row, this_mi_col); + } + break; #endif // CONFIG_EXT_PARTITION_TYPES default: assert(0); } @@ -2865,17 +3031,15 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, assert(mbmi->segment_id_supertx < MAX_SEGMENTS); skip = write_skip(cm, xd, mbmi->segment_id_supertx, xd->mi[0], w); + + FRAME_CONTEXT *ec_ctx = xd->tile_ctx; + #if CONFIG_EXT_TX if (get_ext_tx_types(supertx_size, bsize, 1, cm->reduced_tx_set_used) > 1 && !skip) { const int eset = get_ext_tx_set(supertx_size, bsize, 1, cm->reduced_tx_set_used); if (eset > 0) { -#if CONFIG_EC_ADAPT - FRAME_CONTEXT *ec_ctx = xd->tile_ctx; -#else - FRAME_CONTEXT *ec_ctx = cm->fc; -#endif aom_write_symbol(w, av1_ext_tx_inter_ind[eset][mbmi->tx_type], ec_ctx->inter_ext_tx_cdf[eset][supertx_size], ext_tx_cnt_inter[eset]); @@ -2883,9 +3047,8 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, } #else if (supertx_size < TX_32X32 && !skip) { - av1_write_token(w, av1_ext_tx_tree, - cm->fc->inter_ext_tx_prob[supertx_size], - &ext_tx_encodings[mbmi->tx_type]); + aom_write_symbol(w, mbmi->tx_type, ec_ctx->inter_ext_tx_cdf[supertx_size], + TX_TYPES); } #endif // CONFIG_EXT_TX @@ -2900,7 +3063,7 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, const int max_blocks_high = max_block_high(xd, plane_bsize, plane); int row, col; - TX_SIZE tx = get_tx_size(plane, xd); + const TX_SIZE tx = av1_get_tx_size(plane, xd); BLOCK_SIZE txb_size = txsize_to_bsize[tx]; const int stepr = tx_size_high_unit[txb_size]; @@ -2934,11 +3097,24 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, #endif // CONFIG_EXT_PARTITION_TYPES #if CONFIG_CDEF - if (bsize == cm->sb_size && !sb_all_skip(cm, mi_row, mi_col) && - cm->cdef_bits != 0) { - aom_write_literal(w, cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col] - ->mbmi.cdef_strength, - cm->cdef_bits); + if (bsize == cm->sb_size && cm->cdef_bits != 0 && !cm->all_lossless) { + int width_step = mi_size_wide[BLOCK_64X64]; + int height_step = mi_size_high[BLOCK_64X64]; + int width, height; + for (height = 0; (height < mi_size_high[cm->sb_size]) && + (mi_row + height < cm->mi_rows); + height += height_step) { + for (width = 0; (width < mi_size_wide[cm->sb_size]) && + (mi_col + width < cm->mi_cols); + width += width_step) { + if (!sb_all_skip(cm, mi_row + height, mi_col + width)) + aom_write_literal( + w, cm->mi_grid_visible[(mi_row + height) * cm->mi_stride + + (mi_col + width)] + ->mbmi.cdef_strength, + cm->cdef_bits); + } + } } #endif } @@ -2955,12 +3131,8 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile, int mi_row, mi_col; #if CONFIG_DEPENDENT_HORZTILES -#if CONFIG_TILE_GROUPS if (!cm->dependent_horz_tiles || mi_row_start == 0 || tile->tg_horz_boundary) { -#else - if (!cm->dependent_horz_tiles || mi_row_start == 0) { -#endif av1_zero_above_context(cm, mi_col_start, mi_col_end); } #else @@ -2986,7 +3158,7 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile, for (mi_col = mi_col_start; mi_col < mi_col_end; mi_col += cm->mib_size) { write_modes_sb_wrapper(cpi, tile, w, tok, tok_end, 0, mi_row, mi_col, cm->sb_size); -#if CONFIG_MOTION_VAR && CONFIG_NCOBMC +#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT) write_tokens_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col, cm->sb_size); #endif } @@ -3000,214 +3172,6 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile, #endif } -#if !CONFIG_LV_MAP -#if !CONFIG_PVQ && !CONFIG_EC_ADAPT -static void build_tree_distribution(AV1_COMP *cpi, TX_SIZE tx_size, - av1_coeff_stats *coef_branch_ct, - av1_coeff_probs_model *coef_probs) { - av1_coeff_count *coef_counts = cpi->td.rd_counts.coef_counts[tx_size]; - unsigned int(*eob_branch_ct)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] = - cpi->common.counts.eob_branch[tx_size]; - int i, j, k, l, m; -#if CONFIG_RECT_TX - assert(!is_rect_tx(tx_size)); -#endif // CONFIG_RECT_TX - - for (i = 0; i < PLANE_TYPES; ++i) { - for (j = 0; j < REF_TYPES; ++j) { - for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - av1_tree_probs_from_distribution(av1_coef_tree, - coef_branch_ct[i][j][k][l], - coef_counts[i][j][k][l]); - coef_branch_ct[i][j][k][l][0][1] = - eob_branch_ct[i][j][k][l] - coef_branch_ct[i][j][k][l][0][0]; - for (m = 0; m < UNCONSTRAINED_NODES; ++m) - coef_probs[i][j][k][l][m] = - get_binary_prob(coef_branch_ct[i][j][k][l][m][0], - coef_branch_ct[i][j][k][l][m][1]); - } - } - } - } -} - -#if !CONFIG_EC_ADAPT -static void update_coef_probs_common(aom_writer *const bc, AV1_COMP *cpi, - TX_SIZE tx_size, - av1_coeff_stats *frame_branch_ct, - av1_coeff_probs_model *new_coef_probs) { - av1_coeff_probs_model *old_coef_probs = cpi->common.fc->coef_probs[tx_size]; - const aom_prob upd = DIFF_UPDATE_PROB; -#if CONFIG_EC_ADAPT - const int entropy_nodes_update = UNCONSTRAINED_NODES - 1; -#else - const int entropy_nodes_update = UNCONSTRAINED_NODES; -#endif - int i, j, k, l, t; - int stepsize = cpi->sf.coeff_prob_appx_step; -#if CONFIG_TILE_GROUPS - const int probwt = cpi->common.num_tg; -#else - const int probwt = 1; -#endif -#if CONFIG_RECT_TX - assert(!is_rect_tx(tx_size)); -#endif // CONFIG_RECT_TX - - switch (cpi->sf.use_fast_coef_updates) { - case TWO_LOOP: { - /* dry run to see if there is any update at all needed */ - int savings = 0; - int update[2] = { 0, 0 }; - for (i = 0; i < PLANE_TYPES; ++i) { - for (j = 0; j < REF_TYPES; ++j) { - for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - for (t = 0; t < entropy_nodes_update; ++t) { - aom_prob newp = new_coef_probs[i][j][k][l][t]; - const aom_prob oldp = old_coef_probs[i][j][k][l][t]; - int s; - int u = 0; - if (t == PIVOT_NODE) - s = av1_prob_diff_update_savings_search_model( - frame_branch_ct[i][j][k][l][0], oldp, &newp, upd, - stepsize, probwt); - else - s = av1_prob_diff_update_savings_search( - frame_branch_ct[i][j][k][l][t], oldp, &newp, upd, probwt); - - if (s > 0 && newp != oldp) u = 1; - if (u) - savings += s - (int)(av1_cost_zero(upd)); - else - savings -= (int)(av1_cost_zero(upd)); - update[u]++; - } - } - } - } - } - - /* Is coef updated at all */ - if (update[1] == 0 || savings < 0) { - aom_write_bit(bc, 0); - return; - } - aom_write_bit(bc, 1); - for (i = 0; i < PLANE_TYPES; ++i) { - for (j = 0; j < REF_TYPES; ++j) { - for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - // calc probs and branch cts for this frame only - for (t = 0; t < entropy_nodes_update; ++t) { - aom_prob newp = new_coef_probs[i][j][k][l][t]; - aom_prob *oldp = old_coef_probs[i][j][k][l] + t; - int s; - int u = 0; - if (t == PIVOT_NODE) - s = av1_prob_diff_update_savings_search_model( - frame_branch_ct[i][j][k][l][0], *oldp, &newp, upd, - stepsize, probwt); - else - s = av1_prob_diff_update_savings_search( - frame_branch_ct[i][j][k][l][t], *oldp, &newp, upd, - probwt); - if (s > 0 && newp != *oldp) u = 1; - aom_write(bc, u, upd); - if (u) { - /* send/use new probability */ - av1_write_prob_diff_update(bc, newp, *oldp); - *oldp = newp; - } - } - } - } - } - } - return; - } - - case ONE_LOOP_REDUCED: { - int updates = 0; - int noupdates_before_first = 0; - for (i = 0; i < PLANE_TYPES; ++i) { - for (j = 0; j < REF_TYPES; ++j) { - for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - // calc probs and branch cts for this frame only - for (t = 0; t < entropy_nodes_update; ++t) { - aom_prob newp = new_coef_probs[i][j][k][l][t]; - aom_prob *oldp = old_coef_probs[i][j][k][l] + t; - int s; - int u = 0; - if (t == PIVOT_NODE) { - s = av1_prob_diff_update_savings_search_model( - frame_branch_ct[i][j][k][l][0], *oldp, &newp, upd, - stepsize, probwt); - } else { - s = av1_prob_diff_update_savings_search( - frame_branch_ct[i][j][k][l][t], *oldp, &newp, upd, - probwt); - } - - if (s > 0 && newp != *oldp) u = 1; - updates += u; - if (u == 0 && updates == 0) { - noupdates_before_first++; - continue; - } - if (u == 1 && updates == 1) { - int v; - // first update - aom_write_bit(bc, 1); - for (v = 0; v < noupdates_before_first; ++v) - aom_write(bc, 0, upd); - } - aom_write(bc, u, upd); - if (u) { - /* send/use new probability */ - av1_write_prob_diff_update(bc, newp, *oldp); - *oldp = newp; - } - } - } - } - } - } - if (updates == 0) { - aom_write_bit(bc, 0); // no updates - } - return; - } - default: assert(0); - } -} -#endif - -#if !CONFIG_EC_ADAPT -static void update_coef_probs(AV1_COMP *cpi, aom_writer *w) { - const TX_MODE tx_mode = cpi->common.tx_mode; - const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode]; - TX_SIZE tx_size; - - for (tx_size = 0; tx_size <= max_tx_size; ++tx_size) { - av1_coeff_stats frame_branch_ct[PLANE_TYPES]; - av1_coeff_probs_model frame_coef_probs[PLANE_TYPES]; - if (cpi->td.counts->tx_size_totals[tx_size] <= 20 || CONFIG_RD_DEBUG || - (tx_size >= TX_16X16 && cpi->sf.tx_size_search_method == USE_TX_8X8)) { - aom_write_bit(w, 0); - } else { - build_tree_distribution(cpi, tx_size, frame_branch_ct, frame_coef_probs); - update_coef_probs_common(w, cpi, tx_size, frame_branch_ct, - frame_coef_probs); - } - } -} -#endif // !CONFIG_EC_ADAPT -#endif // !CONFIG_EC_ADAPT -#endif // !CONFIG_LV_MAP - #if CONFIG_LOOP_RESTORATION static void encode_restoration_mode(AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { @@ -3257,6 +3221,23 @@ static void encode_restoration_mode(AV1_COMMON *cm, wb, rsi->restoration_tilesize != (RESTORATION_TILESIZE_MAX >> 1)); } } + int s = AOMMIN(cm->subsampling_x, cm->subsampling_y); + if (s && (cm->rst_info[1].frame_restoration_type != RESTORE_NONE || + cm->rst_info[2].frame_restoration_type != RESTORE_NONE)) { + aom_wb_write_bit(wb, cm->rst_info[1].restoration_tilesize != + cm->rst_info[0].restoration_tilesize); + assert(cm->rst_info[1].restoration_tilesize == + cm->rst_info[0].restoration_tilesize || + cm->rst_info[1].restoration_tilesize == + (cm->rst_info[0].restoration_tilesize >> s)); + assert(cm->rst_info[2].restoration_tilesize == + cm->rst_info[1].restoration_tilesize); + } else if (!s) { + assert(cm->rst_info[1].restoration_tilesize == + cm->rst_info[0].restoration_tilesize); + assert(cm->rst_info[2].restoration_tilesize == + cm->rst_info[1].restoration_tilesize); + } } static void write_wiener_filter(WienerInfo *wiener_info, @@ -3311,16 +3292,23 @@ static void write_sgrproj_filter(SgrprojInfo *sgrproj_info, static void encode_restoration(AV1_COMMON *cm, aom_writer *wb) { int i, p; - const int ntiles = av1_get_rest_ntiles(cm->width, cm->height, - cm->rst_info[0].restoration_tilesize, - NULL, NULL, NULL, NULL); +#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 + const int ntiles = + av1_get_rest_ntiles(width, height, cm->rst_info[0].restoration_tilesize, + NULL, NULL, NULL, NULL); WienerInfo ref_wiener_info; SgrprojInfo ref_sgrproj_info; set_default_wiener(&ref_wiener_info); set_default_sgrproj(&ref_sgrproj_info); const int ntiles_uv = av1_get_rest_ntiles( - ROUND_POWER_OF_TWO(cm->width, cm->subsampling_x), - ROUND_POWER_OF_TWO(cm->height, cm->subsampling_y), + ROUND_POWER_OF_TWO(width, cm->subsampling_x), + ROUND_POWER_OF_TWO(height, cm->subsampling_y), cm->rst_info[1].restoration_tilesize, NULL, NULL, NULL, NULL); RestorationInfo *rsi = &cm->rst_info[0]; if (rsi->frame_restoration_type != RESTORE_NONE) { @@ -3389,6 +3377,12 @@ static void encode_loopfilter(AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { // Encode the loop filter level and type aom_wb_write_literal(wb, lf->filter_level, 6); +#if CONFIG_UV_LVL + if (lf->filter_level > 0) { + aom_wb_write_literal(wb, lf->filter_level_u, 6); + aom_wb_write_literal(wb, lf->filter_level_v, 6); + } +#endif aom_wb_write_literal(wb, lf->sharpness_level, 3); // Write out loop filter deltas applied at the MB level based on mode or @@ -3509,51 +3503,17 @@ static void encode_segmentation(AV1_COMMON *cm, MACROBLOCKD *xd, } } -#if !CONFIG_EC_ADAPT -static void update_seg_probs(AV1_COMP *cpi, aom_writer *w) { - AV1_COMMON *cm = &cpi->common; -#if CONFIG_TILE_GROUPS - const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif - - if (!cm->seg.enabled || !cm->seg.update_map) return; - - if (cm->seg.temporal_update) { - int i; - - for (i = 0; i < PREDICTION_PROBS; i++) - av1_cond_prob_diff_update(w, &cm->fc->seg.pred_probs[i], - cm->counts.seg.pred[i], probwt); - - prob_diff_update(av1_segment_tree, cm->fc->seg.tree_probs, - cm->counts.seg.tree_mispred, MAX_SEGMENTS, probwt, w); - } else { - prob_diff_update(av1_segment_tree, cm->fc->seg.tree_probs, - cm->counts.seg.tree_total, MAX_SEGMENTS, probwt, w); - } -} -#endif - -static void write_tx_mode(AV1_COMMON *cm, MACROBLOCKD *xd, TX_MODE *mode, +static void write_tx_mode(AV1_COMMON *cm, TX_MODE *mode, struct aom_write_bit_buffer *wb) { - int i, all_lossless = 1; - - if (cm->seg.enabled) { - for (i = 0; i < MAX_SEGMENTS; ++i) { - if (!xd->lossless[i]) { - all_lossless = 0; - break; - } - } - } else { - all_lossless = xd->lossless[0]; - } - if (all_lossless) { + if (cm->all_lossless) { *mode = ONLY_4X4; return; } +#if CONFIG_VAR_TX_NO_TX_MODE + (void)wb; + *mode = TX_MODE_SELECT; + return; +#else #if CONFIG_TX64X64 aom_wb_write_bit(wb, *mode == TX_MODE_SELECT); if (*mode != TX_MODE_SELECT) { @@ -3564,26 +3524,9 @@ static void write_tx_mode(AV1_COMMON *cm, MACROBLOCKD *xd, TX_MODE *mode, aom_wb_write_bit(wb, *mode == TX_MODE_SELECT); if (*mode != TX_MODE_SELECT) aom_wb_write_literal(wb, *mode, 2); #endif // CONFIG_TX64X64 +#endif // CONFIG_VAR_TX_NO_TX_MODE } -#if !CONFIG_EC_ADAPT -static void update_txfm_probs(AV1_COMMON *cm, aom_writer *w, - FRAME_COUNTS *counts) { -#if CONFIG_TILE_GROUPS - const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif - if (cm->tx_mode == TX_MODE_SELECT) { - int i, j; - for (i = 0; i < MAX_TX_DEPTH; ++i) - for (j = 0; j < TX_SIZE_CONTEXTS; ++j) - prob_diff_update(av1_tx_size_tree[i], cm->fc->tx_size_probs[i][j], - counts->tx_size[i][j], i + 2, probwt, w); - } -} -#endif - static void write_frame_interp_filter(InterpFilter filter, struct aom_write_bit_buffer *wb) { aom_wb_write_bit(wb, filter == SWITCHABLE); @@ -3624,52 +3567,52 @@ static void fix_interp_filter(AV1_COMMON *cm, FRAME_COUNTS *counts) { static void write_tile_info(const AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) { #if CONFIG_EXT_TILE - const int tile_width = - ALIGN_POWER_OF_TWO(cm->tile_width, cm->mib_size_log2) >> - cm->mib_size_log2; - const int tile_height = - ALIGN_POWER_OF_TWO(cm->tile_height, cm->mib_size_log2) >> - cm->mib_size_log2; - - assert(tile_width > 0); - assert(tile_height > 0); + if (cm->large_scale_tile) { + const int tile_width = + ALIGN_POWER_OF_TWO(cm->tile_width, cm->mib_size_log2) >> + cm->mib_size_log2; + const int tile_height = + ALIGN_POWER_OF_TWO(cm->tile_height, cm->mib_size_log2) >> + cm->mib_size_log2; - aom_wb_write_literal(wb, cm->tile_encoding_mode, 1); + assert(tile_width > 0); + assert(tile_height > 0); // Write the tile sizes #if CONFIG_EXT_PARTITION - if (cm->sb_size == BLOCK_128X128) { - assert(tile_width <= 32); - assert(tile_height <= 32); - aom_wb_write_literal(wb, tile_width - 1, 5); - aom_wb_write_literal(wb, tile_height - 1, 5); - } else + if (cm->sb_size == BLOCK_128X128) { + assert(tile_width <= 32); + assert(tile_height <= 32); + aom_wb_write_literal(wb, tile_width - 1, 5); + aom_wb_write_literal(wb, tile_height - 1, 5); + } else { #endif // CONFIG_EXT_PARTITION - { - assert(tile_width <= 64); - assert(tile_height <= 64); - aom_wb_write_literal(wb, tile_width - 1, 6); - aom_wb_write_literal(wb, tile_height - 1, 6); - } -#if CONFIG_DEPENDENT_HORZTILES - if (tile_height > 1) aom_wb_write_bit(wb, cm->dependent_horz_tiles); -#endif -#else - int min_log2_tile_cols, max_log2_tile_cols, ones; - av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); + assert(tile_width <= 64); + assert(tile_height <= 64); + aom_wb_write_literal(wb, tile_width - 1, 6); + aom_wb_write_literal(wb, tile_height - 1, 6); +#if CONFIG_EXT_PARTITION + } +#endif // CONFIG_EXT_PARTITION + } else { +#endif // CONFIG_EXT_TILE + int min_log2_tile_cols, max_log2_tile_cols, ones; + av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - // columns - ones = cm->log2_tile_cols - min_log2_tile_cols; - while (ones--) aom_wb_write_bit(wb, 1); + // columns + ones = cm->log2_tile_cols - min_log2_tile_cols; + while (ones--) aom_wb_write_bit(wb, 1); - if (cm->log2_tile_cols < max_log2_tile_cols) aom_wb_write_bit(wb, 0); + if (cm->log2_tile_cols < max_log2_tile_cols) aom_wb_write_bit(wb, 0); - // rows - aom_wb_write_bit(wb, cm->log2_tile_rows != 0); - if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->log2_tile_rows != 1); + // rows + aom_wb_write_bit(wb, cm->log2_tile_rows != 0); + if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->log2_tile_rows != 1); #if CONFIG_DEPENDENT_HORZTILES - if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->dependent_horz_tiles); + if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->dependent_horz_tiles); #endif +#if CONFIG_EXT_TILE + } #endif // CONFIG_EXT_TILE #if CONFIG_LOOPFILTERING_ACROSS_TILES @@ -3782,16 +3725,9 @@ static INLINE int find_identical_tile( } #endif // CONFIG_EXT_TILE -#if CONFIG_TILE_GROUPS -static uint32_t write_tiles(AV1_COMP *const cpi, - struct aom_write_bit_buffer *wb, - unsigned int *max_tile_size, - unsigned int *max_tile_col_size) { -#else static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, unsigned int *max_tile_size, unsigned int *max_tile_col_size) { -#endif const AV1_COMMON *const cm = &cpi->common; #if CONFIG_ANS struct BufAnsCoder *buf_ans = &cpi->buf_ans; @@ -3805,19 +3741,24 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, const int tile_cols = cm->tile_cols; const int tile_rows = cm->tile_rows; unsigned int tile_size = 0; -#if CONFIG_TILE_GROUPS + const int have_tiles = tile_cols * tile_rows > 1; + struct aom_write_bit_buffer wb = { dst, 0 }; const int n_log2_tiles = cm->log2_tile_rows + cm->log2_tile_cols; - const int have_tiles = n_log2_tiles > 0; uint32_t comp_hdr_size; // Fixed size tile groups for the moment const int num_tg_hdrs = cm->num_tg; - const int tg_size = (tile_rows * tile_cols + num_tg_hdrs - 1) / num_tg_hdrs; + const int tg_size = +#if CONFIG_EXT_TILE + (cm->large_scale_tile) + ? 1 + : +#endif // CONFIG_EXT_TILE + (tile_rows * tile_cols + num_tg_hdrs - 1) / num_tg_hdrs; int tile_count = 0; int tg_count = 1; int tile_size_bytes = 4; int tile_col_size_bytes; uint32_t uncompressed_hdr_size = 0; - uint8_t *dst = NULL; struct aom_write_bit_buffer comp_hdr_len_wb; struct aom_write_bit_buffer tg_params_wb; struct aom_write_bit_buffer tile_size_bytes_wb; @@ -3825,10 +3766,6 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, int mtu_size = cpi->oxcf.mtu; int curr_tg_data_size = 0; int hdr_size; -#endif -#if CONFIG_EXT_TILE - const int have_tiles = tile_cols * tile_rows > 1; -#endif // CONFIG_EXT_TILE *max_tile_size = 0; *max_tile_col_size = 0; @@ -3837,282 +3774,274 @@ static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst, // later compact the data if smaller headers are adequate. #if CONFIG_EXT_TILE - for (tile_col = 0; tile_col < tile_cols; tile_col++) { - TileInfo tile_info; - const int is_last_col = (tile_col == tile_cols - 1); - const uint32_t col_offset = total_size; - - av1_tile_set_col(&tile_info, cm, tile_col); - - // The last column does not have a column header - if (!is_last_col) total_size += 4; - - for (tile_row = 0; tile_row < tile_rows; tile_row++) { - TileBufferEnc *const buf = &tile_buffers[tile_row][tile_col]; - const TOKENEXTRA *tok = tok_buffers[tile_row][tile_col]; - const TOKENEXTRA *tok_end = tok + cpi->tok_count[tile_row][tile_col]; - const int data_offset = have_tiles ? 4 : 0; -#if CONFIG_EC_ADAPT - const int tile_idx = tile_row * tile_cols + tile_col; - TileDataEnc *this_tile = &cpi->tile_data[tile_idx]; -#endif - av1_tile_set_row(&tile_info, cm, tile_row); + if (cm->large_scale_tile) { + for (tile_col = 0; tile_col < tile_cols; tile_col++) { + TileInfo tile_info; + const int is_last_col = (tile_col == tile_cols - 1); + const uint32_t col_offset = total_size; - buf->data = dst + total_size; + av1_tile_set_col(&tile_info, cm, tile_col); - // 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; -#if CONFIG_EC_ADAPT - // Initialise tile context from the frame context - this_tile->tctx = *cm->fc; - cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; -#endif + // The last column does not have a column header + if (!is_last_col) total_size += 4; + + for (tile_row = 0; tile_row < tile_rows; tile_row++) { + TileBufferEnc *const buf = &tile_buffers[tile_row][tile_col]; + const TOKENEXTRA *tok = tok_buffers[tile_row][tile_col]; + const TOKENEXTRA *tok_end = tok + cpi->tok_count[tile_row][tile_col]; + const int data_offset = have_tiles ? 4 : 0; + const int tile_idx = tile_row * tile_cols + tile_col; + TileDataEnc *this_tile = &cpi->tile_data[tile_idx]; + av1_tile_set_row(&tile_info, cm, tile_row); + + buf->data = dst + total_size; + + // 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; #if CONFIG_PVQ - cpi->td.mb.pvq_q = &this_tile->pvq_q; - cpi->td.mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context; + cpi->td.mb.pvq_q = &this_tile->pvq_q; + cpi->td.mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context; #endif // CONFIG_PVQ #if !CONFIG_ANS - aom_start_encode(&mode_bc, buf->data + data_offset); - write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end); - assert(tok == tok_end); - aom_stop_encode(&mode_bc); - tile_size = mode_bc.pos; + aom_start_encode(&mode_bc, buf->data + data_offset); + write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end); + assert(tok == tok_end); + aom_stop_encode(&mode_bc); + tile_size = mode_bc.pos; #else - buf_ans_write_init(buf_ans, buf->data + data_offset); - write_modes(cpi, &tile_info, buf_ans, &tok, tok_end); - assert(tok == tok_end); - aom_buf_ans_flush(buf_ans); - tile_size = buf_ans_write_end(buf_ans); + buf_ans_write_init(buf_ans, buf->data + data_offset); + write_modes(cpi, &tile_info, buf_ans, &tok, tok_end); + assert(tok == tok_end); + aom_buf_ans_flush(buf_ans); + tile_size = buf_ans_write_end(buf_ans); #endif // !CONFIG_ANS #if CONFIG_PVQ - cpi->td.mb.pvq_q = NULL; + cpi->td.mb.pvq_q = NULL; #endif - buf->size = tile_size; - - // Record the maximum tile size we see, so we can compact headers later. - *max_tile_size = AOMMAX(*max_tile_size, tile_size); - - if (have_tiles) { - // tile header: size of this tile, or copy offset - uint32_t tile_header = tile_size; + buf->size = tile_size; - // If the tile_encoding_mode is 1 (i.e. TILE_VR), check if this tile is - // a copy tile. - // Very low chances to have copy tiles on the key frames, so don't - // search on key frames to reduce unnecessary search. - if (cm->frame_type != KEY_FRAME && cm->tile_encoding_mode) { - const int idendical_tile_offset = - find_identical_tile(tile_row, tile_col, tile_buffers); + // Record the maximum tile size we see, so we can compact headers later. + *max_tile_size = AOMMAX(*max_tile_size, tile_size); - if (idendical_tile_offset > 0) { - tile_size = 0; - tile_header = idendical_tile_offset | 0x80; - tile_header <<= 24; + if (have_tiles) { + // tile header: size of this tile, or copy offset + uint32_t tile_header = tile_size; + const int tile_copy_mode = + ((AOMMAX(cm->tile_width, cm->tile_height) << MI_SIZE_LOG2) <= 256) + ? 1 + : 0; + + // If tile_copy_mode = 1, check if this tile is a copy tile. + // Very low chances to have copy tiles on the key frames, so don't + // search on key frames to reduce unnecessary search. + if (cm->frame_type != KEY_FRAME && tile_copy_mode) { + const int idendical_tile_offset = + find_identical_tile(tile_row, tile_col, tile_buffers); + + if (idendical_tile_offset > 0) { + tile_size = 0; + tile_header = idendical_tile_offset | 0x80; + tile_header <<= 24; + } } + + mem_put_le32(buf->data, tile_header); } - mem_put_le32(buf->data, tile_header); + total_size += tile_size; } - total_size += tile_size; - } - - if (!is_last_col) { - uint32_t col_size = total_size - col_offset - 4; - mem_put_le32(dst + col_offset, col_size); + if (!is_last_col) { + uint32_t col_size = total_size - col_offset - 4; + mem_put_le32(dst + col_offset, col_size); - // If it is not final packing, record the maximum tile column size we see, - // otherwise, check if the tile size is out of the range. - *max_tile_col_size = AOMMAX(*max_tile_col_size, col_size); + // If it is not final packing, record the maximum tile column size we + // see, otherwise, check if the tile size is out of the range. + *max_tile_col_size = AOMMAX(*max_tile_col_size, col_size); + } } - } -#else -#if CONFIG_TILE_GROUPS - write_uncompressed_header(cpi, wb); + } else { +#endif // CONFIG_EXT_TILE + write_uncompressed_header(cpi, &wb); #if CONFIG_EXT_REFS - if (cm->show_existing_frame) { - total_size = aom_wb_bytes_written(wb); - return (uint32_t)total_size; - } + if (cm->show_existing_frame) { + total_size = aom_wb_bytes_written(&wb); + return (uint32_t)total_size; + } #endif // CONFIG_EXT_REFS - // Write the tile length code - tile_size_bytes_wb = *wb; - aom_wb_write_literal(wb, 3, 2); + // Write the tile length code + tile_size_bytes_wb = wb; + aom_wb_write_literal(&wb, 3, 2); - /* Write a placeholder for the number of tiles in each tile group */ - tg_params_wb = *wb; - saved_offset = wb->bit_offset; - if (have_tiles) { - aom_wb_overwrite_literal(wb, 3, n_log2_tiles); - aom_wb_overwrite_literal(wb, (1 << n_log2_tiles) - 1, n_log2_tiles); - } - - /* Write a placeholder for the compressed header length */ - comp_hdr_len_wb = *wb; - aom_wb_write_literal(wb, 0, 16); - - uncompressed_hdr_size = aom_wb_bytes_written(wb); - dst = wb->bit_buffer; - comp_hdr_size = write_compressed_header(cpi, dst + uncompressed_hdr_size); - aom_wb_overwrite_literal(&comp_hdr_len_wb, (int)(comp_hdr_size), 16); - hdr_size = uncompressed_hdr_size + comp_hdr_size; - total_size += hdr_size; -#endif + /* Write a placeholder for the number of tiles in each tile group */ + tg_params_wb = wb; + saved_offset = wb.bit_offset; + if (have_tiles) { + aom_wb_overwrite_literal(&wb, 3, n_log2_tiles); + aom_wb_overwrite_literal(&wb, (1 << n_log2_tiles) - 1, n_log2_tiles); + } - for (tile_row = 0; tile_row < tile_rows; tile_row++) { - TileInfo tile_info; - const int is_last_row = (tile_row == tile_rows - 1); - av1_tile_set_row(&tile_info, cm, tile_row); + /* Write a placeholder for the compressed header length */ + comp_hdr_len_wb = wb; + aom_wb_write_literal(&wb, 0, 16); - for (tile_col = 0; tile_col < tile_cols; tile_col++) { - const int tile_idx = tile_row * tile_cols + tile_col; - TileBufferEnc *const buf = &tile_buffers[tile_row][tile_col]; -#if CONFIG_PVQ || CONFIG_EC_ADAPT - TileDataEnc *this_tile = &cpi->tile_data[tile_idx]; -#endif - const TOKENEXTRA *tok = tok_buffers[tile_row][tile_col]; - const TOKENEXTRA *tok_end = tok + cpi->tok_count[tile_row][tile_col]; - const int is_last_col = (tile_col == tile_cols - 1); - const int is_last_tile = is_last_col && is_last_row; -#if !CONFIG_TILE_GROUPS - (void)tile_idx; -#else + uncompressed_hdr_size = aom_wb_bytes_written(&wb); + comp_hdr_size = write_compressed_header(cpi, dst + uncompressed_hdr_size); + aom_wb_overwrite_literal(&comp_hdr_len_wb, (int)(comp_hdr_size), 16); + hdr_size = uncompressed_hdr_size + comp_hdr_size; + total_size += hdr_size; - if ((!mtu_size && tile_count > tg_size) || - (mtu_size && tile_count && curr_tg_data_size >= mtu_size)) { - // New tile group - tg_count++; - // We've exceeded the packet size - if (tile_count > 1) { - /* The last tile exceeded the packet size. The tile group size - should therefore be tile_count-1. - Move the last tile and insert headers before it - */ - uint32_t old_total_size = total_size - tile_size - 4; - memmove(dst + old_total_size + hdr_size, dst + old_total_size, - (tile_size + 4) * sizeof(uint8_t)); - // Copy uncompressed header - memmove(dst + old_total_size, dst, - uncompressed_hdr_size * sizeof(uint8_t)); - // Write the number of tiles in the group into the last uncompressed - // header before the one we've just inserted - aom_wb_overwrite_literal(&tg_params_wb, tile_idx - tile_count, - n_log2_tiles); - aom_wb_overwrite_literal(&tg_params_wb, tile_count - 2, n_log2_tiles); - // Update the pointer to the last TG params - tg_params_wb.bit_offset = saved_offset + 8 * old_total_size; - // Copy compressed header - memmove(dst + old_total_size + uncompressed_hdr_size, - dst + uncompressed_hdr_size, comp_hdr_size * sizeof(uint8_t)); - total_size += hdr_size; - tile_count = 1; - curr_tg_data_size = hdr_size + tile_size + 4; + for (tile_row = 0; tile_row < tile_rows; tile_row++) { + TileInfo tile_info; + const int is_last_row = (tile_row == tile_rows - 1); + av1_tile_set_row(&tile_info, cm, tile_row); - } else { - // We exceeded the packet size in just one tile - // Copy uncompressed header - memmove(dst + total_size, dst, - uncompressed_hdr_size * sizeof(uint8_t)); - // Write the number of tiles in the group into the last uncompressed - // header - aom_wb_overwrite_literal(&tg_params_wb, tile_idx - tile_count, - n_log2_tiles); - aom_wb_overwrite_literal(&tg_params_wb, tile_count - 1, n_log2_tiles); - tg_params_wb.bit_offset = saved_offset + 8 * total_size; - // Copy compressed header - memmove(dst + total_size + uncompressed_hdr_size, - dst + uncompressed_hdr_size, comp_hdr_size * sizeof(uint8_t)); - total_size += hdr_size; - tile_count = 0; - curr_tg_data_size = hdr_size; + for (tile_col = 0; tile_col < tile_cols; tile_col++) { + const int tile_idx = tile_row * tile_cols + tile_col; + TileBufferEnc *const buf = &tile_buffers[tile_row][tile_col]; + TileDataEnc *this_tile = &cpi->tile_data[tile_idx]; + const TOKENEXTRA *tok = tok_buffers[tile_row][tile_col]; + const TOKENEXTRA *tok_end = tok + cpi->tok_count[tile_row][tile_col]; + const int is_last_col = (tile_col == tile_cols - 1); + const int is_last_tile = is_last_col && is_last_row; + + if ((!mtu_size && tile_count > tg_size) || + (mtu_size && tile_count && curr_tg_data_size >= mtu_size)) { + // New tile group + tg_count++; + // We've exceeded the packet size + if (tile_count > 1) { + /* The last tile exceeded the packet size. The tile group size + should therefore be tile_count-1. + Move the last tile and insert headers before it + */ + uint32_t old_total_size = total_size - tile_size - 4; + memmove(dst + old_total_size + hdr_size, dst + old_total_size, + (tile_size + 4) * sizeof(uint8_t)); + // Copy uncompressed header + memmove(dst + old_total_size, dst, + uncompressed_hdr_size * sizeof(uint8_t)); + // Write the number of tiles in the group into the last uncompressed + // header before the one we've just inserted + aom_wb_overwrite_literal(&tg_params_wb, tile_idx - tile_count, + n_log2_tiles); + aom_wb_overwrite_literal(&tg_params_wb, tile_count - 2, + n_log2_tiles); + // Update the pointer to the last TG params + tg_params_wb.bit_offset = saved_offset + 8 * old_total_size; + // Copy compressed header + memmove(dst + old_total_size + uncompressed_hdr_size, + dst + uncompressed_hdr_size, + comp_hdr_size * sizeof(uint8_t)); + total_size += hdr_size; + tile_count = 1; + curr_tg_data_size = hdr_size + tile_size + 4; + } else { + // We exceeded the packet size in just one tile + // Copy uncompressed header + memmove(dst + total_size, dst, + uncompressed_hdr_size * sizeof(uint8_t)); + // Write the number of tiles in the group into the last uncompressed + // header + aom_wb_overwrite_literal(&tg_params_wb, tile_idx - tile_count, + n_log2_tiles); + aom_wb_overwrite_literal(&tg_params_wb, tile_count - 1, + n_log2_tiles); + tg_params_wb.bit_offset = saved_offset + 8 * total_size; + // Copy compressed header + memmove(dst + total_size + uncompressed_hdr_size, + dst + uncompressed_hdr_size, + comp_hdr_size * sizeof(uint8_t)); + total_size += hdr_size; + tile_count = 0; + curr_tg_data_size = hdr_size; + } } - } - tile_count++; -#endif - av1_tile_set_col(&tile_info, cm, tile_col); + tile_count++; + av1_tile_set_col(&tile_info, cm, tile_col); -#if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS - av1_tile_set_tg_boundary(&tile_info, cm, tile_row, tile_col); +#if CONFIG_DEPENDENT_HORZTILES + av1_tile_set_tg_boundary(&tile_info, cm, tile_row, tile_col); #endif - buf->data = dst + total_size; + buf->data = dst + total_size; - // The last tile does not have a header. - if (!is_last_tile) total_size += 4; + // The last tile does not have a header. + if (!is_last_tile) total_size += 4; -#if CONFIG_EC_ADAPT - // Initialise tile context from the frame context - this_tile->tctx = *cm->fc; - cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; -#endif + // Initialise tile context from the frame context + this_tile->tctx = *cm->fc; + cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; #if CONFIG_PVQ - cpi->td.mb.pvq_q = &this_tile->pvq_q; - cpi->td.mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context; + cpi->td.mb.pvq_q = &this_tile->pvq_q; + cpi->td.mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context; #endif // CONFIG_PVQ #if CONFIG_ANS - buf_ans_write_init(buf_ans, dst + total_size); - write_modes(cpi, &tile_info, buf_ans, &tok, tok_end); - assert(tok == tok_end); - aom_buf_ans_flush(buf_ans); - tile_size = buf_ans_write_end(buf_ans); + buf_ans_write_init(buf_ans, dst + total_size); + write_modes(cpi, &tile_info, buf_ans, &tok, tok_end); + assert(tok == tok_end); + aom_buf_ans_flush(buf_ans); + tile_size = buf_ans_write_end(buf_ans); #else aom_start_encode(&mode_bc, dst + total_size); write_modes(cpi, &tile_info, &mode_bc, &tok, tok_end); #if !CONFIG_LV_MAP +#if !CONFIG_PVQ assert(tok == tok_end); +#endif // !CONFIG_PVQ #endif // !CONFIG_LV_MAP aom_stop_encode(&mode_bc); tile_size = mode_bc.pos; #endif // CONFIG_ANS #if CONFIG_PVQ - cpi->td.mb.pvq_q = NULL; + cpi->td.mb.pvq_q = NULL; #endif - assert(tile_size > 0); + assert(tile_size > 0); -#if CONFIG_TILE_GROUPS - curr_tg_data_size += tile_size + 4; -#endif - buf->size = tile_size; + curr_tg_data_size += tile_size + 4; + buf->size = tile_size; - if (!is_last_tile) { - *max_tile_size = AOMMAX(*max_tile_size, tile_size); - // size of this tile - mem_put_le32(buf->data, tile_size); - } + if (!is_last_tile) { + *max_tile_size = AOMMAX(*max_tile_size, tile_size); + // size of this tile + mem_put_le32(buf->data, tile_size); + } - total_size += tile_size; + total_size += tile_size; + } + } + // Write the final tile group size + if (n_log2_tiles) { + aom_wb_overwrite_literal(&tg_params_wb, (1 << n_log2_tiles) - tile_count, + n_log2_tiles); + aom_wb_overwrite_literal(&tg_params_wb, tile_count - 1, n_log2_tiles); + } + // Remux if possible. TODO (Thomas Davies): do this for more than one tile + // group + if (have_tiles && tg_count == 1) { + int data_size = total_size - (uncompressed_hdr_size + comp_hdr_size); + data_size = remux_tiles(cm, dst + uncompressed_hdr_size + comp_hdr_size, + data_size, *max_tile_size, *max_tile_col_size, + &tile_size_bytes, &tile_col_size_bytes); + total_size = data_size + uncompressed_hdr_size + comp_hdr_size; + aom_wb_overwrite_literal(&tile_size_bytes_wb, tile_size_bytes - 1, 2); } - } -#if CONFIG_TILE_GROUPS - // Write the final tile group size - if (n_log2_tiles) { - aom_wb_overwrite_literal(&tg_params_wb, (1 << n_log2_tiles) - tile_count, - n_log2_tiles); - aom_wb_overwrite_literal(&tg_params_wb, tile_count - 1, n_log2_tiles); - } - // Remux if possible. TODO (Thomas Davies): do this for more than one tile - // group - if (have_tiles && tg_count == 1) { - int data_size = total_size - (uncompressed_hdr_size + comp_hdr_size); - data_size = remux_tiles(cm, dst + uncompressed_hdr_size + comp_hdr_size, - data_size, *max_tile_size, *max_tile_col_size, - &tile_size_bytes, &tile_col_size_bytes); - total_size = data_size + uncompressed_hdr_size + comp_hdr_size; - aom_wb_overwrite_literal(&tile_size_bytes_wb, tile_size_bytes - 1, 2); - } -#endif +#if CONFIG_EXT_TILE + } #endif // CONFIG_EXT_TILE return (uint32_t)total_size; } static void write_render_size(const AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { - const int scaling_active = - cm->width != cm->render_width || cm->height != cm->render_height; + const int scaling_active = !av1_resize_unscaled(cm); aom_wb_write_bit(wb, scaling_active); if (scaling_active) { aom_wb_write_literal(wb, cm->render_width - 1, 16); @@ -4124,11 +4053,10 @@ static void write_render_size(const AV1_COMMON *cm, static void write_superres_scale(const AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) { // First bit is whether to to scale or not - if (cm->superres_scale_numerator == SUPERRES_SCALE_DENOMINATOR) { + if (cm->superres_scale_numerator == SCALE_DENOMINATOR) { aom_wb_write_bit(wb, 0); // no scaling } else { aom_wb_write_bit(wb, 1); // scaling, write scale factor - // TODO(afergs): write factor to the compressed header instead aom_wb_write_literal( wb, cm->superres_scale_numerator - SUPERRES_SCALE_NUMERATOR_MIN, SUPERRES_SCALE_BITS); @@ -4138,13 +4066,15 @@ static void write_superres_scale(const AV1_COMMON *const cm, static void write_frame_size(const AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { - aom_wb_write_literal(wb, cm->width - 1, 16); - aom_wb_write_literal(wb, cm->height - 1, 16); - - write_render_size(cm, wb); #if CONFIG_FRAME_SUPERRES + aom_wb_write_literal(wb, cm->superres_upscaled_width - 1, 16); + aom_wb_write_literal(wb, cm->superres_upscaled_height - 1, 16); write_superres_scale(cm, wb); +#else + aom_wb_write_literal(wb, cm->width - 1, 16); + aom_wb_write_literal(wb, cm->height - 1, 16); #endif // CONFIG_FRAME_SUPERRES + write_render_size(cm, wb); } static void write_frame_size_with_refs(AV1_COMP *cpi, @@ -4157,20 +4087,26 @@ static void write_frame_size_with_refs(AV1_COMP *cpi, YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame); if (cfg != NULL) { +#if CONFIG_FRAME_SUPERRES + found = cm->superres_upscaled_width == cfg->y_crop_width && + cm->superres_upscaled_height == cfg->y_crop_height; +#else found = cm->width == cfg->y_crop_width && cm->height == cfg->y_crop_height; +#endif found &= cm->render_width == cfg->render_width && cm->render_height == cfg->render_height; } aom_wb_write_bit(wb, found); if (found) { +#if CONFIG_FRAME_SUPERRES + write_superres_scale(cm, wb); +#endif // CONFIG_FRAME_SUPERRES break; } } - if (!found) { - write_frame_size(cm, wb); - } + if (!found) write_frame_size(cm, wb); } static void write_sync_code(struct aom_write_bit_buffer *wb) { @@ -4196,7 +4132,12 @@ static void write_bitdepth_colorspace_sampling( assert(cm->bit_depth > AOM_BITS_8); aom_wb_write_bit(wb, cm->bit_depth == AOM_BITS_10 ? 0 : 1); } +#if CONFIG_COLORSPACE_HEADERS + aom_wb_write_literal(wb, cm->color_space, 5); + aom_wb_write_literal(wb, cm->transfer_function, 5); +#else aom_wb_write_literal(wb, cm->color_space, 3); +#endif if (cm->color_space != AOM_CS_SRGB) { // 0: [16, 235] (i.e. xvYCC), 1: [0, 255] aom_wb_write_bit(wb, cm->color_range); @@ -4208,6 +4149,11 @@ static void write_bitdepth_colorspace_sampling( } else { assert(cm->subsampling_x == 1 && cm->subsampling_y == 1); } +#if CONFIG_COLORSPACE_HEADERS + if (cm->subsampling_x == 1 && cm->subsampling_y == 1) { + aom_wb_write_literal(wb, cm->chroma_sample_position, 2); + } +#endif } else { assert(cm->profile == PROFILE_1 || cm->profile == PROFILE_3); aom_wb_write_bit(wb, 0); // unused @@ -4215,9 +4161,17 @@ static void write_bitdepth_colorspace_sampling( } #if CONFIG_REFERENCE_BUFFER -void write_sequence_header(SequenceHeader *seq_params) { +void write_sequence_header( +#if CONFIG_EXT_TILE + AV1_COMMON *const cm, +#endif // CONFIG_EXT_TILE + SequenceHeader *seq_params) { /* Placeholder for actually writing to the bitstream */ - seq_params->frame_id_numbers_present_flag = FRAME_ID_NUMBERS_PRESENT_FLAG; + seq_params->frame_id_numbers_present_flag = +#if CONFIG_EXT_TILE + cm->large_scale_tile ? 0 : +#endif // CONFIG_EXT_TILE + FRAME_ID_NUMBERS_PRESENT_FLAG; seq_params->frame_id_length_minus7 = FRAME_ID_LENGTH_MINUS7; seq_params->delta_frame_id_length_minus2 = DELTA_FRAME_ID_LENGTH_MINUS2; } @@ -4236,7 +4190,11 @@ static void write_compound_tools(const AV1_COMMON *cm, } #endif // CONFIG_INTERINTRA #if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT +#if CONFIG_COMPOUND_SINGLEREF + if (!frame_is_intra_only(cm)) { +#else // !CONFIG_COMPOUND_SINGLEREF if (!frame_is_intra_only(cm) && cm->reference_mode != SINGLE_REFERENCE) { +#endif // CONFIG_COMPOUND_SINGLEREF aom_wb_write_bit(wb, cm->allow_masked_compound); } else { assert(cm->allow_masked_compound == 0); @@ -4252,13 +4210,21 @@ static void write_uncompressed_header(AV1_COMP *cpi, #if CONFIG_REFERENCE_BUFFER /* TODO: Move outside frame loop or inside key-frame branch */ - write_sequence_header(&cpi->seq_params); + write_sequence_header( +#if CONFIG_EXT_TILE + cm, +#endif // CONFIG_EXT_TILE + &cpi->seq_params); #endif aom_wb_write_literal(wb, AOM_FRAME_MARKER, 2); write_profile(cm->profile, wb); +#if CONFIG_EXT_TILE + aom_wb_write_literal(wb, cm->large_scale_tile, 1); +#endif // CONFIG_EXT_TILE + #if CONFIG_EXT_REFS // NOTE: By default all coded frames to be used as a reference cm->is_reference_frame = 1; @@ -4309,11 +4275,6 @@ static void write_uncompressed_header(AV1_COMP *cpi, } #endif -#if CONFIG_FRAME_SUPERRES - // TODO(afergs): Remove - this is just to stop superres from breaking - cm->superres_scale_numerator = SUPERRES_SCALE_DENOMINATOR; -#endif // CONFIG_FRAME_SUPERRES - if (cm->frame_type == KEY_FRAME) { write_sync_code(wb); write_bitdepth_colorspace_sampling(cm, wb); @@ -4447,12 +4408,6 @@ static void write_uncompressed_header(AV1_COMP *cpi, #endif // CONFIG_EXT_PARTITION encode_loopfilter(cm, wb); -#if CONFIG_CDEF - encode_cdef(cm, wb); -#endif -#if CONFIG_LOOP_RESTORATION - encode_restoration_mode(cm, wb); -#endif // CONFIG_LOOP_RESTORATION encode_quantization(cm, wb); encode_segmentation(cm, xd, wb); #if CONFIG_DELTA_Q @@ -4485,8 +4440,15 @@ static void write_uncompressed_header(AV1_COMP *cpi, } } #endif - - write_tx_mode(cm, xd, &cm->tx_mode, wb); +#if CONFIG_CDEF + if (!cm->all_lossless) { + encode_cdef(cm, wb); + } +#endif +#if CONFIG_LOOP_RESTORATION + encode_restoration_mode(cm, wb); +#endif // CONFIG_LOOP_RESTORATION + write_tx_mode(cm, &cm->tx_mode, wb); if (cpi->allow_comp_inter_inter) { const int use_hybrid_pred = cm->reference_mode == REFERENCE_MODE_SELECT; @@ -4513,13 +4475,13 @@ static void write_uncompressed_header(AV1_COMP *cpi, #if CONFIG_GLOBAL_MOTION static void write_global_motion_params(WarpedMotionParams *params, WarpedMotionParams *ref_params, - aom_prob *probs, aom_writer *w, - int allow_hp) { + aom_writer *w, int allow_hp) { TransformationType type = params->wmtype; int trans_bits; int trans_prec_diff; - av1_write_token(w, av1_global_motion_types_tree, probs, - &global_motion_types_encodings[type]); + aom_write_bit(w, type != IDENTITY); + if (type != IDENTITY) aom_write_literal(w, type - 1, GLOBAL_TYPE_BITS); + switch (type) { case HOMOGRAPHY: case HORTRAPEZOID: @@ -4584,10 +4546,18 @@ static void write_global_motion_params(WarpedMotionParams *params, static void write_global_motion(AV1_COMP *cpi, aom_writer *w) { AV1_COMMON *const cm = &cpi->common; int frame; + YV12_BUFFER_CONFIG *ref_buf; for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) { - write_global_motion_params( - &cm->global_motion[frame], &cm->prev_frame->global_motion[frame], - cm->fc->global_motion_types_prob, w, cm->allow_high_precision_mv); + ref_buf = get_ref_frame_buffer(cpi, frame); + if (cpi->source->y_crop_width == ref_buf->y_crop_width && + cpi->source->y_crop_height == ref_buf->y_crop_height) { + write_global_motion_params(&cm->global_motion[frame], + &cm->prev_frame->global_motion[frame], w, + cm->allow_high_precision_mv); + } else { + assert(cm->global_motion[frame].wmtype == IDENTITY && + "Invalid warp type for frames of different resolutions"); + } /* printf("Frame %d/%d: Enc Ref %d (used %d): %d %d %d %d\n", cm->current_video_frame, cm->show_frame, frame, @@ -4605,15 +4575,17 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; #endif // CONFIG_SUPERTX FRAME_CONTEXT *const fc = cm->fc; - FRAME_COUNTS *counts = cpi->td.counts; aom_writer *header_bc; - int i, j; + int i; +#if !CONFIG_NEW_MULTISYMBOL + FRAME_COUNTS *counts = cpi->td.counts; + int j; +#endif -#if CONFIG_TILE_GROUPS const int probwt = cm->num_tg; -#else - const int probwt = 1; -#endif + (void)probwt; + (void)i; + (void)fc; #if CONFIG_ANS int header_size; @@ -4628,96 +4600,26 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { #if CONFIG_LOOP_RESTORATION encode_restoration(cm, header_bc); #endif // CONFIG_LOOP_RESTORATION -#if !CONFIG_EC_ADAPT - update_txfm_probs(cm, header_bc, counts); -#endif -#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT +#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, cm->counts.quarter_tx_size, probwt); -#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT +#endif #if CONFIG_LV_MAP av1_write_txb_probs(cpi, header_bc); -#else -#if !CONFIG_PVQ -#if !CONFIG_EC_ADAPT - update_coef_probs(cpi, header_bc); -#endif // !CONFIG_EC_ADAPT -#endif // CONFIG_PVQ #endif // CONFIG_LV_MAP -#if CONFIG_VAR_TX +#if CONFIG_VAR_TX && !CONFIG_NEW_MULTISYMBOL update_txfm_partition_probs(cm, header_bc, counts, probwt); #endif +#if !CONFIG_NEW_MULTISYMBOL update_skip_probs(cm, header_bc, counts); -#if !CONFIG_EC_ADAPT && CONFIG_DELTA_Q - update_delta_q_probs(cm, header_bc, counts); -#if CONFIG_EXT_DELTA_Q - update_delta_lf_probs(cm, header_bc, counts); -#endif -#endif -#if !CONFIG_EC_ADAPT - update_seg_probs(cpi, header_bc); - - for (i = 0; i < INTRA_MODES; ++i) { - prob_diff_update(av1_intra_mode_tree, fc->uv_mode_prob[i], - counts->uv_mode[i], INTRA_MODES, probwt, header_bc); - } - -#if CONFIG_EXT_PARTITION_TYPES - for (i = 0; i < PARTITION_PLOFFSET; ++i) - prob_diff_update(av1_partition_tree, fc->partition_prob[i], - counts->partition[i], PARTITION_TYPES, probwt, header_bc); - for (; i < PARTITION_CONTEXTS_PRIMARY; ++i) - prob_diff_update(av1_ext_partition_tree, fc->partition_prob[i], - counts->partition[i], EXT_PARTITION_TYPES, probwt, - header_bc); -#else - for (i = 0; i < PARTITION_CONTEXTS_PRIMARY; ++i) - prob_diff_update(av1_partition_tree, fc->partition_prob[i], - counts->partition[i], PARTITION_TYPES, probwt, header_bc); -#endif // CONFIG_EXT_PARTITION_TYPES -#if CONFIG_UNPOISON_PARTITION_CTX - for (; i < PARTITION_CONTEXTS_PRIMARY + PARTITION_BLOCK_SIZES; ++i) { - unsigned int ct[2] = { counts->partition[i][PARTITION_VERT], - counts->partition[i][PARTITION_SPLIT] }; - assert(counts->partition[i][PARTITION_NONE] == 0); - assert(counts->partition[i][PARTITION_HORZ] == 0); - assert(fc->partition_prob[i][PARTITION_NONE] == 0); - assert(fc->partition_prob[i][PARTITION_HORZ] == 0); - av1_cond_prob_diff_update(header_bc, &fc->partition_prob[i][PARTITION_VERT], - ct, probwt); - } - for (; i < PARTITION_CONTEXTS_PRIMARY + 2 * PARTITION_BLOCK_SIZES; ++i) { - unsigned int ct[2] = { counts->partition[i][PARTITION_HORZ], - counts->partition[i][PARTITION_SPLIT] }; - assert(counts->partition[i][PARTITION_NONE] == 0); - assert(counts->partition[i][PARTITION_VERT] == 0); - assert(fc->partition_prob[i][PARTITION_NONE] == 0); - assert(fc->partition_prob[i][PARTITION_VERT] == 0); - av1_cond_prob_diff_update(header_bc, &fc->partition_prob[i][PARTITION_HORZ], - ct, probwt); - } #endif -#if CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP - for (i = 0; i < INTRA_FILTERS + 1; ++i) - prob_diff_update(av1_intra_filter_tree, fc->intra_filter_probs[i], - counts->intra_filter[i], INTRA_FILTERS, probwt, header_bc); -#endif // CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP -#endif // !CONFIG_EC_ADAPT if (frame_is_intra_only(cm)) { - av1_copy(cm->kf_y_prob, av1_kf_y_mode_prob); av1_copy(cm->fc->kf_y_cdf, av1_kf_y_mode_cdf); -#if !CONFIG_EC_ADAPT - for (i = 0; i < INTRA_MODES; ++i) - for (j = 0; j < INTRA_MODES; ++j) - prob_diff_update(av1_intra_mode_tree, cm->kf_y_prob[i][j], - counts->kf_y_mode[i][j], INTRA_MODES, probwt, - header_bc); -#endif // CONFIG_EC_ADAPT #if CONFIG_INTRABC if (cm->allow_screen_content_tools) { av1_cond_prob_diff_update(header_bc, &fc->intrabc_prob, @@ -4725,56 +4627,54 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { } #endif } else { +#if !CONFIG_NEW_MULTISYMBOL update_inter_mode_probs(cm, header_bc, counts); +#endif #if CONFIG_EXT_INTER - update_inter_compound_mode_probs(cm, probwt, header_bc); #if CONFIG_INTERINTRA if (cm->reference_mode != COMPOUND_REFERENCE && cm->allow_interintra_compound) { +#if !CONFIG_NEW_MULTISYMBOL for (i = 0; i < BLOCK_SIZE_GROUPS; i++) { if (is_interintra_allowed_bsize_group(i)) { av1_cond_prob_diff_update(header_bc, &fc->interintra_prob[i], cm->counts.interintra[i], probwt); } } - for (i = 0; i < BLOCK_SIZE_GROUPS; i++) { - prob_diff_update( - av1_interintra_mode_tree, cm->fc->interintra_mode_prob[i], - counts->interintra_mode[i], INTERINTRA_MODES, probwt, header_bc); - } -#if CONFIG_WEDGE - for (i = 0; i < BLOCK_SIZES; i++) { +#endif +#if CONFIG_WEDGE && !CONFIG_NEW_MULTISYMBOL +#if CONFIG_EXT_PARTITION_TYPES + int block_sizes_to_update = BLOCK_SIZES_ALL; +#else + int block_sizes_to_update = BLOCK_SIZES; +#endif + for (i = 0; i < block_sizes_to_update; i++) { if (is_interintra_allowed_bsize(i) && is_interintra_wedge_used(i)) av1_cond_prob_diff_update(header_bc, &fc->wedge_interintra_prob[i], cm->counts.wedge_interintra[i], probwt); } -#endif // CONFIG_WEDGE +#endif // CONFIG_WEDGE && CONFIG_NEW_MULTISYMBOL } #endif // CONFIG_INTERINTRA -#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE - if (cm->reference_mode != SINGLE_REFERENCE && cm->allow_masked_compound) { - for (i = 0; i < BLOCK_SIZES; i++) - prob_diff_update(av1_compound_type_tree, fc->compound_type_prob[i], - cm->counts.compound_interinter[i], COMPOUND_TYPES, - probwt, header_bc); - } -#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE #endif // CONFIG_EXT_INTER #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION - for (i = BLOCK_8X8; i < BLOCK_SIZES; ++i) - prob_diff_update(av1_motion_mode_tree, fc->motion_mode_prob[i], - counts->motion_mode[i], MOTION_MODES, probwt, header_bc); -#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION -#if !CONFIG_EC_ADAPT - if (cm->interp_filter == SWITCHABLE) - update_switchable_interp_probs(cm, header_bc, counts); +#if CONFIG_NCOBMC_ADAPT_WEIGHT + for (i = ADAPT_OVERLAP_BLOCK_8X8; i < ADAPT_OVERLAP_BLOCKS; ++i) { + prob_diff_update(av1_ncobmc_mode_tree, fc->ncobmc_mode_prob[i], + counts->ncobmc_mode[i], MAX_NCOBMC_MODES, probwt, + header_bc); + } #endif +#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION +#if !CONFIG_NEW_MULTISYMBOL for (i = 0; i < INTRA_INTER_CONTEXTS; i++) av1_cond_prob_diff_update(header_bc, &fc->intra_inter_prob[i], counts->intra_inter[i], probwt); +#endif +#if !CONFIG_NEW_MULTISYMBOL if (cpi->allow_comp_inter_inter) { const int use_hybrid_pred = cm->reference_mode == REFERENCE_MODE_SELECT; if (use_hybrid_pred) @@ -4791,7 +4691,19 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { } } } + if (cm->reference_mode != SINGLE_REFERENCE) { +#if CONFIG_EXT_COMP_REFS + for (i = 0; i < COMP_REF_TYPE_CONTEXTS; i++) + av1_cond_prob_diff_update(header_bc, &fc->comp_ref_type_prob[i], + counts->comp_ref_type[i], probwt); + + for (i = 0; i < UNI_COMP_REF_CONTEXTS; i++) + for (j = 0; j < (UNIDIR_COMP_REFS - 1); j++) + av1_cond_prob_diff_update(header_bc, &fc->uni_comp_ref_prob[i][j], + counts->uni_comp_ref[i][j], probwt); +#endif // CONFIG_EXT_COMP_REFS + for (i = 0; i < REF_CONTEXTS; i++) { #if CONFIG_EXT_REFS for (j = 0; j < (FWD_REFS - 1); j++) { @@ -4810,17 +4722,16 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { #endif // CONFIG_EXT_REFS } } +#endif // CONFIG_NEW_MULTISYMBOL -#if !CONFIG_EC_ADAPT - for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) { - prob_diff_update(av1_intra_mode_tree, cm->fc->y_mode_prob[i], - counts->y_mode[i], INTRA_MODES, probwt, header_bc); - } -#endif +#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF + for (i = 0; i < COMP_INTER_MODE_CONTEXTS; i++) + av1_cond_prob_diff_update(header_bc, &fc->comp_inter_mode_prob[i], + counts->comp_inter_mode[i], probwt); +#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF +#if !CONFIG_NEW_MULTISYMBOL av1_write_nmv_probs(cm, cm->allow_high_precision_mv, header_bc, counts->mv); -#if !CONFIG_EC_ADAPT - update_ext_tx_probs(cm, header_bc); #endif #if CONFIG_SUPERTX if (!xd->lossless[0]) update_supertx_probs(cm, probwt, header_bc); @@ -4829,12 +4740,6 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { write_global_motion(cpi, header_bc); #endif // CONFIG_GLOBAL_MOTION } -#if !CONFIG_EC_ADAPT - av1_coef_head_cdfs(fc); - av1_coef_pareto_cdfs(fc); - for (i = 0; i < NMV_CONTEXTS; ++i) av1_set_mv_cdfs(&fc->nmvc[i]); - av1_set_mode_cdfs(cm); -#endif // !CONFIG_EC_ADAPT #if CONFIG_ANS aom_buf_ans_flush(header_bc); header_size = buf_ans_write_end(header_bc); @@ -4881,16 +4786,23 @@ static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst, const uint32_t max_tile_col_size, int *const tile_size_bytes, int *const tile_col_size_bytes) { -// Choose the tile size bytes (tsb) and tile column size bytes (tcsb) + // Choose the tile size bytes (tsb) and tile column size bytes (tcsb) + int tsb; + int tcsb; + #if CONFIG_EXT_TILE - // The top bit in the tile size field indicates tile copy mode, so we - // have 1 less bit to code the tile size - const int tsb = choose_size_bytes(max_tile_size, 1); - const int tcsb = choose_size_bytes(max_tile_col_size, 0); -#else - const int tsb = choose_size_bytes(max_tile_size, 0); - const int tcsb = 4; // This is ignored - (void)max_tile_col_size; + if (cm->large_scale_tile) { + // The top bit in the tile size field indicates tile copy mode, so we + // have 1 less bit to code the tile size + tsb = choose_size_bytes(max_tile_size, 1); + tcsb = choose_size_bytes(max_tile_col_size, 0); + } else { +#endif // CONFIG_EXT_TILE + tsb = choose_size_bytes(max_tile_size, 0); + tcsb = 4; // This is ignored + (void)max_tile_col_size; +#if CONFIG_EXT_TILE + } #endif // CONFIG_EXT_TILE assert(tsb > 0); @@ -4906,64 +4818,68 @@ static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst, uint32_t rpos = 0; #if CONFIG_EXT_TILE - int tile_row; - int tile_col; - - for (tile_col = 0; tile_col < cm->tile_cols; tile_col++) { - // All but the last column has a column header - if (tile_col < cm->tile_cols - 1) { - uint32_t tile_col_size = mem_get_le32(dst + rpos); - rpos += 4; + if (cm->large_scale_tile) { + int tile_row; + int tile_col; + + for (tile_col = 0; tile_col < cm->tile_cols; tile_col++) { + // All but the last column has a column header + if (tile_col < cm->tile_cols - 1) { + uint32_t tile_col_size = mem_get_le32(dst + rpos); + rpos += 4; + + // Adjust the tile column size by the number of bytes removed + // from the tile size fields. + tile_col_size -= (4 - tsb) * cm->tile_rows; + + mem_put_varsize(dst + wpos, tcsb, tile_col_size); + wpos += tcsb; + } - // Adjust the tile column size by the number of bytes removed - // from the tile size fields. - tile_col_size -= (4 - tsb) * cm->tile_rows; + for (tile_row = 0; tile_row < cm->tile_rows; tile_row++) { + // All, including the last row has a header + uint32_t tile_header = mem_get_le32(dst + rpos); + rpos += 4; + + // If this is a copy tile, we need to shift the MSB to the + // top bit of the new width, and there is no data to copy. + if (tile_header >> 31 != 0) { + if (tsb < 4) tile_header >>= 32 - 8 * tsb; + mem_put_varsize(dst + wpos, tsb, tile_header); + wpos += tsb; + } else { + mem_put_varsize(dst + wpos, tsb, tile_header); + wpos += tsb; - mem_put_varsize(dst + wpos, tcsb, tile_col_size); - wpos += tcsb; + memmove(dst + wpos, dst + rpos, tile_header); + rpos += tile_header; + wpos += tile_header; + } + } } + } else { +#endif // CONFIG_EXT_TILE + const int n_tiles = cm->tile_cols * cm->tile_rows; + int n; - for (tile_row = 0; tile_row < cm->tile_rows; tile_row++) { - // All, including the last row has a header - uint32_t tile_header = mem_get_le32(dst + rpos); - rpos += 4; + for (n = 0; n < n_tiles; n++) { + int tile_size; - // If this is a copy tile, we need to shift the MSB to the - // top bit of the new width, and there is no data to copy. - if (tile_header >> 31 != 0) { - if (tsb < 4) tile_header >>= 32 - 8 * tsb; - mem_put_varsize(dst + wpos, tsb, tile_header); - wpos += tsb; + if (n == n_tiles - 1) { + tile_size = data_size - rpos; } else { - mem_put_varsize(dst + wpos, tsb, tile_header); + tile_size = mem_get_le32(dst + rpos); + rpos += 4; + mem_put_varsize(dst + wpos, tsb, tile_size); wpos += tsb; - - memmove(dst + wpos, dst + rpos, tile_header); - rpos += tile_header; - wpos += tile_header; } - } - } -#else - const int n_tiles = cm->tile_cols * cm->tile_rows; - int n; - for (n = 0; n < n_tiles; n++) { - int tile_size; + memmove(dst + wpos, dst + rpos, tile_size); - if (n == n_tiles - 1) { - tile_size = data_size - rpos; - } else { - tile_size = mem_get_le32(dst + rpos); - rpos += 4; - mem_put_varsize(dst + wpos, tsb, tile_size); - wpos += tsb; + rpos += tile_size; + wpos += tile_size; } - - memmove(dst + wpos, dst + rpos, tile_size); - - rpos += tile_size; - wpos += tile_size; +#if CONFIG_EXT_TILE } #endif // CONFIG_EXT_TILE @@ -4976,14 +4892,17 @@ static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst, void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) { uint8_t *data = dst; -#if !CONFIG_TILE_GROUPS - uint32_t compressed_header_size; + uint32_t data_size; +#if CONFIG_EXT_TILE + AV1_COMMON *const cm = &cpi->common; + uint32_t compressed_header_size = 0; uint32_t uncompressed_header_size; struct aom_write_bit_buffer saved_wb; -#endif - uint32_t data_size; struct aom_write_bit_buffer wb = { data, 0 }; - + const int have_tiles = cm->tile_cols * cm->tile_rows > 1; + int tile_size_bytes; + int tile_col_size_bytes; +#endif // CONFIG_EXT_TILE unsigned int max_tile_size; unsigned int max_tile_col_size; @@ -4991,76 +4910,77 @@ void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) { bitstream_queue_reset_write(); #endif -#if !CONFIG_TILE_GROUPS - int tile_size_bytes; - int tile_col_size_bytes; - AV1_COMMON *const cm = &cpi->common; - const int have_tiles = cm->tile_cols * cm->tile_rows > 1; - - // Write the uncompressed header - write_uncompressed_header(cpi, &wb); +#if CONFIG_EXT_TILE + if (cm->large_scale_tile) { + // Write the uncompressed header + write_uncompressed_header(cpi, &wb); #if CONFIG_EXT_REFS - if (cm->show_existing_frame) { - *size = aom_wb_bytes_written(&wb); - return; - } + if (cm->show_existing_frame) { + *size = aom_wb_bytes_written(&wb); + return; + } #endif // CONFIG_EXT_REFS - // We do not know these in advance. Output placeholder bit. - saved_wb = wb; - // Write tile size magnitudes - if (have_tiles) { -// Note that the last item in the uncompressed header is the data -// describing tile configuration. -#if CONFIG_EXT_TILE - // Number of bytes in tile column size - 1 - aom_wb_write_literal(&wb, 0, 2); -#endif // CONFIG_EXT_TILE - // Number of bytes in tile size - 1 - aom_wb_write_literal(&wb, 0, 2); - } - // Size of compressed header - aom_wb_write_literal(&wb, 0, 16); + // We do not know these in advance. Output placeholder bit. + saved_wb = wb; + // Write tile size magnitudes + if (have_tiles) { + // Note that the last item in the uncompressed header is the data + // describing tile configuration. + // Number of bytes in tile column size - 1 + aom_wb_write_literal(&wb, 0, 2); + + // Number of bytes in tile size - 1 + aom_wb_write_literal(&wb, 0, 2); + } + // Size of compressed header + aom_wb_write_literal(&wb, 0, 16); - uncompressed_header_size = (uint32_t)aom_wb_bytes_written(&wb); - data += uncompressed_header_size; + uncompressed_header_size = (uint32_t)aom_wb_bytes_written(&wb); + data += uncompressed_header_size; - aom_clear_system_state(); + aom_clear_system_state(); - // Write the compressed header - compressed_header_size = write_compressed_header(cpi, data); - data += compressed_header_size; + // Write the compressed header + compressed_header_size = write_compressed_header(cpi, data); + data += compressed_header_size; - // Write the encoded tile data - data_size = write_tiles(cpi, data, &max_tile_size, &max_tile_col_size); -#else - data_size = write_tiles(cpi, &wb, &max_tile_size, &max_tile_col_size); -#endif -#if !CONFIG_TILE_GROUPS - if (have_tiles) { - data_size = - remux_tiles(cm, data, data_size, max_tile_size, max_tile_col_size, - &tile_size_bytes, &tile_col_size_bytes); + // Write the encoded tile data + data_size = write_tiles(cpi, data, &max_tile_size, &max_tile_col_size); + } else { +#endif // CONFIG_EXT_TILE + data_size = write_tiles(cpi, data, &max_tile_size, &max_tile_col_size); +#if CONFIG_EXT_TILE } +#endif // CONFIG_EXT_TILE +#if CONFIG_EXT_TILE + if (cm->large_scale_tile) { + if (have_tiles) { + data_size = + remux_tiles(cm, data, data_size, max_tile_size, max_tile_col_size, + &tile_size_bytes, &tile_col_size_bytes); + } - data += data_size; + data += data_size; - // Now fill in the gaps in the uncompressed header. - if (have_tiles) { -#if CONFIG_EXT_TILE - assert(tile_col_size_bytes >= 1 && tile_col_size_bytes <= 4); - aom_wb_write_literal(&saved_wb, tile_col_size_bytes - 1, 2); + // Now fill in the gaps in the uncompressed header. + if (have_tiles) { + assert(tile_col_size_bytes >= 1 && tile_col_size_bytes <= 4); + aom_wb_write_literal(&saved_wb, tile_col_size_bytes - 1, 2); + + assert(tile_size_bytes >= 1 && tile_size_bytes <= 4); + aom_wb_write_literal(&saved_wb, tile_size_bytes - 1, 2); + } + // TODO(jbb): Figure out what to do if compressed_header_size > 16 bits. + assert(compressed_header_size <= 0xffff); + aom_wb_write_literal(&saved_wb, compressed_header_size, 16); + } else { #endif // CONFIG_EXT_TILE - assert(tile_size_bytes >= 1 && tile_size_bytes <= 4); - aom_wb_write_literal(&saved_wb, tile_size_bytes - 1, 2); + data += data_size; +#if CONFIG_EXT_TILE } - // TODO(jbb): Figure out what to do if compressed_header_size > 16 bits. - assert(compressed_header_size <= 0xffff); - aom_wb_write_literal(&saved_wb, compressed_header_size, 16); -#else - data += data_size; -#endif +#endif // CONFIG_EXT_TILE #if CONFIG_ANS && ANS_REVERSE // Avoid aliasing the superframe index *data++ = 0; |