shithub: libvpx

Download patch

ref: ba1a6619b3e06324354b728ec28d1b0750a7cc32
parent: 7748d833e8dc61c6169529dc105aacea006ee455
author: Yaowu Xu <yaowu@google.com>
date: Thu Dec 8 06:43:09 EST 2011

Revised coding using adaptive mode context to depend on frame type

A previous commit 76feb965 made the vp8_mode_context adaptive on a frame
frame basis, this commit further made the coding context adaptive to two
frame types separately. Tests on derf set showed a further small gain on
all metrics: avg psnr 0.10%, glb psnr: 0.11%, ssim: 0.08%

http://www.corp.google.com/~yaowu/no_crawl/newNearMode_1209.html

Change-Id: I7b3e32ec8729de1903d14a3f1213f1624b78cdee

--- a/vp8/common/alloccommon.c
+++ b/vp8/common/alloccommon.c
@@ -190,12 +190,6 @@
     vp8_machine_specific_config(oci);
 
     vp8_init_mbmode_probs(oci);
-#if CONFIG_NEWNEAR
-    vp8_init_mv_ref_counts(oci);
-#endif
-    vpx_memcpy( oci->vp8_mode_contexts,
-                default_vp8_mode_contexts,
-                sizeof(default_vp8_mode_contexts));
 
     vp8_default_bmode_probs(oci->fc.bmode_prob);
 
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -9,10 +9,12 @@
  */
 
 
+#include "modecont.h"
 #include "entropymode.h"
 #include "entropy.h"
 #include "vpx_mem/vpx_mem.h"
 
+
 #if CONFIG_QIMODE
 const unsigned int kf_y_mode_cts[8][VP8_YMODES] =
 {
@@ -356,9 +358,18 @@
 }
 
 #if CONFIG_NEWNEAR
