diff --git a/av1/common/entropy.c b/av1/common/entropy.c index dd2177a4c1d593f1cc3d6a32ccf7755b0dbc8606..ff6f0aab4d36b37818a831a484c83a9d98aad60a 100644 --- a/av1/common/entropy.c +++ b/av1/common/entropy.c @@ -1618,18 +1618,16 @@ void av1_average_tile_coef_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[], #if CONFIG_LV_MAP AVERAGE_TILE_CDFS(txb_skip_cdf) -#if CONFIG_LV_MAP_MULTI - AVERAGE_TILE_CDFS(coeff_base_cdf) -#else +#if !CONFIG_LV_MAP_MULTI AVERAGE_TILE_CDFS(nz_map_cdf) #endif AVERAGE_TILE_CDFS(eob_flag_cdf) AVERAGE_TILE_CDFS(eob_extra_cdf) AVERAGE_TILE_CDFS(dc_sign_cdf) -#if !CONFIG_LV_MAP_MULTI AVERAGE_TILE_CDFS(coeff_base_cdf) -#endif +#if !CONFIG_LV_MAP_MULTI AVERAGE_TILE_CDFS(coeff_lps_cdf) +#endif AVERAGE_TILE_CDFS(coeff_br_cdf) #if CONFIG_CTX1D AVERAGE_TILE_CDFS(eob_mode_cdf) diff --git a/av1/common/entropy.h b/av1/common/entropy.h index 33ec7436d8d099c541df036e6234fc3e8e1ba730..c3433b71ec3f964c0deafc782a0c47d75e6f79cc 100644 --- a/av1/common/entropy.h +++ b/av1/common/entropy.h @@ -99,8 +99,14 @@ extern "C" { #define LEVEL_CONTEXTS (BR_TMP_OFFSET * BR_REF_CAT) #define NUM_BASE_LEVELS 2 + +#if CONFIG_LV_MAP_MULTI +#define BR_CDF_SIZE (4) +#define COEFF_BASE_RANGE (4 * (BR_CDF_SIZE - 1)) +#else #define COEFF_BASE_RANGE (16 - NUM_BASE_LEVELS) #define BASE_RANGE_SETS 3 +#endif #define COEFF_CONTEXT_BITS 6 #define COEFF_CONTEXT_MASK ((1 << COEFF_CONTEXT_BITS) - 1) diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c index 33f351e4ffcbe157499098d6ff39d764e22b82c7..be1ec75e9a98aaa12c513d218e0fa84589a162b8 100644 --- a/av1/common/entropymode.c +++ b/av1/common/entropymode.c @@ -498,9 +498,10 @@ const aom_prob default_coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS] = { { 133, 128, 129, 144, 128, 116, 135, 128, 43, 101, 100, 128, 140, 163, 158, 173, 205, 128, 165, 171, 128, 128, 210, 163, 172, 184, 192, 176, 201, 183, 177, 190, 128, 192, 199, 144, - 192, 192, 1, 196, 192, 255, 171, 178, 255, 128, 171, 179 } } + 192, 192, 128, 196, 192, 255, 171, 178, 255, 128, 171, 179 } } }; +#if !CONFIG_LV_MAP_MULTI const aom_prob default_coeff_br[TX_SIZES][PLANE_TYPES][BASE_RANGE_SETS][LEVEL_CONTEXTS] = { { { { 62, 128, 54, 116, 128, 51, 97, 128, 59, 68, 107, 128, @@ -600,6 +601,7 @@ const aom_prob 26, 27, 128, 126, 128, 255, 63, 142, 128, 128, 1, 1, 125, 159, 128, 173, 212, 128, 85, 189, 128, 128, 255, 171 } } } }; +#endif #if CONFIG_CTX1D static const aom_prob default_eob_mode[TX_SIZES][PLANE_TYPES][TX_CLASSES] = { { { 128, 176, 157 }, { 128, 222, 198 } }, @@ -3230,7 +3232,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) { av1_copy(fc->dc_sign, default_dc_sign); av1_copy(fc->coeff_base, default_coeff_base); av1_copy(fc->coeff_lps, default_coeff_lps); +#if !CONFIG_LV_MAP_MULTI av1_copy(fc->coeff_br, default_coeff_br); +#endif #if CONFIG_CTX1D av1_copy(fc->eob_mode, default_eob_mode); av1_copy(fc->empty_line, default_empty_line); diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h index 7e86fa6ce15cd2b22db7a8952e88cbfbc787b70b..d2cb00942fcae58017059fda102e9d8bcbba8782 100644 --- a/av1/common/entropymode.h +++ b/av1/common/entropymode.h @@ -144,7 +144,9 @@ typedef struct frame_contexts { aom_prob coeff_base[TX_SIZES][PLANE_TYPES][NUM_BASE_LEVELS] [COEFF_BASE_CONTEXTS]; aom_prob coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS]; +#if !CONFIG_LV_MAP_MULTI aom_prob coeff_br[TX_SIZES][PLANE_TYPES][BASE_RANGE_SETS][LEVEL_CONTEXTS]; +#endif #if CONFIG_CTX1D aom_prob eob_mode[TX_SIZES][PLANE_TYPES][TX_CLASSES]; aom_prob empty_line[TX_SIZES][PLANE_TYPES][TX_CLASSES][EMPTY_LINE_CONTEXTS]; @@ -152,10 +154,7 @@ typedef struct frame_contexts { #endif // CONFIG_CTX1D aom_cdf_prob txb_skip_cdf[TX_SIZES][TXB_SKIP_CONTEXTS][CDF_SIZE(2)]; -#if CONFIG_LV_MAP_MULTI - aom_cdf_prob coeff_base_cdf[TX_SIZES][PLANE_TYPES][SIG_COEF_CONTEXTS] - [CDF_SIZE(4)]; -#else +#if !CONFIG_LV_MAP_MULTI aom_cdf_prob nz_map_cdf[TX_SIZES][PLANE_TYPES][SIG_COEF_CONTEXTS] [CDF_SIZE(2)]; #endif @@ -164,14 +163,19 @@ typedef struct frame_contexts { aom_cdf_prob eob_extra_cdf[TX_SIZES][PLANE_TYPES][EOB_COEF_CONTEXTS] [CDF_SIZE(2)]; aom_cdf_prob dc_sign_cdf[PLANE_TYPES][DC_SIGN_CONTEXTS][CDF_SIZE(2)]; -#if !CONFIG_LV_MAP_MULTI +#if CONFIG_LV_MAP_MULTI + aom_cdf_prob coeff_base_cdf[TX_SIZES][PLANE_TYPES][SIG_COEF_CONTEXTS] + [CDF_SIZE(4)]; + aom_cdf_prob coeff_br_cdf[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS] + [CDF_SIZE(BR_CDF_SIZE)]; +#else aom_cdf_prob coeff_base_cdf[TX_SIZES][PLANE_TYPES][NUM_BASE_LEVELS] [COEFF_BASE_CONTEXTS][CDF_SIZE(2)]; -#endif aom_cdf_prob coeff_lps_cdf[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS] [CDF_SIZE(2)]; aom_cdf_prob coeff_br_cdf[TX_SIZES][PLANE_TYPES][BASE_RANGE_SETS] [LEVEL_CONTEXTS][CDF_SIZE(2)]; +#endif #if CONFIG_CTX1D aom_cdf_prob eob_mode_cdf[TX_SIZES][PLANE_TYPES][TX_CLASSES][CDF_SIZE(2)]; aom_cdf_prob empty_line_cdf[TX_SIZES][PLANE_TYPES][TX_CLASSES] @@ -409,8 +413,10 @@ typedef struct FRAME_COUNTS { unsigned int coeff_base[TX_SIZES][PLANE_TYPES][NUM_BASE_LEVELS] [COEFF_BASE_CONTEXTS][2]; unsigned int coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS][2]; +#if !CONFIG_LV_MAP_MULTI unsigned int coeff_br[TX_SIZES][PLANE_TYPES][BASE_RANGE_SETS][LEVEL_CONTEXTS] [2]; +#endif #if CONFIG_CTX1D unsigned int eob_mode[TX_SIZES][PLANE_TYPES][TX_CLASSES][2]; unsigned int empty_line[TX_SIZES][PLANE_TYPES][TX_CLASSES] diff --git a/av1/common/txb_common.c b/av1/common/txb_common.c index 836d44dcdc9b611e3277ac58b4cf94121d3250dd..38ac984ec8b1be57a91ad1a95bf9e58ccb23669c 100644 --- a/av1/common/txb_common.c +++ b/av1/common/txb_common.c @@ -119,7 +119,22 @@ void av1_init_txb_probs(FRAME_CONTEXT *fc) { } } -#if !CONFIG_LV_MAP_MULTI +#if CONFIG_LV_MAP_MULTI + for (tx_size = 0; tx_size < TX_SIZES; ++tx_size) { + for (plane = 0; plane < PLANE_TYPES; ++plane) { + for (ctx = 0; ctx < COEFF_BASE_CONTEXTS; ++ctx) { + int p = fc->nz_map[tx_size][plane][ctx] * 128; + fc->coeff_base_cdf[tx_size][plane][ctx][0] = AOM_ICDF(p); + p += ((32768 - p) * fc->coeff_base[tx_size][plane][0][ctx]) >> 8; + fc->coeff_base_cdf[tx_size][plane][ctx][1] = AOM_ICDF(p); + p += ((32768 - p) * fc->coeff_base[tx_size][plane][1][ctx]) >> 8; + fc->coeff_base_cdf[tx_size][plane][ctx][2] = AOM_ICDF(p); + fc->coeff_base_cdf[tx_size][plane][ctx][3] = AOM_ICDF(32768); + fc->coeff_base_cdf[tx_size][plane][ctx][4] = 0; + } + } + } +#else // Update probability models for non-zero coefficient map and eob flag. for (tx_size = 0; tx_size < TX_SIZES; ++tx_size) { for (plane = 0; plane < PLANE_TYPES; ++plane) { @@ -138,16 +153,7 @@ void av1_init_txb_probs(FRAME_CONTEXT *fc) { for (tx_size = 0; tx_size < TX_SIZES; ++tx_size) { for (plane = 0; plane < PLANE_TYPES; ++plane) { for (ctx = 0; ctx < SIG_COEF_CONTEXTS; ++ctx) { -#if CONFIG_LV_MAP_MULTI - int p = fc->nz_map[tx_size][plane][ctx] * 128; - fc->coeff_base_cdf[tx_size][plane][ctx][0] = AOM_ICDF(p); - p += ((32768 - p) * fc->coeff_base[tx_size][plane][0][ctx]) >> 8; - fc->coeff_base_cdf[tx_size][plane][ctx][1] = AOM_ICDF(p); - p += ((32768 - p) * fc->coeff_base[tx_size][plane][1][ctx]) >> 8; - fc->coeff_base_cdf[tx_size][plane][ctx][2] = AOM_ICDF(p); - fc->coeff_base_cdf[tx_size][plane][ctx][3] = AOM_ICDF(32768); - fc->coeff_base_cdf[tx_size][plane][ctx][4] = 0; -#else +#if !CONFIG_LV_MAP_MULTI fc->nz_map_cdf[tx_size][plane][ctx][0] = AOM_ICDF(128 * (aom_cdf_prob)fc->nz_map[tx_size][plane][ctx]); fc->nz_map_cdf[tx_size][plane][ctx][1] = AOM_ICDF(32768); @@ -172,6 +178,23 @@ void av1_init_txb_probs(FRAME_CONTEXT *fc) { for (tx_size = 0; tx_size < TX_SIZES; ++tx_size) { for (plane = 0; plane < PLANE_TYPES; ++plane) { +#if CONFIG_LV_MAP_MULTI + for (ctx = 0; ctx < LEVEL_CONTEXTS; ++ctx) { + int p = 32768 - fc->coeff_lps[tx_size][plane][ctx] * 128; + int sum = p; + fc->coeff_br_cdf[tx_size][plane][ctx][0] = AOM_ICDF(sum); + sum += ((32768 - sum) * p) >> 15; + fc->coeff_br_cdf[tx_size][plane][ctx][1] = AOM_ICDF(sum); + sum += ((32768 - sum) * p) >> 15; + fc->coeff_br_cdf[tx_size][plane][ctx][2] = AOM_ICDF(sum); + fc->coeff_br_cdf[tx_size][plane][ctx][3] = AOM_ICDF(32768); + fc->coeff_br_cdf[tx_size][plane][ctx][4] = AOM_ICDF(32768); + // printf("br_cdf: %d %d %2d : %3d %3d %3d\n", tx_size, plane, ctx, + // fc->coeff_br_cdf[tx_size][plane][ctx][0] >> 7, + // fc->coeff_br_cdf[tx_size][plane][ctx][1] >> 7, + // fc->coeff_br_cdf[tx_size][plane][ctx][2] >> 7); + } +#else for (ctx = 0; ctx < LEVEL_CONTEXTS; ++ctx) { fc->coeff_lps_cdf[tx_size][plane][ctx][0] = AOM_ICDF(128 * (aom_cdf_prob)fc->coeff_lps[tx_size][plane][ctx]); @@ -187,6 +210,7 @@ void av1_init_txb_probs(FRAME_CONTEXT *fc) { fc->coeff_br_cdf[tx_size][plane][br][ctx][2] = 0; } } +#endif } } #if CONFIG_CTX1D diff --git a/av1/common/txb_common.h b/av1/common/txb_common.h index 2043be6c7663fd5556ba8414f717e84326b98439..c609f29e0b4abe94086f7f931420d8ab9b7b1678 100644 --- a/av1/common/txb_common.h +++ b/av1/common/txb_common.h @@ -209,6 +209,7 @@ static const int br_level_map[9] = { 0, 0, 1, 1, 2, 2, 3, 3, 3, }; +#if !CONFIG_LV_MAP_MULTI static const int coeff_to_br_index[COEFF_BASE_RANGE] = { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, }; @@ -220,6 +221,7 @@ static const int br_index_to_coeff[BASE_RANGE_SETS] = { static const int br_extra_bits[BASE_RANGE_SETS] = { 1, 2, 3, }; +#endif #define BR_MAG_OFFSET 1 // TODO(angiebird): optimize this function by using a table to map from diff --git a/av1/decoder/decodetxb.c b/av1/decoder/decodetxb.c index a89e39ca175dc154f6d1d1cbf656e89e1683caa7..edcb0aa349625ab7333d969e7766601cded2bb5e 100644 --- a/av1/decoder/decodetxb.c +++ b/av1/decoder/decodetxb.c @@ -286,6 +286,19 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd, ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]]); +#if CONFIG_LV_MAP_MULTI + for (idx = 0; idx < COEFF_BASE_RANGE / (BR_CDF_SIZE - 1); ++idx) { + int k = av1_read_record_symbol4( + counts, r, ec_ctx->coeff_br_cdf[txs_ctx][plane_type][ctx], + BR_CDF_SIZE, ACCT_STR); + *level += k; + if (k < BR_CDF_SIZE - 1) break; + } + if (*level <= NUM_BASE_LEVELS + COEFF_BASE_RANGE) { + cul_level += *level; + continue; + } +#else for (idx = 0; idx < BASE_RANGE_SETS; ++idx) { // printf("br: %d %d %d %d\n", txs_ctx, plane_type, idx, ctx); if (av1_read_record_bin( @@ -318,7 +331,7 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd, } if (idx < BASE_RANGE_SETS) continue; - +#endif // decode 0-th order Golomb code *level = COEFF_BASE_RANGE + 1 + NUM_BASE_LEVELS; // Save golomb in tcoeffs because adding it to level may incur overflow diff --git a/av1/encoder/block.h b/av1/encoder/block.h index 9c902995c71e8ef205aa271de01a85f85eb7b960..24987f8f65be633c619f643e6b9a565b69c5d2dc 100644 --- a/av1/encoder/block.h +++ b/av1/encoder/block.h @@ -75,7 +75,9 @@ typedef struct { int base_cost[NUM_BASE_LEVELS][COEFF_BASE_CONTEXTS][2]; #endif int lps_cost[LEVEL_CONTEXTS][COEFF_BASE_RANGE + 1]; +#if !CONFIG_LV_MAP_MULTI int br_cost[BASE_RANGE_SETS][LEVEL_CONTEXTS][2]; +#endif #if CONFIG_CTX1D int eob_mode_cost[TX_CLASSES][2]; int empty_line_cost[TX_CLASSES][EMPTY_LINE_CONTEXTS][2]; diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c index 37df7b2604906d53c88137f49dc352acd101717e..e2cce4a15d0863dab6668c785c3a20424bae1ff1 100644 --- a/av1/encoder/encodetxb.c +++ b/av1/encoder/encodetxb.c @@ -469,6 +469,15 @@ void av1_write_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd, ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]]); int base_range = level - 1 - NUM_BASE_LEVELS; +#if CONFIG_LV_MAP_MULTI + for (idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) { + int k = AOMMIN(base_range - idx, BR_CDF_SIZE - 1); + aom_write_cdf4(w, k, ec_ctx->coeff_br_cdf[txs_ctx][plane_type][ctx], + BR_CDF_SIZE); + if (k < BR_CDF_SIZE - 1) break; + } + if (base_range < COEFF_BASE_RANGE) continue; +#else int br_set_idx = 0; int br_base = 0; int br_offset = 0; @@ -501,7 +510,7 @@ void av1_write_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd, } if (br_set_idx < BASE_RANGE_SETS) continue; - +#endif // use 0-th order Golomb code to handle the residual level. write_golomb( w, abs(tcoeff[scan[c]]) - COEFF_BASE_RANGE - 1 - NUM_BASE_LEVELS); @@ -2271,6 +2280,16 @@ void av1_update_and_record_txb_context(int plane, int block, int blk_row, ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]]); int base_range = level - 1 - NUM_BASE_LEVELS; +#if CONFIG_LV_MAP_MULTI + for (idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) { + int k = AOMMIN(base_range - idx, BR_CDF_SIZE - 1); + // printf("br_update: %d %d %2d : %2d %d\n", txsize_ctx, plane, ctx, + // base_range, k); + update_cdf(ec_ctx->coeff_br_cdf[txsize_ctx][plane_type][ctx], k, + BR_CDF_SIZE); + if (k < BR_CDF_SIZE - 1) break; + } +#else int br_set_idx = base_range < COEFF_BASE_RANGE ? coeff_to_br_index[base_range] : BASE_RANGE_SETS; @@ -2304,6 +2323,7 @@ void av1_update_and_record_txb_context(int plane, int block, int blk_row, update_bin(ec_ctx->coeff_br_cdf[txsize_ctx][plane_type][idx][ctx], 0, 2); } +#endif // use 0-th order Golomb code to handle the residual level. } } diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c index 4b4de0dc394d2eec68beb70e8d108ec1c0a6480e..4173020435eb69856a45d97f9784dadfb1ce6c24 100644 --- a/av1/encoder/rd.c +++ b/av1/encoder/rd.c @@ -569,14 +569,36 @@ void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc) { av1_cost_tokens_from_cdf( pcost->base_cost[layer][ctx], fc->coeff_base_cdf[tx_size][plane][layer][ctx], NULL); -#endif for (int br = 0; br < BASE_RANGE_SETS; ++br) for (int ctx = 0; ctx < LEVEL_CONTEXTS; ++ctx) av1_cost_tokens_from_cdf(pcost->br_cost[br][ctx], fc->coeff_br_cdf[tx_size][plane][br][ctx], NULL); +#endif for (int ctx = 0; ctx < LEVEL_CONTEXTS; ++ctx) { +#if CONFIG_LV_MAP_MULTI + int br_rate[BR_CDF_SIZE]; + int prev_cost = 0; + int i, j; + av1_cost_tokens_from_cdf(br_rate, fc->coeff_br_cdf[tx_size][plane][ctx], + NULL); + // printf("br_rate: "); + // for(j = 0; j < BR_CDF_SIZE; j++) + // printf("%4d ", br_rate[j]); + // printf("\n"); + for (i = 0; i < COEFF_BASE_RANGE; i += BR_CDF_SIZE - 1) { + for (j = 0; j < BR_CDF_SIZE - 1; j++) { + pcost->lps_cost[ctx][i + j] = prev_cost + br_rate[j]; + } + prev_cost += br_rate[j]; + } + pcost->lps_cost[ctx][i] = prev_cost; +// printf("lps_cost: %d %d %2d : ", tx_size, plane, ctx); +// for (i = 0; i <= COEFF_BASE_RANGE; i++) +// printf("%5d ", pcost->lps_cost[ctx][i]); +// printf("\n"); +#else int lps_rate[2]; av1_cost_tokens_from_cdf(lps_rate, fc->coeff_lps_cdf[tx_size][plane][ctx], NULL); @@ -611,6 +633,7 @@ void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc) { } // load the base range cost } +#endif } #if CONFIG_CTX1D for (int tx_class = 0; tx_class < TX_CLASSES; ++tx_class)