diff --git a/configure b/configure old mode 100755 new mode 100644 index 8c3716e7ab5a4b280e072eb1adc8d515b26b0631..a394fff7e6aa0cc1a74dd7b073dfca12d34e767b --- a/configure +++ b/configure @@ -230,6 +230,7 @@ EXPERIMENT_LIST=" expanded_coef_context int_8x8fdct newintramodes + adaptive_entropy " CONFIG_LIST=" external_build diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c index 8bab3452ff43adb276a8e2237eb47ee5ad4112b8..2830c3e15d946d79145e72a4a28132a0d17aa464 100644 --- a/vp8/common/alloccommon.c +++ b/vp8/common/alloccommon.c @@ -15,6 +15,7 @@ #include "onyxc_int.h" #include "findnearmv.h" #include "entropymode.h" +#include "entropymv.h" #include "systemdependent.h" @@ -239,6 +240,8 @@ void vp8_initialize_common() vp8_entropy_mode_init(); + vp8_entropy_mv_init(); + vp8_init_scan_order_mask(); } diff --git a/vp8/common/default_coef_probs.h b/vp8/common/default_coef_probs.h old mode 100755 new mode 100644 diff --git a/vp8/common/entropy.c b/vp8/common/entropy.c index 9849fd4c297a3f0cb7c6b815aa73bd405bcdd8ee..0b0a2357fe85ce3c82c6cd325d315b02ec7c2e92 100644 --- a/vp8/common/entropy.c +++ b/vp8/common/entropy.c @@ -15,6 +15,7 @@ #include "string.h" #include "blockd.h" #include "onyxc_int.h" +#include "entropymode.h" #include "vpx_mem/vpx_mem.h" #define uchar unsigned char /* typedefs can clash */ @@ -192,3 +193,139 @@ void vp8_coef_tree_initialize() init_bit_trees(); vp8_tokens_from_tree(vp8_coef_encodings, vp8_coef_tree); } + +#if CONFIG_ADAPTIVE_ENTROPY + +//#define COEF_COUNT_TESTING + +#define COEF_COUNT_SAT 24 +#define COEF_MAX_UPDATE_FACTOR 112 +#define COEF_COUNT_SAT_KEY 24 +#define COEF_MAX_UPDATE_FACTOR_KEY 112 +#define COEF_COUNT_SAT_AFTER_KEY 24 +#define COEF_MAX_UPDATE_FACTOR_AFTER_KEY 128 + +void vp8_adapt_coef_probs(VP8_COMMON *cm) +{ + int t, i, j, k, count; + unsigned int branch_ct[ENTROPY_NODES][2]; + vp8_prob coef_probs[ENTROPY_NODES]; + int update_factor; /* denominator 256 */ + int factor; + int count_sat; + + //printf("Frame type: %d\n", cm->frame_type); + if (cm->frame_type == KEY_FRAME) + { + update_factor = COEF_MAX_UPDATE_FACTOR_KEY; + count_sat = COEF_COUNT_SAT_KEY; + } + else if (cm->last_frame_type == KEY_FRAME) + { + update_factor = COEF_MAX_UPDATE_FACTOR_AFTER_KEY; /* adapt quickly */ + count_sat = COEF_COUNT_SAT_AFTER_KEY; + } + else + { + update_factor = COEF_MAX_UPDATE_FACTOR; + count_sat = COEF_COUNT_SAT; + } + +#ifdef COEF_COUNT_TESTING + { + printf("static const unsigned int\ncoef_counts" + "[BLOCK_TYPES] [COEF_BANDS]" + "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {\n"); + for (i = 0; i<BLOCK_TYPES; ++i) + { + printf(" {\n"); + for (j = 0; j<COEF_BANDS; ++j) + { + printf(" {\n"); + for (k = 0; k<PREV_COEF_CONTEXTS; ++k) + { + printf(" {"); + for (t = 0; t<MAX_ENTROPY_TOKENS; ++t) printf("%d, ", cm->fc.coef_counts[i][j][k][t]); + printf("},\n"); + } + printf(" },\n"); + } + printf(" },\n"); + } + printf("};\n"); + printf("static const unsigned int\ncoef_counts_8x8" + "[BLOCK_TYPES_8X8] [COEF_BANDS]" + "[PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {\n"); + for (i = 0; i<BLOCK_TYPES_8X8; ++i) + { + printf(" {\n"); + for (j = 0; j<COEF_BANDS; ++j) + { + printf(" {\n"); + for (k = 0; k<PREV_COEF_CONTEXTS; ++k) + { + printf(" {"); + for (t = 0; t<MAX_ENTROPY_TOKENS; ++t) printf("%d, ", cm->fc.coef_counts_8x8[i][j][k][t]); + printf("},\n"); + } + printf(" },\n"); + } + printf(" },\n"); + } + printf("};\n"); + } +#endif + + for (i = 0; i<BLOCK_TYPES; ++i) + for (j = 0; j<COEF_BANDS; ++j) + for (k = 0; k<PREV_COEF_CONTEXTS; ++k) + { +#if CONFIG_EXPANDED_COEF_CONTEXT + if (k >=3 && ((i == 0 && j == 1) || (i > 0 && j == 0))) + continue; +#endif + vp8_tree_probs_from_distribution( + MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree, + coef_probs, branch_ct, cm->fc.coef_counts [i][j][k], + 256, 1); + for (t=0; t<ENTROPY_NODES; ++t) + { + int prob; + count = branch_ct[t][0] + branch_ct[t][1]; + count = count > count_sat ? count_sat : count; + factor = (update_factor * count / count_sat); + prob = ((int)cm->fc.pre_coef_probs[i][j][k][t] * (256-factor) + + (int)coef_probs[t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.coef_probs[i][j][k][t] = 1; + else if (prob > 255) cm->fc.coef_probs[i][j][k][t] = 255; + else cm->fc.coef_probs[i][j][k][t] = prob; + } + } + + for (i = 0; i<BLOCK_TYPES_8X8; ++i) + for (j = 0; j<COEF_BANDS; ++j) + for (k = 0; k<PREV_COEF_CONTEXTS; ++k) + { +#if CONFIG_EXPANDED_COEF_CONTEXT + if (k >=3 && ((i == 0 && j == 1) || (i > 0 && j == 0))) + continue; +#endif + vp8_tree_probs_from_distribution( + MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree, + coef_probs, branch_ct, cm->fc.coef_counts_8x8 [i][j][k], + 256, 1); + for (t=0; t<ENTROPY_NODES; ++t) + { + int prob; + count = branch_ct[t][0] + branch_ct[t][1]; + count = count > count_sat ? count_sat : count; + factor = (update_factor * count / count_sat); + prob = ((int)cm->fc.pre_coef_probs_8x8[i][j][k][t] * (256-factor) + + (int)coef_probs[t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.coef_probs_8x8[i][j][k][t] = 1; + else if (prob > 255) cm->fc.coef_probs_8x8[i][j][k][t] = 255; + else cm->fc.coef_probs_8x8[i][j][k][t] = prob; + } + } +} +#endif diff --git a/vp8/common/entropy.h b/vp8/common/entropy.h index 692c2c4184cf48c909821cc05c931315d9c3c05d..78f8d5d03478b10531785bd6761e7dc2502bf28d 100644 --- a/vp8/common/entropy.h +++ b/vp8/common/entropy.h @@ -92,9 +92,9 @@ extern DECLARE_ALIGNED(64, const unsigned char, vp8_coef_bands_8x8[64]); #endif #if CONFIG_NEWUPDATE -#define SUBEXP_PARAM 2 /* Subexponential code parameter */ -#define MODULUS_PARAM 21 /* Modulus parameter */ -#define COEFUPDATETYPE 2 /* coef update type to use (1/2/3) */ +#define SUBEXP_PARAM 4 /* Subexponential code parameter */ +#define MODULUS_PARAM 13 /* Modulus parameter */ +#define COEFUPDATETYPE 1 /* coef update type to use (1/2/3) */ #endif @@ -107,4 +107,8 @@ extern short vp8_default_zig_zag_mask[16]; extern DECLARE_ALIGNED(64, const int, vp8_default_zig_zag1d_8x8[64]); extern short vp8_default_zig_zag_mask_8x8[64];//int64_t void vp8_coef_tree_initialize(void); + +#if CONFIG_ADAPTIVE_ENTROPY +void vp8_adapt_coef_probs(struct VP8Common *); +#endif #endif diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c index 0ae6a934326941d717233c4134560e361d577e0c..a1a3cfa887d3d8f5fb2ece13b9ce6aaa80eef531 100644 --- a/vp8/common/entropymode.c +++ b/vp8/common/entropymode.c @@ -11,6 +11,7 @@ #include "modecont.h" #include "entropymode.h" +#include "entropymv.h" #include "entropy.h" #include "vpx_mem/vpx_mem.h" @@ -325,40 +326,6 @@ struct vp8_token_struct vp8_mbsplit_encodings [VP8_NUMMBSPLITS]; struct vp8_token_struct vp8_mv_ref_encoding_array [VP8_MVREFS]; struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS]; -#if CONFIG_HIGH_PRECISION_MV -const vp8_tree_index vp8_small_mvtree_hp [30] = -{ - 2, 16, - 4, 10, - 6, 8, - -0, -1, - -2, -3, - 12, 14, - -4, -5, - -6, -7, - 18, 24, - 20, 22, - -8, -9, - -10, -11, - 26, 28, - -12, -13, - -14, -15 -}; -struct vp8_token_struct vp8_small_mvencodings_hp [16]; -#endif /* CONFIG_HIGH_PRECISION_MV */ - -const vp8_tree_index vp8_small_mvtree [14] = -{ - 2, 8, - 4, 6, - -0, -1, - -2, -3, - 10, 12, - -4, -5, - -6, -7 -}; -struct vp8_token_struct vp8_small_mvencodings [8]; - void vp8_init_mbmode_probs(VP8_COMMON *x) @@ -396,7 +363,7 @@ void vp8_init_mbmode_probs(VP8_COMMON *x) vp8_tree_probs_from_distribution( VP8_I8X8_MODES, vp8_i8x8_mode_encodings, vp8_i8x8_mode_tree, - x->i8x8_mode_prob, bct, i8x8_mode_cts, + x->fc.i8x8_mode_prob, bct, i8x8_mode_cts, 256, 1); vpx_memcpy(x->fc.sub_mv_ref_prob, sub_mv_ref_prob, sizeof(sub_mv_ref_prob)); @@ -458,11 +425,6 @@ void vp8_entropy_mode_init() vp8_mv_ref_tree, NEARESTMV); vp8_tokens_from_tree_offset(vp8_sub_mv_ref_encoding_array, vp8_sub_mv_ref_tree, LEFT4X4); - - vp8_tokens_from_tree(vp8_small_mvencodings, vp8_small_mvtree); -#if CONFIG_HIGH_PRECISION_MV - vp8_tokens_from_tree(vp8_small_mvencodings_hp, vp8_small_mvtree_hp); -#endif } void vp8_init_mode_contexts(VP8_COMMON *pc) @@ -595,3 +557,110 @@ void print_mv_ref_cts(VP8_COMMON *pc) printf("\n"); } } + +#if CONFIG_ADAPTIVE_ENTROPY +//#define MODE_COUNT_TESTING +#define MODE_COUNT_SAT 16 +#define MODE_MAX_UPDATE_FACTOR 96 +void vp8_adapt_mode_probs(VP8_COMMON *cm) +{ + int i, t, count, factor; + unsigned int branch_ct[32][2]; + int update_factor = MODE_MAX_UPDATE_FACTOR; /* denominator 256 */ + int count_sat = MODE_COUNT_SAT; + vp8_prob ymode_probs[VP8_YMODES-1]; + vp8_prob uvmode_probs[VP8_UV_MODES-1]; + vp8_prob bmode_probs[VP8_BINTRAMODES-1]; + vp8_prob i8x8_mode_probs[VP8_I8X8_MODES-1]; +#ifdef MODE_COUNT_TESTING + printf("static const unsigned int\nymode_counts" + "[VP8_YMODES] = {\n"); + for (t = 0; t<VP8_YMODES; ++t) printf("%d, ", cm->fc.ymode_counts[t]); + printf("};\n"); + printf("static const unsigned int\nuv_mode_counts" + "[VP8_YMODES] [VP8_UV_MODES] = {\n"); + for (i = 0; i < VP8_YMODES; ++i) + { + printf(" {"); + for (t = 0; t < VP8_UV_MODES; ++t) printf("%d, ", cm->fc.uv_mode_counts[i][t]); + printf("},\n"); + } + printf("};\n"); + printf("static const unsigned int\nbmode_counts" + "[VP8_BINTRAMODES] = {\n"); + for (t = 0; t<VP8_BINTRAMODES; ++t) printf("%d, ", cm->fc.bmode_counts[t]); + printf("};\n"); + printf("static const unsigned int\ni8x8_mode_counts" + "[VP8_I8X8_MODES] = {\n"); + for (t = 0; t<VP8_I8X8_MODES; ++t) printf("%d, ", cm->fc.i8x8_mode_counts[t]); + printf("};\n"); +#endif + vp8_tree_probs_from_distribution( + VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree, + ymode_probs, branch_ct, cm->fc.ymode_counts, + 256, 1); + for (t=0; t<VP8_YMODES-1; ++t) + { + int prob; + count = branch_ct[t][0] + branch_ct[t][1]; + count = count > count_sat ? count_sat : count; + factor = (update_factor * count / count_sat); + prob = ((int)cm->fc.pre_ymode_prob[t] * (256-factor) + + (int)ymode_probs[t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.ymode_prob[t] = 1; + else if (prob > 255) cm->fc.ymode_prob[t] = 255; + else cm->fc.ymode_prob[t] = prob; + } + for (i = 0; i < VP8_YMODES; ++i) + { + vp8_tree_probs_from_distribution( + VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, + uvmode_probs, branch_ct, cm->fc.uv_mode_counts[i], + 256, 1); + for (t = 0; t < VP8_UV_MODES-1; ++t) + { + int prob; + count = branch_ct[t][0] + branch_ct[t][1]; + count = count > count_sat ? count_sat : count; + factor = (update_factor * count / count_sat); + prob = ((int)cm->fc.pre_uv_mode_prob[i][t] * (256-factor) + + (int)uvmode_probs[t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.uv_mode_prob[i][t] = 1; + else if (prob > 255) cm->fc.uv_mode_prob[i][t] = 255; + else cm->fc.uv_mode_prob[i][t] = prob; + } + } + vp8_tree_probs_from_distribution( + VP8_BINTRAMODES, vp8_bmode_encodings, vp8_bmode_tree, + bmode_probs, branch_ct, cm->fc.bmode_counts, + 256, 1); + for (t=0; t<VP8_BINTRAMODES-1; ++t) + { + int prob; + count = branch_ct[t][0] + branch_ct[t][1]; + count = count > count_sat ? count_sat : count; + factor = (update_factor * count / count_sat); + prob = ((int)cm->fc.pre_bmode_prob[t] * (256-factor) + + (int)bmode_probs[t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.bmode_prob[t] = 1; + else if (prob > 255) cm->fc.bmode_prob[t] = 255; + else cm->fc.bmode_prob[t] = prob; + } + vp8_tree_probs_from_distribution( + VP8_I8X8_MODES, vp8_i8x8_mode_encodings, vp8_i8x8_mode_tree, + i8x8_mode_probs, branch_ct, cm->fc.i8x8_mode_counts, + 256, 1); + for (t=0; t<VP8_I8X8_MODES-1; ++t) + { + int prob; + count = branch_ct[t][0] + branch_ct[t][1]; + count = count > count_sat ? count_sat : count; + factor = (update_factor * count / count_sat); + prob = ((int)cm->fc.pre_i8x8_mode_prob[t] * (256-factor) + + (int)i8x8_mode_probs[t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.i8x8_mode_prob[t] = 1; + else if (prob > 255) cm->fc.i8x8_mode_prob[t] = 255; + else cm->fc.i8x8_mode_prob[t] = prob; + } +} +#endif diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h index 09d5c7704253c61a2c59d9993eb5f54cf75db3b3..cfd53273602b97bf21f804c2117a907443f92510 100644 --- a/vp8/common/entropymode.h +++ b/vp8/common/entropymode.h @@ -55,13 +55,6 @@ extern struct vp8_token_struct vp8_mbsplit_encodings [VP8_NUMMBSPLITS]; extern struct vp8_token_struct vp8_mv_ref_encoding_array [VP8_MVREFS]; extern struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS]; -extern const vp8_tree_index vp8_small_mvtree[]; -extern struct vp8_token_struct vp8_small_mvencodings [8]; -#if CONFIG_HIGH_PRECISION_MV -extern const vp8_tree_index vp8_small_mvtree_hp[]; -extern struct vp8_token_struct vp8_small_mvencodings_hp [16]; -#endif - void vp8_entropy_mode_init(void); void vp8_init_mbmode_probs(VP8_COMMON *x); @@ -71,7 +64,10 @@ extern void vp8_accum_mv_refs(VP8_COMMON *pc, MB_PREDICTION_MODE m, const int ct[4]); -void vp8_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES-1]); +void vp8_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES-1]); void vp8_kf_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1]); +#if CONFIG_ADAPTIVE_ENTROPY +void vp8_adapt_mode_probs(struct VP8Common *); +#endif #endif diff --git a/vp8/common/entropymv.c b/vp8/common/entropymv.c index 90195f7bccdeb2c2de6413f5c10aa587ccca23f6..2c27b0913e4ae4f679cf72525f34384872df024d 100644 --- a/vp8/common/entropymv.c +++ b/vp8/common/entropymv.c @@ -9,6 +9,7 @@ */ +#include "onyxc_int.h" #include "entropymv.h" #if CONFIG_HIGH_PRECISION_MV @@ -78,3 +79,361 @@ const MV_CONTEXT vp8_default_mv_context[2] = 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 /* long bits */ }} }; + +#if CONFIG_HIGH_PRECISION_MV +const vp8_tree_index vp8_small_mvtree_hp [30] = +{ + 2, 16, + 4, 10, + 6, 8, + -0, -1, + -2, -3, + 12, 14, + -4, -5, + -6, -7, + 18, 24, + 20, 22, + -8, -9, + -10, -11, + 26, 28, + -12, -13, + -14, -15 +}; +struct vp8_token_struct vp8_small_mvencodings_hp [16]; +#endif /* CONFIG_HIGH_PRECISION_MV */ + +const vp8_tree_index vp8_small_mvtree [14] = +{ + 2, 8, + 4, 6, + -0, -1, + -2, -3, + 10, 12, + -4, -5, + -6, -7 +}; +struct vp8_token_struct vp8_small_mvencodings [8]; + + +__inline static void calc_prob(vp8_prob *p, const unsigned int ct[2], int pbits) +{ + const unsigned int tot = ct[0] + ct[1]; + if (tot) + { + const vp8_prob x = ((ct[0] * 255) / tot) & -(1<<(8-pbits)); + *p = x ? x : 1; + } +} + +static void compute_component_probs( + const unsigned int events [MVvals], + vp8_prob Pnew [MVPcount], + unsigned int is_short_ct[2], + unsigned int sign_ct[2], + unsigned int bit_ct [mvlong_width] [2], + unsigned int short_ct [mvnum_short], + unsigned int short_bct [mvnum_short-1] [2] +) +{ + is_short_ct[0] = is_short_ct[1] = 0; + sign_ct[0] = sign_ct[1] = 0; + vpx_memset(bit_ct, 0, sizeof(unsigned int)*mvlong_width*2); + vpx_memset(short_ct, 0, sizeof(unsigned int)*mvnum_short); + vpx_memset(short_bct, 0, sizeof(unsigned int)*(mvnum_short-1)*2); + + { + const int c = events [mv_max]; + is_short_ct [0] += c; // Short vector + short_ct [0] += c; // Magnitude distribution + } + { + int j = 1; + do + { + const int c1 = events [mv_max + j]; //positive + const int c2 = events [mv_max - j]; //negative + const int c = c1 + c2; + int a = j; + + sign_ct [0] += c1; + sign_ct [1] += c2; + + if (a < mvnum_short) + { + is_short_ct [0] += c; // Short vector + short_ct [a] += c; // Magnitude distribution + } + else + { + int k = mvlong_width - 1; + is_short_ct [1] += c; // Long vector + + do + bit_ct [k] [(a >> k) & 1] += c; + + while (--k >= 0); + } + } + while (++j <= mv_max); + } + calc_prob(Pnew + mvpis_short, is_short_ct, 8); + + calc_prob(Pnew + MVPsign, sign_ct, 8); + + { + vp8_prob p [mvnum_short - 1]; /* actually only need branch ct */ + int j = 0; + + vp8_tree_probs_from_distribution( + mvnum_short, vp8_small_mvencodings, vp8_small_mvtree, + p, short_bct, short_ct, + 256, 1 + ); + + do + calc_prob(Pnew + MVPshort + j, short_bct[j], 8); + while (++j < mvnum_short - 1); + } + + { + int j = 0; + do + calc_prob(Pnew + MVPbits + j, bit_ct[j], 8); + while (++j < mvlong_width); + } +} + +#if CONFIG_HIGH_PRECISION_MV +static void compute_component_probs_hp( + const unsigned int events [MVvals_hp], + vp8_prob Pnew [MVPcount_hp], + unsigned int is_short_ct[2], + unsigned int sign_ct[2], + unsigned int bit_ct [mvlong_width_hp] [2], + unsigned int short_ct [mvnum_short_hp], + unsigned int short_bct [mvnum_short_hp-1] [2] +) +{ + is_short_ct[0] = is_short_ct[1] = 0; + sign_ct[0] = sign_ct[1] = 0; + vpx_memset(bit_ct, 0, sizeof(unsigned int)*mvlong_width_hp*2); + vpx_memset(short_ct, 0, sizeof(unsigned int)*mvnum_short_hp); + vpx_memset(short_bct, 0, sizeof(unsigned int)*(mvnum_short_hp-1)*2); + + { + const int c = events [mv_max_hp]; + is_short_ct [0] += c; // Short vector + short_ct [0] += c; // Magnitude distribution + } + { + int j = 1; + do + { + const int c1 = events [mv_max_hp + j]; //positive + const int c2 = events [mv_max_hp - j]; //negative + const int c = c1 + c2; + int a = j; + + sign_ct [0] += c1; + sign_ct [1] += c2; + + if (a < mvnum_short_hp) + { + is_short_ct [0] += c; // Short vector + short_ct [a] += c; // Magnitude distribution + } + else + { + int k = mvlong_width_hp - 1; + is_short_ct [1] += c; // Long vector + + do + bit_ct [k] [(a >> k) & 1] += c; + + while (--k >= 0); + } + } + while (++j <= mv_max_hp); + } + calc_prob(Pnew + mvpis_short_hp, is_short_ct, 8); + + calc_prob(Pnew + MVPsign_hp, sign_ct, 8); + + { + vp8_prob p [mvnum_short_hp - 1]; /* actually only need branch ct */ + int j = 0; + + vp8_tree_probs_from_distribution( + mvnum_short_hp, vp8_small_mvencodings_hp, vp8_small_mvtree_hp, + p, short_bct, short_ct, + 256, 1 + ); + + do + calc_prob(Pnew + MVPshort_hp + j, short_bct[j], 8); + while (++j < mvnum_short_hp - 1); + } + + { + int j = 0; + do + calc_prob(Pnew + MVPbits_hp + j, bit_ct[j], 8); + while (++j < mvlong_width_hp); + } +} +#endif /* CONFIG_HIGH_PRECISION_MV */ + +void vp8_entropy_mv_init() +{ + vp8_tokens_from_tree(vp8_small_mvencodings, vp8_small_mvtree); +#if CONFIG_HIGH_PRECISION_MV + vp8_tokens_from_tree(vp8_small_mvencodings_hp, vp8_small_mvtree_hp); +#endif +} + +#if CONFIG_ADAPTIVE_ENTROPY +//#define MV_COUNT_TESTING +#define MV_COUNT_SAT 16 +#define MV_MAX_UPDATE_FACTOR 128 +void vp8_adapt_mv_probs(VP8_COMMON *cm) +{ + int i, t, count, factor; +#ifdef MV_COUNT_TESTING + printf("static const unsigned int\nMVcount[2][MVvals]={\n"); + for (i = 0; i < 2; ++i) + { + printf(" { "); + for (t = 0; t < MVvals; t++) + { + printf("%d, ", cm->fc.MVcount[i][t]); + if (t%16 == 15 && t!=MVvals-1) printf("\n "); + } + printf("},\n"); + } + printf("};\n"); +#if CONFIG_HIGH_PRECISION_MV + printf("static const unsigned int\nMVcount_hp[2][MVvals_hp]={\n"); + for (i = 0; i < 2; ++i) + { + printf(" { "); + for (t = 0; t < MVvals_hp; t++) + { + printf("%d, ", cm->fc.MVcount_hp[i][t]); + if (t%16 == 15 && t!=MVvals_hp-1) printf("\n "); + } + printf("},\n"); + } + printf("};\n"); +#endif +#endif /* MV_COUNT_TESTING */ + + for (i = 0; i < 2; ++i) + { + int prob; + unsigned int is_short_ct[2]; + unsigned int sign_ct[2]; + unsigned int bit_ct [mvlong_width] [2]; + unsigned int short_ct [mvnum_short]; + unsigned int short_bct [mvnum_short-1] [2]; + vp8_prob Pnew [MVPcount]; + compute_component_probs(cm->fc.MVcount[i], Pnew, + is_short_ct, sign_ct, + bit_ct, short_ct, short_bct); + count = is_short_ct[0] + is_short_ct[1]; + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)cm->fc.pre_mvc[i].prob[mvpis_short] * (256-factor) + + (int)Pnew[mvpis_short] * factor + 128) >> 8; + if (prob <= 0) cm->fc.mvc[i].prob[mvpis_short] = 1; + else if (prob > 255) cm->fc.mvc[i].prob[mvpis_short] = 255; + else cm->fc.mvc[i].prob[mvpis_short] = prob; + + count = sign_ct[0] + sign_ct[1]; + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)cm->fc.pre_mvc[i].prob[MVPsign] * (256-factor) + + (int)Pnew[MVPsign] * factor + 128) >> 8; + if (prob <= 0) cm->fc.mvc[i].prob[MVPsign] = 1; + else if (prob > 255) cm->fc.mvc[i].prob[MVPsign] = 255; + else cm->fc.mvc[i].prob[MVPsign] = prob; + + for (t = 0; t < mvnum_short - 1; ++t) + { + count = short_bct[t][0] + short_bct[t][1]; + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)cm->fc.pre_mvc[i].prob[MVPshort+t] * (256-factor) + + (int)Pnew[MVPshort+t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.mvc[i].prob[MVPshort+t] = 1; + else if (prob > 255) cm->fc.mvc[i].prob[MVPshort+t] = 255; + else cm->fc.mvc[i].prob[MVPshort+t] = prob; + } + for (t = 0; t < mvlong_width; ++t) + { + count = bit_ct[t][0] + bit_ct[t][1]; + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)cm->fc.pre_mvc[i].prob[MVPbits+t] * (256-factor) + + (int)Pnew[MVPbits+t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.mvc[i].prob[MVPbits+t] = 1; + else if (prob > 255) cm->fc.mvc[i].prob[MVPbits+t] = 255; + else cm->fc.mvc[i].prob[MVPbits+t] = prob; + } + } +#if CONFIG_HIGH_PRECISION_MV + for (i = 0; i < 2; ++i) + { + int prob; + unsigned int is_short_ct[2]; + unsigned int sign_ct[2]; + unsigned int bit_ct [mvlong_width_hp] [2]; + unsigned int short_ct [mvnum_short_hp]; + unsigned int short_bct [mvnum_short_hp-1] [2]; + vp8_prob Pnew [MVPcount_hp]; + compute_component_probs_hp(cm->fc.MVcount_hp[i], Pnew, + is_short_ct, sign_ct, + bit_ct, short_ct, short_bct); + count = is_short_ct[0] + is_short_ct[1]; + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)cm->fc.pre_mvc_hp[i].prob[mvpis_short_hp] * (256-factor) + + (int)Pnew[mvpis_short_hp] * factor + 128) >> 8; + if (prob <= 0) cm->fc.mvc_hp[i].prob[mvpis_short_hp] = 1; + else if (prob > 255) cm->fc.mvc_hp[i].prob[mvpis_short_hp] = 255; + else cm->fc.mvc_hp[i].prob[mvpis_short_hp] = prob; + + count = sign_ct[0] + sign_ct[1]; + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)cm->fc.pre_mvc_hp[i].prob[MVPsign_hp] * (256-factor) + + (int)Pnew[MVPsign_hp] * factor + 128) >> 8; + if (prob <= 0) cm->fc.mvc_hp[i].prob[MVPsign_hp] = 1; + else if (prob > 255) cm->fc.mvc_hp[i].prob[MVPsign_hp] = 255; + else cm->fc.mvc_hp[i].prob[MVPsign_hp] = prob; + + for (t = 0; t < mvnum_short_hp - 1; ++t) + { + count = short_bct[t][0] + short_bct[t][1]; + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)cm->fc.pre_mvc_hp[i].prob[MVPshort_hp+t] * (256-factor) + + (int)Pnew[MVPshort_hp+t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.mvc_hp[i].prob[MVPshort_hp+t] = 1; + else if (prob > 255) cm->fc.mvc_hp[i].prob[MVPshort_hp+t] = 255; + else cm->fc.mvc_hp[i].prob[MVPshort_hp+t] = prob; + } + for (t = 0; t < mvlong_width_hp; ++t) + { + count = bit_ct[t][0] + bit_ct[t][1]; + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)cm->fc.pre_mvc_hp[i].prob[MVPbits_hp+t] * (256-factor) + + (int)Pnew[MVPbits_hp+t] * factor + 128) >> 8; + if (prob <= 0) cm->fc.mvc_hp[i].prob[MVPbits_hp+t] = 1; + else if (prob > 255) cm->fc.mvc_hp[i].prob[MVPbits_hp+t] = 255; + else cm->fc.mvc_hp[i].prob[MVPbits_hp+t] = prob; + } + } +#endif +} +#endif /* CONFIG_ADAPTIVE_ENTROPY */ diff --git a/vp8/common/entropymv.h b/vp8/common/entropymv.h index d97c12eab61caf883f746080ee83cab3b8ec9e77..09c2587d27f3b242d7cfe42288e4544b89837a52 100644 --- a/vp8/common/entropymv.h +++ b/vp8/common/entropymv.h @@ -71,6 +71,16 @@ typedef struct mv_context_hp } MV_CONTEXT_HP; extern const MV_CONTEXT_HP vp8_mv_update_probs_hp[2], vp8_default_mv_context_hp[2]; + #endif /* CONFIG_HIGH_PRECISION_MV */ +extern const vp8_tree_index vp8_small_mvtree[]; +extern struct vp8_token_struct vp8_small_mvencodings [8]; +#if CONFIG_HIGH_PRECISION_MV +extern const vp8_tree_index vp8_small_mvtree_hp[]; +extern struct vp8_token_struct vp8_small_mvencodings_hp [16]; +#endif + +void vp8_entropy_mv_init(); + #endif diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index f36915c51cf0f6455c224bce7ed4666e7091dc15..a068b43ae026bdefa6efc2f973fbc0ec359ca2ef 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -47,6 +47,7 @@ typedef struct frame_contexts vp8_prob bmode_prob [VP8_BINTRAMODES-1]; vp8_prob ymode_prob [VP8_YMODES-1]; /* interframe intra mode probs */ vp8_prob uv_mode_prob [VP8_YMODES][VP8_UV_MODES-1]; + vp8_prob i8x8_mode_prob [VP8_I8X8_MODES-1]; vp8_prob sub_mv_ref_prob [VP8_SUBMVREFS-1]; vp8_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; vp8_prob coef_probs_8x8 [BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; @@ -54,6 +55,31 @@ typedef struct frame_contexts #if CONFIG_HIGH_PRECISION_MV MV_CONTEXT_HP mvc_hp[2]; #endif +#if CONFIG_ADAPTIVE_ENTROPY + MV_CONTEXT pre_mvc[2]; +#if CONFIG_HIGH_PRECISION_MV + MV_CONTEXT_HP pre_mvc_hp[2]; +#endif + vp8_prob pre_bmode_prob [VP8_BINTRAMODES-1]; + vp8_prob pre_ymode_prob [VP8_YMODES-1]; /* interframe intra mode probs */ + vp8_prob pre_uv_mode_prob [VP8_YMODES][VP8_UV_MODES-1]; + vp8_prob pre_i8x8_mode_prob [VP8_I8X8_MODES-1]; + unsigned int bmode_counts [VP8_BINTRAMODES]; + unsigned int ymode_counts [VP8_YMODES]; /* interframe intra mode probs */ + unsigned int uv_mode_counts [VP8_YMODES][VP8_UV_MODES]; + unsigned int i8x8_mode_counts [VP8_I8X8_MODES]; /* interframe intra mode probs */ + + vp8_prob pre_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; + vp8_prob pre_coef_probs_8x8 [BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; + unsigned int coef_counts [BLOCK_TYPES] [COEF_BANDS] + [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; + unsigned int coef_counts_8x8 [BLOCK_TYPES_8X8] [COEF_BANDS] + [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; + unsigned int MVcount [2] [MVvals]; +#if CONFIG_HIGH_PRECISION_MV + unsigned int MVcount_hp [2] [MVvals_hp]; +#endif +#endif /* CONFIG_ADAPTIVE_ENTROPY */ } FRAME_CONTEXT; typedef enum @@ -104,7 +130,6 @@ typedef struct VP8_COMMON_RTCD } VP8_COMMON_RTCD; typedef struct VP8Common - { struct vpx_internal_error_info error; @@ -205,7 +230,6 @@ typedef struct VP8Common int kf_ymode_probs_index; int kf_ymode_probs_update; vp8_prob kf_uv_mode_prob[VP8_YMODES] [VP8_UV_MODES-1]; - vp8_prob i8x8_mode_prob [VP8_UV_MODES-1]; vp8_prob prob_intra_coded; vp8_prob prob_last_coded; diff --git a/vp8/common/tapify.py b/vp8/common/tapify.py old mode 100755 new mode 100644 diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index cd8de8a74e3e4a782ab56dc33561bf85e1dd07e7..3b9a098c54f643e04d834f19d8404858ab7930f2 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -171,7 +171,7 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, for(i=0;i<4;i++) { int ib = vp8_i8x8_block[i]; - mode8x8 = vp8_read_i8x8_mode(bc, pbi->common.i8x8_mode_prob); + mode8x8 = vp8_read_i8x8_mode(bc, pbi->common.fc.i8x8_mode_prob); m->bmi[ib+0].as_mode.first= mode8x8; m->bmi[ib+1].as_mode.first= mode8x8; m->bmi[ib+4].as_mode.first= mode8x8; @@ -789,10 +789,22 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, case NEW4X4: #if CONFIG_HIGH_PRECISION_MV if (xd->allow_high_precision_mv) + { read_mv_hp(bc, &blockmv.as_mv, (const MV_CONTEXT_HP *) mvc_hp); +#if CONFIG_ADAPTIVE_ENTROPY + cm->fc.MVcount_hp[0][mv_max_hp+(blockmv.as_mv.row)]++; + cm->fc.MVcount_hp[1][mv_max_hp+(blockmv.as_mv.col)]++; +#endif + } else #endif - read_mv(bc, &blockmv.as_mv, (const MV_CONTEXT *) mvc); + { + read_mv(bc, &blockmv.as_mv, (const MV_CONTEXT *) mvc); +#if CONFIG_ADAPTIVE_ENTROPY + cm->fc.MVcount[0][mv_max+(blockmv.as_mv.row>>1)]++; + cm->fc.MVcount[1][mv_max+(blockmv.as_mv.col>>1)]++; +#endif + } blockmv.as_mv.row += best_mv.as_mv.row; blockmv.as_mv.col += best_mv.as_mv.col; @@ -807,25 +819,25 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, secondmv.as_mv.row += best_mv_second.as_mv.row; secondmv.as_mv.col += best_mv_second.as_mv.col; } - #ifdef VPX_MODE_COUNT +#ifdef VPX_MODE_COUNT vp8_mv_cont_count[mv_contz][3]++; - #endif +#endif break; case LEFT4X4: blockmv.as_int = leftmv.as_int; if (mbmi->second_ref_frame) secondmv.as_int = second_leftmv.as_int; - #ifdef VPX_MODE_COUNT +#ifdef VPX_MODE_COUNT vp8_mv_cont_count[mv_contz][0]++; - #endif +#endif break; case ABOVE4X4: blockmv.as_int = abovemv.as_int; if (mbmi->second_ref_frame) secondmv.as_int = second_abovemv.as_int; - #ifdef VPX_MODE_COUNT +#ifdef VPX_MODE_COUNT vp8_mv_cont_count[mv_contz][1]++; - #endif +#endif break; case ZERO4X4: blockmv.as_int = 0; @@ -914,10 +926,22 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, case NEWMV: #if CONFIG_HIGH_PRECISION_MV if (xd->allow_high_precision_mv) + { read_mv_hp(bc, &mv->as_mv, (const MV_CONTEXT_HP *) mvc_hp); +#if CONFIG_ADAPTIVE_ENTROPY + cm->fc.MVcount_hp[0][mv_max_hp+(mv->as_mv.row)]++; + cm->fc.MVcount_hp[1][mv_max_hp+(mv->as_mv.col)]++; +#endif + } else #endif - read_mv(bc, &mv->as_mv, (const MV_CONTEXT *) mvc); + { + read_mv(bc, &mv->as_mv, (const MV_CONTEXT *) mvc); +#if CONFIG_ADAPTIVE_ENTROPY + cm->fc.MVcount[0][mv_max+(mv->as_mv.row>>1)]++; + cm->fc.MVcount[1][mv_max+(mv->as_mv.col>>1)]++; +#endif + } mv->as_mv.row += best_mv.as_mv.row; mv->as_mv.col += best_mv.as_mv.col; @@ -967,6 +991,9 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, { mbmi->mode = (MB_PREDICTION_MODE) vp8_read_ymode(bc, pbi->common.fc.ymode_prob); +#if CONFIG_ADAPTIVE_ENTROPY + pbi->common.fc.ymode_counts[mbmi->mode]++; +#endif } #if CONFIG_COMP_INTRA_PRED mbmi->second_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); @@ -982,6 +1009,9 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, do { mi->bmi[j].as_mode.first = (B_PREDICTION_MODE)vp8_read_bmode(bc, pbi->common.fc.bmode_prob); +#if CONFIG_ADAPTIVE_ENTROPY + pbi->common.fc.bmode_counts[mi->bmi[j].as_mode.first]++; +#endif #if CONFIG_COMP_INTRA_PRED if (use_comp_pred) { @@ -1003,11 +1033,14 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, for(i=0;i<4;i++) { int ib = vp8_i8x8_block[i]; - mode8x8 = vp8_read_i8x8_mode(bc, pbi->common.i8x8_mode_prob); + mode8x8 = vp8_read_i8x8_mode(bc, pbi->common.fc.i8x8_mode_prob); mi->bmi[ib+0].as_mode.first= mode8x8; mi->bmi[ib+1].as_mode.first= mode8x8; mi->bmi[ib+4].as_mode.first= mode8x8; mi->bmi[ib+5].as_mode.first= mode8x8; +#if CONFIG_ADAPTIVE_ENTROPY + pbi->common.fc.i8x8_mode_counts[mode8x8]++; +#endif #if CONFIG_COMP_INTRA_PRED mi->bmi[ib+0].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); mi->bmi[ib+1].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); @@ -1017,8 +1050,13 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, } } else + { mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, pbi->common.fc.uv_mode_prob[mbmi->mode]); +#if CONFIG_ADAPTIVE_ENTROPY + pbi->common.fc.uv_mode_counts[mbmi->mode][mbmi->uv_mode]++; +#endif + } #if CONFIG_COMP_INTRA_PRED mbmi->second_uv_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 68ef98481d8061ae6db4ee632ed2e723eaa7ed1d..0bfef9dddc764bdb57ecec03732bedd9252b1192 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -44,6 +44,8 @@ int dec_debug = 0; #endif +#define COEFCOUNT_TESTING + #if CONFIG_NEWUPDATE static int merge_index(int v, int n, int modulus) @@ -1019,6 +1021,7 @@ int vp8_decode_frame(VP8D_COMP *pbi) } else { + pc->last_frame_type = pc->frame_type; pc->frame_type = (FRAME_TYPE)(data[0] & 1); pc->version = (data[0] >> 1) & 7; pc->show_frame = (data[0] >> 4) & 1; @@ -1426,6 +1429,28 @@ int vp8_decode_frame(VP8D_COMP *pbi) fclose(z); } +#if CONFIG_ADAPTIVE_ENTROPY + vp8_copy(pbi->common.fc.pre_coef_probs, pbi->common.fc.coef_probs); + vp8_copy(pbi->common.fc.pre_coef_probs_8x8, pbi->common.fc.coef_probs_8x8); + vp8_copy(pbi->common.fc.pre_ymode_prob, pbi->common.fc.ymode_prob); + vp8_copy(pbi->common.fc.pre_uv_mode_prob, pbi->common.fc.uv_mode_prob); + vp8_copy(pbi->common.fc.pre_bmode_prob, pbi->common.fc.bmode_prob); + vp8_copy(pbi->common.fc.pre_i8x8_mode_prob, pbi->common.fc.i8x8_mode_prob); + vp8_copy(pbi->common.fc.pre_mvc, pbi->common.fc.mvc); +#if CONFIG_HIGH_PRECISION_MV + vp8_copy(pbi->common.fc.pre_mvc_hp, pbi->common.fc.mvc_hp); +#endif + vp8_zero(pbi->common.fc.coef_counts); + vp8_zero(pbi->common.fc.coef_counts_8x8); + vp8_zero(pbi->common.fc.ymode_counts); + vp8_zero(pbi->common.fc.uv_mode_counts); + vp8_zero(pbi->common.fc.bmode_counts); + vp8_zero(pbi->common.fc.i8x8_mode_counts); + vp8_zero(pbi->common.fc.MVcount); +#if CONFIG_HIGH_PRECISION_MV + vp8_zero(pbi->common.fc.MVcount_hp); +#endif +#endif #if COEFUPDATETYPE == 2 read_coef_probs2(pbi); #elif COEFUPDATETYPE == 3 @@ -1437,8 +1462,8 @@ int vp8_decode_frame(VP8D_COMP *pbi) vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->lst_fb_idx], sizeof(YV12_BUFFER_CONFIG)); vpx_memcpy(&xd->dst, &pc->yv12_fb[pc->new_fb_idx], sizeof(YV12_BUFFER_CONFIG)); - // Create the segmentation map structure and set to 0 - if (!pc->last_frame_seg_map) + // Create the segmentation map structure and set to 0 + if (!pc->last_frame_seg_map) CHECK_MEM_ERROR(pc->last_frame_seg_map, vpx_calloc((pc->mb_rows * pc->mb_cols), 1)); @@ -1490,6 +1515,14 @@ int vp8_decode_frame(VP8D_COMP *pbi) } /* vpx_log("Decoder: Frame Decoded, Size Roughly:%d bytes \n",bc->pos+pbi->bc2.pos); */ +#if CONFIG_ADAPTIVE_ENTROPY + vp8_adapt_coef_probs(pc); + if (pc->frame_type != KEY_FRAME) + { + vp8_adapt_mode_probs(pc); + vp8_adapt_mv_probs(pc); + } +#endif /* If this was a kf or Gf note the Q used */ if ((pc->frame_type == KEY_FRAME) || diff --git a/vp8/decoder/detokenize.c b/vp8/decoder/detokenize.c index 966c0f127dc1db543658e3329dd5f9654190ea8a..03cf620ccb9bcffb78675775fdaccb5efbc573e1 100644 --- a/vp8/decoder/detokenize.c +++ b/vp8/decoder/detokenize.c @@ -234,6 +234,7 @@ DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); ++c; \ goto DO_WHILE; }\ qcoeff_ptr [ 15 ] = (INT16) v; \ + c++; \ goto BLOCK_FINISHED; @@ -245,6 +246,7 @@ DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); ++c; \ goto DO_WHILE_8x8; }\ qcoeff_ptr [ scan[3] ] = (INT16) v; \ + c++; \ goto BLOCK_FINISHED_8x8; #define DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT_8x8(val) \ DECODE_AND_APPLYSIGN(val) \ @@ -254,6 +256,7 @@ DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); ++c; \ goto DO_WHILE_8x8; }\ qcoeff_ptr [ scan[63] ] = (INT16) v; \ + c++; \ goto BLOCK_FINISHED_8x8; @@ -274,6 +277,68 @@ DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); NORMALIZE +#if CONFIG_ADAPTIVE_ENTROPY +int get_token(int v) +{ + if (v < 0) v = -v; + if (v == 0) return ZERO_TOKEN; + else if (v == 1) return ONE_TOKEN; + else if (v == 2) return TWO_TOKEN; + else if (v == 3) return THREE_TOKEN; + else if (v == 4) return FOUR_TOKEN; + else if (v <= 6) return DCT_VAL_CATEGORY1; + else if (v <= 10) return DCT_VAL_CATEGORY2; + else if (v <= 18) return DCT_VAL_CATEGORY3; + else if (v <= 34) return DCT_VAL_CATEGORY4; + else if (v <= 66) return DCT_VAL_CATEGORY5; + else return DCT_VAL_CATEGORY6; +} + +void static count_tokens(INT16 *qcoeff_ptr, int block, int type, + ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, + int eob, int seg_eob, FRAME_CONTEXT *fc) +{ + int c, pt, token, band; + VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); + for (c = !type; c < eob; ++c) + { + int rc = vp8_default_zig_zag1d[c]; + int v = qcoeff_ptr[rc]; + band = vp8_coef_bands[c]; + token = get_token(v); + fc->coef_counts[type][band][pt][token]++; + pt = vp8_prev_token_class[token]; + } + if (eob < seg_eob) + { + band = vp8_coef_bands[c]; + fc->coef_counts[type][band][pt][DCT_EOB_TOKEN]++; + } +} + +void static count_tokens_8x8(INT16 *qcoeff_ptr, int block, int type, + ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, + int eob, int seg_eob, FRAME_CONTEXT *fc) +{ + int c, pt, token, band; + VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); + for (c = !type; c < eob; ++c) + { + int rc = (type == 1 ? vp8_default_zig_zag1d[c] : vp8_default_zig_zag1d_8x8[c]); + int v = qcoeff_ptr[rc]; + band = (type == 1 ? vp8_coef_bands[c] : vp8_coef_bands_8x8[c]); + token = get_token(v); + fc->coef_counts_8x8[type][band][pt][token]++; + pt = vp8_prev_token_class[token]; + } + if (eob < seg_eob) + { + band = (type == 1 ? vp8_coef_bands[c] : vp8_coef_bands_8x8[c]); + fc->coef_counts_8x8[type][band][pt][DCT_EOB_TOKEN]++; + } +} +#endif + int vp8_decode_mb_tokens_8x8(VP8D_COMP *dx, MACROBLOCKD *x) { ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)x->above_context; @@ -554,9 +619,13 @@ ONE_CONTEXT_NODE_0_8x8_: qcoeff_ptr [ scan[3] ] = (INT16) v;//15 else qcoeff_ptr [ scan[63] ] = (INT16) v; + c++; BLOCK_FINISHED_8x8: +#if CONFIG_ADAPTIVE_ENTROPY + count_tokens_8x8(qcoeff_ptr, i, type, a, l, c, seg_eob, &dx->common.fc); +#endif *a = *l = ((eobs[i] = c) != !type); // any nonzero data? if (i!=24) { @@ -776,7 +845,11 @@ ONE_CONTEXT_NODE_0_: } qcoeff_ptr [ 15 ] = (INT16) v; + ++c; BLOCK_FINISHED: +#if CONFIG_ADAPTIVE_ENTROPY + count_tokens(qcoeff_ptr, i, type, a, l, c, seg_eob, &dx->common.fc); +#endif *a = *l = ((eobs[i] = c) != !type); /* any nonzero data? */ eobtotal += c; diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 9275f253433a47f9154a9cdc0eb7dc38a487d442..05734a591b4f4cd8124433c8a1bac908e73eab65 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -957,7 +957,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) #endif if ( !segfeature_active( xd, segment_id, SEG_LVL_MODE ) ) + { write_ymode(w, mode, pc->fc.ymode_prob); + } if (mode == B_PRED) { @@ -985,22 +987,18 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) if(mode == I8X8_PRED) { write_i8x8_mode(w, m->bmi[0].as_mode.first, - pc->i8x8_mode_prob); + pc->fc.i8x8_mode_prob); write_i8x8_mode(w, m->bmi[2].as_mode.first, - pc->i8x8_mode_prob); + pc->fc.i8x8_mode_prob); write_i8x8_mode(w, m->bmi[8].as_mode.first, - pc->i8x8_mode_prob); + pc->fc.i8x8_mode_prob); write_i8x8_mode(w, m->bmi[10].as_mode.first, - pc->i8x8_mode_prob); + pc->fc.i8x8_mode_prob); } else { write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob[mode]); -#ifdef MODE_STATS - if(mode!=B_PRED) - ++cpi->y_uv_mode_count[mode][mi->uv_mode]; -#endif } } else @@ -1329,16 +1327,16 @@ static void write_kfmodes(VP8_COMP *cpi) if(ym == I8X8_PRED) { write_i8x8_mode(bc, m->bmi[0].as_mode.first, - c->i8x8_mode_prob); + c->fc.i8x8_mode_prob); //printf(" mode: %d\n", m->bmi[0].as_mode.first); fflush(stdout); write_i8x8_mode(bc, m->bmi[2].as_mode.first, - c->i8x8_mode_prob); + c->fc.i8x8_mode_prob); //printf(" mode: %d\n", m->bmi[2].as_mode.first); fflush(stdout); write_i8x8_mode(bc, m->bmi[8].as_mode.first, - c->i8x8_mode_prob); + c->fc.i8x8_mode_prob); //printf(" mode: %d\n", m->bmi[8].as_mode.first); fflush(stdout); write_i8x8_mode(bc, m->bmi[10].as_mode.first, - c->i8x8_mode_prob); + c->fc.i8x8_mode_prob); //printf(" mode: %d\n", m->bmi[10].as_mode.first); fflush(stdout); } else @@ -1883,6 +1881,7 @@ static void update_coef_probs(VP8_COMP *cpi) vp8_clear_system_state(); //__asm emms; // Build the cofficient contexts based on counts collected in encode loop + build_coeff_contexts(cpi); //vp8_prob bestupd = find_coef_update_prob(cpi); @@ -2117,17 +2116,18 @@ static void update_coef_probs(VP8_COMP *cpi) vp8_prob *Pold = cpi->common.fc.coef_probs_8x8 [i][j][k] + t; const vp8_prob oldp = *Pold; const vp8_prob upd = COEF_UPDATE_PROB_8X8; -#if CONFIG_NEWUPDATE && defined(SEARCH_NEWP) - const int s = prob_diff_update_savings_search(ct, oldp, &newp, upd); - const int u = s > 0 && newp != oldp ? 1 : 0; -#else - const int s = prob_update_savings(ct, oldp, newp, upd); - const int u = s > 0 ? 1 : 0; + int s, u; #if CONFIG_EXPANDED_COEF_CONTEXT if (k >=3 && ((i == 0 && j == 1) || (i > 0 && j == 0))) continue; #endif +#if CONFIG_NEWUPDATE && defined(SEARCH_NEWP) + s = prob_diff_update_savings_search(ct, oldp, &newp, upd); + u = s > 0 && newp != oldp ? 1 : 0; +#else + s = prob_update_savings(ct, oldp, newp, upd); + u = s > 0 ? 1 : 0; #endif vp8_write(w, u, upd); #ifdef ENTROPY_STATS @@ -2617,6 +2617,18 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) vp8_clear_system_state(); //__asm emms; +#if CONFIG_ADAPTIVE_ENTROPY + vp8_copy(cpi->common.fc.pre_coef_probs, cpi->common.fc.coef_probs); + vp8_copy(cpi->common.fc.pre_coef_probs_8x8, cpi->common.fc.coef_probs_8x8); + vp8_copy(cpi->common.fc.pre_ymode_prob, cpi->common.fc.ymode_prob); + vp8_copy(cpi->common.fc.pre_uv_mode_prob, cpi->common.fc.uv_mode_prob); + vp8_copy(cpi->common.fc.pre_bmode_prob, cpi->common.fc.bmode_prob); + vp8_copy(cpi->common.fc.pre_i8x8_mode_prob, cpi->common.fc.i8x8_mode_prob); + vp8_copy(cpi->common.fc.pre_mvc, cpi->common.fc.mvc); +#if CONFIG_HIGH_PRECISION_MV + vp8_copy(cpi->common.fc.pre_mvc_hp, cpi->common.fc.mvc_hp); +#endif +#endif #if COEFUPDATETYPE == 2 update_coef_probs2(cpi); #elif COEFUPDATETYPE == 3 @@ -2677,6 +2689,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) vp8_stop_encode(&cpi->bc2); *size += cpi->bc2.pos; + } #ifdef ENTROPY_STATS diff --git a/vp8/encoder/boolhuff.c b/vp8/encoder/boolhuff.c index 23f6b91b25b7bf4a41d1c83b7acd6d1d3bc856f5..d96ca7d40b76853302c9bae28a53aba32e216502 100644 --- a/vp8/encoder/boolhuff.c +++ b/vp8/encoder/boolhuff.c @@ -149,7 +149,7 @@ int vp8_count_term_subexp(int word, int k, int num_syms) int b = (i?k+i-1:k); int a = (1<<b); if (num_syms<=mk+3*a) { - count += vp8_count_uniform(num_syms-mk, word-mk); + count += vp8_count_uniform(word-mk, num_syms-mk); break; } else { int t = (word>=mk+a); diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 364d6ed55bafc0ddfa20fa83a9dd1cb0e1d9141b..2dfdd4cbd5fe3bdb2b9e40e31059ff140c53f665 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -1064,8 +1064,11 @@ void init_encode_frame_mb_context(VP8_COMP *cpi) xd->left_context = &cm->left_context; vp8_zero(cpi->count_mb_ref_frame_usage) + vp8_zero(cpi->bmode_count) vp8_zero(cpi->ymode_count) - vp8_zero(cpi->uv_mode_count) + vp8_zero(cpi->i8x8_mode_count) + vp8_zero(cpi->y_uv_mode_count) + //vp8_zero(cpi->uv_mode_count) x->mvc = cm->fc.mvc; #if CONFIG_HIGH_PRECISION_MV @@ -1206,6 +1209,7 @@ static void encode_frame_internal(VP8_COMP *cpi) vp8_zero(cpi->MVcount_hp); #endif vp8_zero(cpi->coef_counts); + vp8_zero(cpi->coef_counts_8x8); vp8cx_frame_init_quantizer(cpi); @@ -1502,8 +1506,24 @@ static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x) #endif ++cpi->ymode_count[m]; - ++cpi->uv_mode_count[uvm]; - + if (m!=I8X8_PRED) + ++cpi->y_uv_mode_count[m][uvm]; + else + { + cpi->i8x8_mode_count[xd->block[0].bmi.as_mode.first]++; + cpi->i8x8_mode_count[xd->block[2].bmi.as_mode.first]++; + cpi->i8x8_mode_count[xd->block[8].bmi.as_mode.first]++; + cpi->i8x8_mode_count[xd->block[10].bmi.as_mode.first]++; + } + if (m == B_PRED) + { + int b = 0; + do + { + ++ cpi->bmode_count[xd->block[b].bmi.as_mode.first]; + } + while (++b < 16); + } } // Experimental stub function to create a per MB zbin adjustment based on diff --git a/vp8/encoder/modecosts.c b/vp8/encoder/modecosts.c index 02f17c2371a56c42f8b5cdf82b8131af6865ad3e..c6198c2213de311e89ce583e9281f1b9a214ce10 100644 --- a/vp8/encoder/modecosts.c +++ b/vp8/encoder/modecosts.c @@ -49,6 +49,6 @@ void vp8_init_mode_costs(VP8_COMP *c) vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], x->kf_uv_mode_prob[VP8_YMODES-1], vp8_uv_mode_tree); vp8_cost_tokens(c->mb.i8x8_mode_costs, - x->i8x8_mode_prob,vp8_i8x8_mode_tree); + x->fc.i8x8_mode_prob,vp8_i8x8_mode_tree); } diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 642ff64ebe8f95b9f762ee8e2146b0725e8211f7..58165bab0bf8b1c2a41695e7aa4e6ebd4372290e 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -3692,6 +3692,25 @@ static void encode_frame_to_data_rate vp8_pack_bitstream(cpi, dest, size); update_reference_frames(cm); +#if CONFIG_ADAPTIVE_ENTROPY + vp8_copy(cpi->common.fc.coef_counts, cpi->coef_counts); + vp8_copy(cpi->common.fc.coef_counts_8x8, cpi->coef_counts_8x8); + vp8_adapt_coef_probs(&cpi->common); + if (cpi->common.frame_type != KEY_FRAME) + { + vp8_copy(cpi->common.fc.ymode_counts, cpi->ymode_count); + vp8_copy(cpi->common.fc.uv_mode_counts, cpi->y_uv_mode_count); + vp8_copy(cpi->common.fc.bmode_counts, cpi->bmode_count); + vp8_copy(cpi->common.fc.i8x8_mode_counts, cpi->i8x8_mode_count); + vp8_adapt_mode_probs(&cpi->common); + + vp8_copy(cpi->common.fc.MVcount, cpi->MVcount); +#if CONFIG_HIGH_PRECISION_MV + vp8_copy(cpi->common.fc.MVcount_hp, cpi->MVcount_hp); +#endif + vp8_adapt_mv_probs(&cpi->common); + } +#endif /* CONFIG_ADAPTIVE_ENTROPY */ /* Move storing frame_type out of the above loop since it is also * needed in motion search besides loopfilter */ diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 580b04403f647826e83603be23157f34a5d2bd98..f4e6f94901c9b7c0dd666e68bc28c5a7d2708c54 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -97,6 +97,8 @@ typedef struct vp8_prob ymode_prob [VP8_YMODES-1]; /* interframe intra mode probs */ vp8_prob uv_mode_prob [VP8_YMODES][VP8_UV_MODES-1]; + vp8_prob bmode_prob [VP8_BINTRAMODES-1]; + vp8_prob i8x8_mode_prob [VP8_I8X8_MODES-1]; int mv_ref_ct[6][4][2]; int mode_context[6][4]; @@ -454,7 +456,9 @@ typedef struct VP8_COMP int cq_target_quality; int ymode_count [VP8_YMODES]; /* intra MB type cts this frame */ - int uv_mode_count[VP8_UV_MODES]; /* intra MB type cts this frame */ + int bmode_count [VP8_BINTRAMODES]; + int i8x8_mode_count [VP8_I8X8_MODES]; + //int uv_mode_count[VP8_UV_MODES]; /* intra MB type cts this frame */ unsigned int MVcount [2] [MVvals]; /* (row,col) MV cts this frame */ #if CONFIG_HIGH_PRECISION_MV diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c index 864dd6573867bfa9c88384795d75801d9d37767e..9243af97873c0a6e95579ccc89f6a66568c8ed67 100644 --- a/vp8/encoder/ratectrl.c +++ b/vp8/encoder/ratectrl.c @@ -156,7 +156,9 @@ void vp8_save_coding_context(VP8_COMP *cpi) vp8_copy( cc->mode_context_a, cm->mode_context_a ); vp8_copy( cc->ymode_prob, cm->fc.ymode_prob ); + vp8_copy( cc->bmode_prob, cm->fc.bmode_prob ); vp8_copy( cc->uv_mode_prob, cm->fc.uv_mode_prob ); + vp8_copy( cc->i8x8_mode_prob, cm->fc.i8x8_mode_prob ); // Stats #ifdef MODE_STATS @@ -205,6 +207,8 @@ void vp8_restore_coding_context(VP8_COMP *cpi) vp8_copy( cm->mode_context_a, cc->mode_context_a ); vp8_copy( cm->fc.ymode_prob, cc->ymode_prob); + vp8_copy( cm->fc.bmode_prob, cc->bmode_prob); + vp8_copy( cm->fc.i8x8_mode_prob, cc->i8x8_mode_prob); vp8_copy( cm->fc.uv_mode_prob, cc->uv_mode_prob); // Stats