-void vp8_init_mv_ref_counts(VP8_COMMON *pc)
+void vp8_init_mode_contexts(VP8_COMMON *pc)
 {
     vpx_memset(pc->mv_ref_ct, 0, sizeof(pc->mv_ref_ct));
+    vpx_memset(pc->mv_ref_ct_a, 0, sizeof(pc->mv_ref_ct_a));
+
+    vpx_memcpy( pc->mode_context,
+                default_vp8_mode_contexts,
+                sizeof (pc->mode_context));
+    vpx_memcpy( pc->mode_context_a,
+                default_vp8_mode_contexts,
+                sizeof (pc->mode_context_a));
+
 }
 
 void vp8_accum_mv_refs(VP8_COMMON *pc,
@@ -365,34 +376,41 @@
                        MB_PREDICTION_MODE m,
                        const int ct[4])
 {
+    int (*mv_ref_ct)[4][2];
+
+    if(pc->refresh_alt_ref_frame)
+        mv_ref_ct = pc->mv_ref_ct_a;
+    else
+        mv_ref_ct = pc->mv_ref_ct;
+
     if (m == ZEROMV)
     {
-        ++pc->mv_ref_ct [ct[0]] [0] [0];
+        ++mv_ref_ct [ct[0]] [0] [0];
     }
     else
     {
-        ++pc->mv_ref_ct [ct[0]] [0] [1];
+        ++mv_ref_ct [ct[0]] [0] [1];
         if (m == NEARESTMV)
         {
-            ++pc->mv_ref_ct [ct[1]] [1] [0];
+            ++mv_ref_ct [ct[1]] [1] [0];
         }
         else
         {
-            ++pc->mv_ref_ct [ct[1]] [1] [1];
+            ++mv_ref_ct [ct[1]] [1] [1];
             if (m == NEARMV)
             {
-                ++pc->mv_ref_ct [ct[2]] [2] [0];
+                ++mv_ref_ct [ct[2]] [2] [0];
             }
             else
             {
-                ++pc->mv_ref_ct [ct[2]] [2] [1];
+                ++mv_ref_ct [ct[2]] [2] [1];
                 if (m == NEWMV)
                 {
-                    ++pc->mv_ref_ct [ct[3]] [3] [0];
+                    ++mv_ref_ct [ct[3]] [3] [0];
                 }
                 else
                 {
-                    ++pc->mv_ref_ct [ct[3]] [3] [1];
+                    ++mv_ref_ct [ct[3]] [3] [1];
                 }
             }
         }
@@ -402,24 +420,37 @@
 void vp8_update_mode_context(VP8_COMMON *pc)
 {
     int i, j;
+    int (*mv_ref_ct)[4][2];
+    int (*mode_context)[4];
+
+    if(pc->refresh_alt_ref_frame)
+    {
+        mv_ref_ct = pc->mv_ref_ct_a;
+        mode_context = pc->mode_context_a;
+    }
+    else
+    {
+        mv_ref_ct = pc->mv_ref_ct;
+        mode_context = pc->mode_context;
+    }
+
     for (j = 0; j < 6; j++)
     {
         for (i = 0; i < 4; i++)
         {
             int this_prob;
-            int count;
-            // context probs
-            count = pc->mv_ref_ct[j][i][0] + pc->mv_ref_ct[j][i][1];
+            int count = mv_ref_ct[j][i][0] + mv_ref_ct[j][i][1];
+
             if (count)
-                this_prob = 256 * pc->mv_ref_ct[j][i][0] / count;
+                this_prob = 256 * mv_ref_ct[j][i][0] / count;
             else
                 this_prob = 128;
+            this_prob = this_prob? (this_prob<255?this_prob:255):1;
             if (this_prob == 0)
                 this_prob = 1;
             if (this_prob == 256)
                 this_prob = 255;
-
-            pc->mode_context[j][i] = this_prob;
+            mode_context[j][i] = this_prob;
         }
     }
 }
@@ -427,14 +458,25 @@
 void print_mode_contexts(VP8_COMMON *pc)
 {
     int j, i;
+    printf("====================\n");
     for(j=0; j<6; j++)
     {
         for (i = 0; i < 4; i++)
         {
-            printf( "%4d ", pc->vp8_mode_contexts[j][i]);
+            printf( "%4d ", pc->mode_context[j][i]);
         }
         printf("\n");
     }
+    printf("====================\n");
+    for(j=0; j<6; j++)
+    {
+        for (i = 0; i < 4; i++)
+        {
+            printf( "%4d ", pc->mode_context_a[j][i]);
+        }
+        printf("\n");
+    }
+
 }
 void print_mv_ref_cts(VP8_COMMON *pc)
 {
--- a/vp8/common/entropymode.h
+++ b/vp8/common/entropymode.h
@@ -63,6 +63,8 @@
 
 void vp8_init_mbmode_probs(VP8_COMMON *x);
 
+extern void vp8_update_mode_context(VP8_COMMON *pc);;
+
 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]);
 
--- a/vp8/common/modecont.c
+++ b/vp8/common/modecont.c
@@ -10,9 +10,40 @@
 
 
 #include "entropy.h"
-
+#if CONFIG_NEWNEAR
 const int default_vp8_mode_contexts[6][4] =
 {
+    {   /* 0 */
+         7,     1,     1,   183},
+    {   /* 1 */
+        14,    18,    14,   147},
+    {/* 2 */
+       135,    64,    57,    68},
+    {   /* 3 */
+         60,    56,   128,   65},
+    {/* 4 */
+        159,   134,   128,   34},
+    {   /* 5 */
+        234,   188,   128,   28},
+};
+const int default_vp8_mode_contexts_a[6][4] =
+{
+    {   /* 0 */
+         4,     1,    1,   143},
+    {   /* 1 */
+         7,     9,    7,   107},
+    {/* 2 */
+        95,    34,   57,    68},
+    {   /* 3 */
+        95,    56,   128,   65},
+    {/* 4 */
+        159,   67,   128,   34},
+    {   /* 5 */
+        234,   94,   128,   28},
+};
+#else
+const int default_vp8_mode_contexts[6][4] =
+{
     {
         /* 0 */
         7,     1,     1,   143,
@@ -38,3 +69,4 @@
         234,   188,   128,    28,
     },
 };
+#endif
\ No newline at end of file
--- a/vp8/common/modecont.h
+++ b/vp8/common/modecont.h
@@ -13,5 +13,7 @@
 #define __INC_MODECONT_H
 
 extern const int default_vp8_mode_contexts[6][4];
-
+#if CONFIG_NEWNEAR
+extern const int default_vp8_mode_contexts_a[6][4];
+#endif
 #endif
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -218,12 +218,13 @@
 #if CONFIG_NEWNEAR
     int mv_ref_ct[6][4][2];
     int mode_context[6][4];
+    int mv_ref_ct_a[6][4][2];
+    int mode_context_a[6][4];
 #endif
 
     int vp8_mode_contexts[6][4];
 
     unsigned int current_video_frame;
-
     int near_boffset[3];
     int version;
 
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -848,8 +848,16 @@
         vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
 
 #if CONFIG_NEWNEAR
-        vp8_init_mv_ref_counts(&pbi->common);
-#endif
+        vp8_init_mode_contexts(&pbi->common);
+        vpx_memcpy( pbi->common.vp8_mode_contexts,
+                    pbi->common.mode_context,
+                    sizeof(pbi->common.mode_context));
+
+#else
+        vpx_memcpy( pbi->common.vp8_mode_contexts,
+                    default_vp8_mode_contexts,
+                    sizeof(default_vp8_mode_contexts));
+#endif /* CONFIG_NEWNEAR */
     }
     else
     {
@@ -1236,9 +1244,23 @@
 #endif
 
         if(pc->refresh_alt_ref_frame)
+        {
             vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc));
+#if CONFIG_NEWNEAR
+            vpx_memcpy( pc->vp8_mode_contexts,
+                        pc->mode_context_a,
+                        sizeof(pc->vp8_mode_contexts));
+#endif
+        }
         else
+        {
             vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
+#if CONFIG_NEWNEAR
+            vpx_memcpy( pc->vp8_mode_contexts,
+                        pc->mode_context,
+                        sizeof(pc->vp8_mode_contexts));
+#endif
+        }
 
         /* Buffer to buffer copy flags. */
         pc->copy_buffer_to_gf = 0;
