]> granicus.if.org Git - libvpx/commitdiff
Adaptive entropy coding of coefficients, modes, mv.
authorDeb Mukherjee <debargha@google.com>
Tue, 5 Jun 2012 22:25:07 +0000 (15:25 -0700)
committerDeb Mukherjee <debargha@google.com>
Fri, 15 Jun 2012 17:35:23 +0000 (10:35 -0700)
This patch incorporates adaptive entropy coding of coefficient tokens,
and mode/mv information based on distributions encountered in a frame.
Specifically, there is an initial forward update to the probabilities
in the bitstream as before for coding the symbols in the frame, however
at the end of decoding each frame, the forward update to the
probabilities is reverted and instead the probabilities are updated
towards the actual distributions encountered within the frame.
The amount of update is weighted by the number of hits within each
context.

Results on derf/hd/std-hd are all up by 1.6%.

On derf, the most of the gains come from coefficients, however for the
hd and std-hd sets, the most of the gains come from the mode/mv
information updates.

Change-Id: I708c0e11fdacafee04940fe7ae159ba6844005fd

21 files changed:
configure [changed mode: 0755->0644]
vp8/common/alloccommon.c
vp8/common/default_coef_probs.h [changed mode: 0755->0644]
vp8/common/entropy.c
vp8/common/entropy.h
vp8/common/entropymode.c
vp8/common/entropymode.h
vp8/common/entropymv.c
vp8/common/entropymv.h
vp8/common/onyxc_int.h
vp8/common/tapify.py [changed mode: 0755->0644]
vp8/decoder/decodemv.c
vp8/decoder/decodframe.c
vp8/decoder/detokenize.c
vp8/encoder/bitstream.c
vp8/encoder/boolhuff.c
vp8/encoder/encodeframe.c
vp8/encoder/modecosts.c
vp8/encoder/onyx_if.c
vp8/encoder/onyx_int.h
vp8/encoder/ratectrl.c

old mode 100755 (executable)
new mode 100644 (file)
index 8c3716e..a394fff
--- a/configure
+++ b/configure
@@ -230,6 +230,7 @@ EXPERIMENT_LIST="
     expanded_coef_context
     int_8x8fdct
     newintramodes
+    adaptive_entropy
 "
 CONFIG_LIST="
     external_build
index 8bab3452ff43adb276a8e2237eb47ee5ad4112b8..2830c3e15d946d79145e72a4a28132a0d17aa464 100644 (file)
@@ -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();
 
 }
old mode 100755 (executable)
new mode 100644 (file)
index 9849fd4c297a3f0cb7c6b815aa73bd405bcdd8ee..0b0a2357fe85ce3c82c6cd325d315b02ec7c2e92 100644 (file)
@@ -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
index 692c2c4184cf48c909821cc05c931315d9c3c05d..78f8d5d03478b10531785bd6761e7dc2502bf28d 100644 (file)
@@ -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
index 0ae6a934326941d717233c4134560e361d577e0c..a1a3cfa887d3d8f5fb2ece13b9ce6aaa80eef531 100644 (file)
@@ -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
index 09d5c7704253c61a2c59d9993eb5f54cf75db3b3..cfd53273602b97bf21f804c2117a907443f92510 100644 (file)
@@ -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
index 90195f7bccdeb2c2de6413f5c10aa587ccca23f6..2c27b0913e4ae4f679cf72525f34384872df024d 100644 (file)
@@ -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 */
index d97c12eab61caf883f746080ee83cab3b8ec9e77..09c2587d27f3b242d7cfe42288e4544b89837a52 100644 (file)
@@ -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
index f36915c51cf0f6455c224bce7ed4666e7091dc15..a068b43ae026bdefa6efc2f973fbc0ec359ca2ef 100644 (file)
@@ -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;
old mode 100755 (executable)
new mode 100644 (file)
index cd8de8a74e3e4a782ab56dc33561bf85e1dd07e7..3b9a098c54f643e04d834f19d8404858ab7930f2 100644 (file)
@@ -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);
index 68ef98481d8061ae6db4ee632ed2e723eaa7ed1d..0bfef9dddc764bdb57ecec03732bedd9252b1192 100644 (file)
@@ -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) ||
index 966c0f127dc1db543658e3329dd5f9654190ea8a..03cf620ccb9bcffb78675775fdaccb5efbc573e1 100644 (file)
@@ -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;
index 9275f253433a47f9154a9cdc0eb7dc38a487d442..05734a591b4f4cd8124433c8a1bac908e73eab65 100644 (file)
@@ -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
index 23f6b91b25b7bf4a41d1c83b7acd6d1d3bc856f5..d96ca7d40b76853302c9bae28a53aba32e216502 100644 (file)
@@ -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);
index 364d6ed55bafc0ddfa20fa83a9dd1cb0e1d9141b..2dfdd4cbd5fe3bdb2b9e40e31059ff140c53f665 100644 (file)
@@ -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
index 02f17c2371a56c42f8b5cdf82b8131af6865ad3e..c6198c2213de311e89ce583e9281f1b9a214ce10 100644 (file)
@@ -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);
 
 }
index 642ff64ebe8f95b9f762ee8e2146b0725e8211f7..58165bab0bf8b1c2a41695e7aa4e6ebd4372290e 100644 (file)
@@ -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 */
index 580b04403f647826e83603be23157f34a5d2bd98..f4e6f94901c9b7c0dd666e68bc28c5a7d2708c54 100644 (file)
@@ -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
index 864dd6573867bfa9c88384795d75801d9d37767e..9243af97873c0a6e95579ccc89f6a66568c8ed67 100644 (file)
@@ -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