]> granicus.if.org Git - libvpx/commitdiff
added separate entropy context for alt_ref
authorYaowu Xu <yaowu@google.com>
Thu, 1 Dec 2011 00:36:46 +0000 (16:36 -0800)
committerYaowu Xu <yaowu@google.com>
Fri, 2 Dec 2011 22:43:33 +0000 (14:43 -0800)
This commit added code to keep track of separate entropy contexts for
normal frames and alt ref frames. The underly assumption was that the
two type of frames have different entropy characteristics given they
typically have quite different quantization levels. By keeping entropy
contexts separate, it helps the entropy context distribution to be more
closely adapted to each frame type.

Tests on derf set showed a good and very consistent gain on all clips
on all metrics, avg psnr: 0.89%, overall psnr: 0.84% and ssim 0.93%.

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

Change-Id: I15bc9697f6ff7829042911fe0c62930585d7e65d

vp8/common/onyxc_int.h
vp8/decoder/decodemv.c
vp8/decoder/decodframe.c
vp8/decoder/onyxd_if.c
vp8/encoder/bitstream.c
vp8/encoder/onyx_if.c
vp8/encoder/ratectrl.c

index d85cad0a2f72a237ab7db7f5450040d59c75eee3..7329e3869732b78d6596c94d1981f210d8461e8f 100644 (file)
@@ -199,7 +199,9 @@ typedef struct VP8Common
     vp8_prob i8x8_mode_prob [VP8_UV_MODES-1];
 #endif
 
-
+#if CONFIG_MULCONTEXT
+    FRAME_CONTEXT lfc_a; /* last alt ref entropy */
+#endif
     FRAME_CONTEXT lfc; /* last frame entropy */
     FRAME_CONTEXT fc;  /* this frame entropy */
 
index 68044f4d53c336bb5f38fe80c9ba1ccf7535eb70..7e3137fd26a4b764541de801a7c5742372704ff8 100644 (file)
@@ -854,4 +854,4 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
 #endif
 
 
-}
+}
\ No newline at end of file
index 5e89252862687de6ed952fb7a3cc3990908d64ee..f3da2d0b573d7ceeeed18f3988df4463eaf59733 100644 (file)
@@ -830,9 +830,16 @@ static void init_frame(VP8D_COMP *pbi)
          */
         pc->ref_frame_sign_bias[GOLDEN_FRAME] = 0;
         pc->ref_frame_sign_bias[ALTREF_FRAME] = 0;
+
+#if CONFIG_MULCONTEXT
+        vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
+        vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
+#endif
+
     }
     else
     {
+
         if (!pc->use_bilinear_mc_filter)
             pc->mcomp_filter_type = SIXTAP;
         else
@@ -1206,6 +1213,13 @@ int vp8_decode_frame(VP8D_COMP *pbi)
             pc->refresh_alt_ref_frame = 0;
 #endif
 
+#if CONFIG_MULCONTEXT
+        if(pc->refresh_alt_ref_frame)
+            vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc));
+        else
+            vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
+#endif
+
         /* Buffer to buffer copy flags. */
         pc->copy_buffer_to_gf = 0;
 
@@ -1391,12 +1405,21 @@ int vp8_decode_frame(VP8D_COMP *pbi)
     {
         pc->last_kf_gf_q = pc->base_qindex;
     }
-
+#if CONFIG_MULCONTEXT
+    if(pc->refresh_entropy_probs)
+    {
+        if(pc->refresh_alt_ref_frame)
+            vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
+        else
+            vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
+    }
+#else
     if (pc->refresh_entropy_probs == 0)
     {
         vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
         pbi->independent_partitions = prev_independent_partitions;
     }
+#endif
 
 #ifdef PACKET_TESTING
     {
index a45d692d0ccc6c5835ae2d768dd5f9186e36ac73..7862cbf900c7997b2b2fdfd5f18d3afdf58efd91 100644 (file)
@@ -80,6 +80,7 @@ void vp8_recon_write_yuv_frame(char *name, YV12_BUFFER_CONFIG *s)
     fclose(yuv_file);
 }
 #endif
+//#define WRITE_RECON_BUFFER 1
 #if WRITE_RECON_BUFFER
 void write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
 {
@@ -93,21 +94,24 @@ void write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
     yframe = fopen(filename, "wb");
 
     for (i = 0; i < frame->y_height; i++)
-        fwrite(frame->y_buffer + i * frame->y_stride, frame->y_width, 1, yframe);
+        fwrite(frame->y_buffer + i * frame->y_stride,
+            frame->y_width, 1, yframe);
 
     fclose(yframe);
     sprintf(filename, "dx\\u%04d.raw", this_frame);
     yframe = fopen(filename, "wb");
 
     for (i = 0; i < frame->uv_height; i++)
-        fwrite(frame->u_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+        fwrite(frame->u_buffer + i * frame->uv_stride,
+            frame->uv_width, 1, yframe);
 
     fclose(yframe);
     sprintf(filename, "dx\\v%04d.raw", this_frame);
     yframe = fopen(filename, "wb");
 
     for (i = 0; i < frame->uv_height; i++)
-        fwrite(frame->v_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+        fwrite(frame->v_buffer + i * frame->uv_stride,
+            frame->uv_width, 1, yframe);
 
     fclose(yframe);
 }
@@ -579,9 +583,17 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
 
 #if WRITE_RECON_BUFFER
         if(cm->show_frame)
+<<<<<<< HEAD
             write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
         else
             write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame+1000);
+=======
+            write_dx_frame_to_file(cm->frame_to_show,
+                cm->current_video_frame);
+        else
+            write_dx_frame_to_file(cm->frame_to_show,
+                cm->current_video_frame+1000);
+>>>>>>> added separate entropy context for alt_ref
 #endif
 
         if(cm->filter_level)
index 6171492c6154f9c9d93a28192f0780ad488086d1..b19d58e3c720531898fcc9c38c94932fbc66c454 100644 (file)
@@ -2222,10 +2222,11 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
 
     //************************************************
     // save a copy for later refresh
+#if !CONFIG_MULCONTEXT
     {
         vpx_memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc));
     }