@@ -1351,25 +1373,9 @@
 
     vp8_decode_mode_mvs(pbi);
 #if CONFIG_NEWNEAR
-    if(!pbi->common.refresh_alt_ref_frame)
+    if(pbi->common.frame_type != KEY_FRAME)
     {
         vp8_update_mode_context(&pbi->common);
-        vpx_memcpy( pc->vp8_mode_contexts,
-                    pbi->common.mode_context,
-                    sizeof(pbi->common.mode_context));
-
-            if(0) //pbi->common.current_video_frame<2)
-            {
-                printf("mv_ref_ct on frame %d:\n",
-                        pbi->common.current_video_frame);
-                print_mv_ref_cts(&pbi->common);
-
-                printf("mode_contexts on frame %d:\n",
-                        pbi->common.current_video_frame);
-                print_mode_contexts();
-            }
-
-
     }
 #endif
 
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -2319,25 +2319,7 @@
         pack_inter_mode_mvs(cpi);
 
 #if CONFIG_NEWNEAR
-        if(!cpi->common.refresh_alt_ref_frame)
-        {
-            vp8_update_mode_context(&cpi->common);
-            vpx_memcpy( pc->vp8_mode_contexts,
-                        cpi->common.mode_context,
-                        sizeof(cpi->common.mode_context));
-
-            if(0) //(cpi->common.current_video_frame<2)
-            {
-
-                printf("mv_ref_ct on frame %d:\n",
-                        cpi->common.current_video_frame);
-                print_mv_ref_cts(&cpi->common);
-
-                printf("mode_contexts on frame %d:\n",
-                        cpi->common.current_video_frame);
-                print_mode_contexts();
-            }
-        }
+        vp8_update_mode_context(&cpi->common);
 #endif
 
 #ifdef ENTROPY_STATS
--- a/vp8/encoder/mcomp.h
+++ b/vp8/encoder/mcomp.h
@@ -25,7 +25,6 @@
 #define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS)) - 1)      // Max full pel mv specified in 1 pel units
 #define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS-1))            // Maximum size of the first step in full pel units
 
-extern void print_mode_context(void);
 extern int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight);
 extern void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride);
 extern void vp8_init3smotion_compensation(MACROBLOCK *x,  int stride);
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -2630,7 +2630,9 @@
                                    - cpi->first_time_stamp_ever) / 10000000.000;
             double total_encode_time = (cpi->time_receive_data + cpi->time_compress_data)   / 1000.000;
             double dr = (double)cpi->bytes * (double) 8 / (double)1000  / time_encoded;
-
+#if CONFIG_NEWNEAR&&defined(MODE_STATS)
+            print_mode_contexts(&cpi->common);
+#endif
             if (cpi->b_calculate_psnr)
             {
                 YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx];
@@ -4361,6 +4363,8 @@
             /* setup entropy for nonkey frame */
             vp8_setup_inter_frame(cpi);
         }
+
+
         // transform / motion compensation build reconstruction frame
         vp8_encode_frame(cpi);
 
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -266,15 +266,40 @@
     vpx_memcpy(&cpi->common.lfc_a, &cpi->common.fc, sizeof(cpi->common.fc));
 
 #if CONFIG_NEWNEAR
-    vp8_init_mv_ref_counts(&cpi->common);
-#endif
+    vp8_init_mode_contexts(&cpi->common);
+    vpx_memcpy( cpi->common.vp8_mode_contexts,
+                cpi->common.mode_context,
+                sizeof(cpi->common.mode_context));
+#else
+    vpx_memcpy( cpi->common.vp8_mode_contexts,
+                default_vp8_mode_contexts,
+                sizeof(default_vp8_mode_contexts));
+#endif /* CONFIG_NEWNEAR */
 }
 void vp8_setup_inter_frame(VP8_COMP *cpi)
 {
     if(cpi->common.refresh_alt_ref_frame)
-        vpx_memcpy(&cpi->common.fc, &cpi->common.lfc_a, sizeof(cpi->common.fc));
+    {
+        vpx_memcpy( &cpi->common.fc,
+                    &cpi->common.lfc_a,
+                    sizeof(cpi->common.fc));
+#if CONFIG_NEWNEAR
+        vpx_memcpy( cpi->common.vp8_mode_contexts,
+                    cpi->common.mode_context_a,
+                    sizeof(cpi->common.vp8_mode_contexts));
+#endif /* CONFIG_NEWNEAR */
+    }
     else
-        vpx_memcpy(&cpi->common.fc, &cpi->common.lfc, sizeof(cpi->common.fc));
+    {
+        vpx_memcpy( &cpi->common.fc,
+                    &cpi->common.lfc,
+                    sizeof(cpi->common.fc));
+#if CONFIG_NEWNEAR
+        vpx_memcpy( cpi->common.vp8_mode_contexts,
+                    cpi->common.mode_context,
+                    sizeof(cpi->common.vp8_mode_contexts));
+#endif /* CONFIG_NEWNEAR */
+    }
 }
 
 
--