-
+#endif
     update_coef_probs(cpi);
 
 #ifdef ENTROPY_STATS
index 867c4bdec45bcffe5509087992378df8912e896c..829906a1c33f646b7530d84cae4b343af17e1389 100644 (file)
@@ -3364,7 +3364,7 @@ static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest,
     vp8_first_pass(cpi);
 }
 #endif
-
+//#define WRITE_RECON_BUFFER 1
 #if WRITE_RECON_BUFFER
 void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
 {
@@ -3378,21 +3378,24 @@ void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
     yframe = fopen(filename, "wb");
 
     for (i = 0; i < frame->y_height; i++)
-        fwrite(frame->y_buffer + i * frame->y_stride, frame->y_width, 1, yframe);
+        fwrite(frame->y_buffer + i * frame->y_stride,
+            frame->y_width, 1, yframe);
 
     fclose(yframe);
     sprintf(filename, "cx\\u%04d.raw", this_frame);
     yframe = fopen(filename, "wb");
 
     for (i = 0; i < frame->uv_height; i++)
-        fwrite(frame->u_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+        fwrite(frame->u_buffer + i * frame->uv_stride,
+            frame->uv_width, 1, yframe);
 
     fclose(yframe);
     sprintf(filename, "cx\\v%04d.raw", this_frame);
     yframe = fopen(filename, "wb");
 
     for (i = 0; i < frame->uv_height; i++)
-        fwrite(frame->v_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+        fwrite(frame->v_buffer + i * frame->uv_stride,
+            frame->uv_width, 1, yframe);
 
     fclose(yframe);
 }
@@ -4154,7 +4157,13 @@ static void encode_frame_to_data_rate
             resize_key_frame(cpi);
             vp8_setup_key_frame(cpi);
         }
-
+#if CONFIG_MULCONTEXT
+        else
+        {
+            /* setup entropy for nonkey frame */
+            vp8_setup_inter_frame(cpi);
+        }
+#endif
         // transform / motion compensation build reconstruction frame
         vp8_encode_frame(cpi);
 
@@ -4512,9 +4521,17 @@ static void encode_frame_to_data_rate
 
 #if WRITE_RECON_BUFFER
     if(cm->show_frame)
+<<<<<<< HEAD
         write_cx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
     else
         write_cx_frame_to_file(cm->frame_to_show, cm->current_video_frame+1000);
+=======
+        write_cx_frame_to_file(cm->frame_to_show,
+            cm->current_video_frame);
+    else
+        write_cx_frame_to_file(cm->frame_to_show,
+            cm->current_video_frame+1000);
+>>>>>>> added separate entropy context for alt_ref
 #endif
 
 #if CONFIG_MULTITHREAD
@@ -5309,10 +5326,23 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
 
     }
 
+
+
+#if CONFIG_MULCONTEXT
+    if(cm->refresh_entropy_probs)
+    {
+        if(cm->refresh_alt_ref_frame)
+            vpx_memcpy(&cm->lfc_a, &cm->fc, sizeof(cm->fc));
+        else
+            vpx_memcpy(&cm->lfc, &cm->fc, sizeof(cm->fc));
+    }
+#else
     if (cm->refresh_entropy_probs == 0)
     {
         vpx_memcpy(&cm->fc, &cm->lfc, sizeof(cm->fc));
     }
+#endif
+
 
     // if its a dropped frame honor the requests on subsequent frames
     if (*size > 0)
index 9a7907e65a07b6388c5a98ec51768f88f0dd0fb1..de6ccaf0f7a010fbbea0192c681990cdb596fc20 100644 (file)
@@ -247,7 +247,22 @@ void vp8_setup_key_frame(VP8_COMP *cpi)
 
     cpi->common.refresh_golden_frame = TRUE;
     cpi->common.refresh_alt_ref_frame = TRUE;
+
+#if CONFIG_MULCONTEXT
+    vpx_memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc));
+    vpx_memcpy(&cpi->common.lfc_a, &cpi->common.fc, sizeof(cpi->common.fc));
+#endif
+
 }
+#if CONFIG_MULCONTEXT
+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));
+    else
+        vpx_memcpy(&cpi->common.fc, &cpi->common.lfc, sizeof(cpi->common.fc));
+}
+#endif
 
 
 static int estimate_bits_at_q(int frame_kind, int Q, int MBs,