shithub: libvpx

Download patch

ref: a9df4183a6587719c9530d45d5dbd81530be9e7b
parent: f82d601f94a2fef69a0a12790c5fcdf49bbbdf2c
author: Paul Wilkins <paulwilkins@google.com>
date: Fri Nov 4 14:29:51 EDT 2011

Segment signaling of TX size

Initial attempt at using new segment feature signaling
to indicate 4x4 or 8x8 transform.

needs --enable-experimental --enable-t8x8

Note this is work in progress.

Change-Id: Ib160d46a5d810307bfcbc79853ce1a65b5b870b7

--- a/vp8/common/seg_common.c
+++ b/vp8/common/seg_common.c
@@ -107,4 +107,11 @@
              ~(1 << INTRA_FRAME) ) ? 1 : 0;
 }
 
+int get_seg_tx_type(MACROBLOCKD *xd, int segment_id)
+{
+    if ( segfeature_active(xd, segment_id, SEG_LVL_TRANSFORM) )
+        return get_segdata(xd, segment_id, SEG_LVL_TRANSFORM);
+    else
+        return TX_4X4;
+}
 // TBD? Functions to read and write segment data with range / validity checking
--- a/vp8/common/seg_common.h
+++ b/vp8/common/seg_common.h
@@ -55,6 +55,7 @@
 
 int check_segref_inter(MACROBLOCKD *xd, int segment_id);
 
+int get_seg_tx_type(MACROBLOCKD *xd, int segment_id);
 
 #endif /* __INC_SEG_COMMON_H__ */
 
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -78,7 +78,6 @@
     VP8_COMMON *const pc = & pbi->common;
     int segment_id = xd->mode_info_context->mbmi.segment_id;
 
-
     // Set the Q baseline allowing for any segment level adjustment
 //#if CONFIG_SEGFEATURES
     if ( segfeature_active( xd, segment_id, SEG_LVL_ALT_Q ) )
@@ -210,6 +209,11 @@
     MB_PREDICTION_MODE mode;
     int i;
 
+#if CONFIG_T8X8
+    int tx_type = get_seg_tx_type(xd, xd->mode_info_context->mbmi.segment_id);
+#endif
+
+
     if (xd->mode_info_context->mbmi.mb_skip_coeff)
     {
         vp8_reset_mb_tokens_context(xd);
@@ -223,8 +227,10 @@
             xd->block[i].eob = 0;
             xd->eobs[i] = 0;
         }
-        if (xd->mode_info_context->mbmi.segment_id >= 2)
+        if ( tx_type == TX_8X8 )
+        {
             eobtotal = vp8_decode_mb_tokens_8x8(pbi, xd);
+        }
         else
 #endif
             eobtotal = vp8_decode_mb_tokens(pbi, xd);
@@ -392,7 +398,7 @@
     else if (mode == SPLITMV)
     {
 #if CONFIG_T8X8
-        if(xd->mode_info_context->mbmi.segment_id >= 2)
+        if ( tx_type == TX_8X8 )
         {
             DEQUANT_INVOKE (&pbi->dequant, idct_add_y_block_8x8)
                 (xd->qcoeff, xd->block[0].dequant,
@@ -416,7 +422,7 @@
 
         /* do 2nd order transform on the dc block */
 #if CONFIG_T8X8
-        if(xd->mode_info_context->mbmi.segment_id >= 2)
+        if( tx_type == TX_8X8 )
         {
             DEQUANT_INVOKE(&pbi->dequant, block_8x8)(b);
 #ifdef DEC_DEBUG
@@ -474,7 +480,7 @@
         }
     }
 #if CONFIG_T8X8
-    if(xd->mode_info_context->mbmi.segment_id >= 2)
+    if( tx_type == TX_8X8 )
     {
         DEQUANT_INVOKE (&pbi->dequant, idct_add_uv_block_8x8)//
             (xd->qcoeff+16*16, xd->block[16].dequant,
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -247,6 +247,7 @@
                          -sse_4*log(sse_4))/log(2);
       }
     }
+
     if(variance_8[0]+variance_8[1]+variance_8[2]+variance_8[3])
       return (entropy_8[0]*variance_8[0]+
               entropy_8[1]*variance_8[1]+
@@ -1567,8 +1568,11 @@
     sum_intra_stats(cpi, x);
     vp8_tokenize_mb(cpi, &x->e_mbd, t);
 #if CONFIG_T8X8
-        if( x->e_mbd.mode_info_context->mbmi.segment_id >=2)
+        if ( get_seg_tx_type(&x->e_mbd,
+                             x->e_mbd.mode_info_context->mbmi.segment_id) )
+        {
             cpi->t8x8_count++;
+        }
         else
             cpi->t4x4_count++;
 #endif
@@ -1590,12 +1594,12 @@
     int intra_error = 0;
     int rate;
     int distortion;
-    int segment_id = xd->mode_info_context->mbmi.segment_id;
+    unsigned char *segment_id = &xd->mode_info_context->mbmi.segment_id;
 
     x->skip = 0;
 
     if (xd->segmentation_enabled)
-        x->encode_breakout = cpi->segment_encode_breakout[segment_id];
+        x->encode_breakout = cpi->segment_encode_breakout[*segment_id];
     else
         x->encode_breakout = cpi->oxcf.encode_breakout;
 
@@ -1657,11 +1661,11 @@
         if (cpi->cyclic_refresh_mode_enabled)
         {
             // Clear segment_id back to 0 if not coded (last frame 0,0)
-            if ( (segment_id == 1) &&
+            if ( (*segment_id == 1) &&
                  ( (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) ||
                    (xd->mode_info_context->mbmi.mode != ZEROMV) ) )
             {
-                xd->mode_info_context->mbmi.segment_id = 0;
+                *segment_id = 0;
 
                 /* segment_id changed, so update */
                 vp8cx_mb_init_quantizer(cpi, x);
@@ -1678,7 +1682,7 @@
                 statsfile = fopen("segmap2.stt", "a");
 
                 fprintf(statsfile, "%2d%2d%2d   ",
-                    xd->mode_info_context->mbmi.segment_id,
+                    *segment_id,
                     xd->mode_info_context->mbmi.ref_frame,
                     xd->mode_info_context->mbmi.mode );
 
@@ -1722,11 +1726,11 @@
     // probabilities. NOTE: At the moment we dont support custom trees
     // for the reference frame coding for each segment but this is a
     // possible future action.
-    if ( !segfeature_active( xd, segment_id, SEG_LVL_REF_FRAME ) ||
-         ( ( check_segref( xd, segment_id, INTRA_FRAME ) +
-             check_segref( xd, segment_id, LAST_FRAME ) +
-             check_segref( xd, segment_id, GOLDEN_FRAME ) +
-             check_segref( xd, segment_id, ALTREF_FRAME ) ) > 1 ) )
+    if ( !segfeature_active( xd, *segment_id, SEG_LVL_REF_FRAME ) ||
+         ( ( check_segref( xd, *segment_id, INTRA_FRAME ) +
+             check_segref( xd, *segment_id, LAST_FRAME ) +
+             check_segref( xd, *segment_id, GOLDEN_FRAME ) +
+             check_segref( xd, *segment_id, ALTREF_FRAME ) ) > 1 ) )
     {
         cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame]++;
     }
@@ -1747,7 +1751,7 @@
         {
 #if CONFIG_T8X8
             if (xd->segmentation_enabled)
-              xd->mode_info_context->mbmi.segment_id |= (vp8_8x8_selection_intra(x) << 1);
+                *segment_id |= (vp8_8x8_selection_intra(x) << 1);
 #endif
             vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
             vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
@@ -1760,7 +1764,7 @@
         int ref_fb_idx;
 #if CONFIG_T8X8
         if (xd->segmentation_enabled)
-          xd->mode_info_context->mbmi.segment_id |= (vp8_8x8_selection_inter(x) << 1);
+            *segment_id |= (vp8_8x8_selection_inter(x) << 1);
 #endif
 
         if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
@@ -1790,8 +1794,10 @@
 
     }
 #if CONFIG_T8X8
-    if (x->e_mbd.mode_info_context->mbmi.segment_id >=2)
+    if ( get_seg_tx_type( xd, *segment_id ) == TX_8X8 )
+    {
         cpi->t8x8_count++;
+    }
     else
         cpi->t4x4_count++;
 #endif
--- a/vp8/encoder/encodeintra.c
+++ b/vp8/encoder/encodeintra.c
@@ -97,11 +97,17 @@
 {
     BLOCK *b = &x->block[0];
 
+#if CONFIG_T8X8
+    int tx_type = get_seg_tx_type(&x->e_mbd,
+                                  x->e_mbd.mode_info_context->mbmi.segment_id);
+#endif
+
     RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mby)(&x->e_mbd);
 
     ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride);
+
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if( tx_type == TX_8X8 )
         vp8_transform_intra_mby_8x8(x);
     else
 #endif
@@ -108,7 +114,7 @@
     vp8_transform_intra_mby(x);
 
 #if  CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if(tx_type == TX_8X8)
       vp8_quantize_mby_8x8(x);
     else
 #endif
@@ -117,7 +123,7 @@
     if (x->optimize)
     {
 #if CONFIG_T8X8
-      if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+      if( tx_type == TX_8X8 )
         vp8_optimize_mby_8x8(x, rtcd);
       else
 #endif
@@ -125,7 +131,7 @@
     }
 
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if(tx_type == TX_8X8)
       vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
     else
 #endif
@@ -169,11 +175,16 @@
 
 void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
 {
+#if CONFIG_T8X8
+    int tx_type = get_seg_tx_type(&x->e_mbd,
+                                  x->e_mbd.mode_info_context->mbmi.segment_id);
+#endif
+
     RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mbuv)(&x->e_mbd);
 
     ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if(tx_type == TX_8X8)
         vp8_transform_mbuv_8x8(x);
     else
 #endif
@@ -180,7 +191,7 @@
         vp8_transform_mbuv(x);
 
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if(tx_type == TX_8X8)
         vp8_quantize_mbuv_8x8(x);
     else
 #endif
@@ -220,7 +231,7 @@
     if (x->optimize)
     {
 #if CONFIG_T8X8
-      if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+      if(tx_type == TX_8X8)
         vp8_optimize_mbuv_8x8(x, rtcd);
       else
 #endif
@@ -228,7 +239,7 @@
     }
 
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if(tx_type == TX_8X8)
       vp8_inverse_transform_mbuv_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
     else
 #endif
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -1247,12 +1247,17 @@
 
 void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
 {
+#if CONFIG_T8X8
+    int tx_type = get_seg_tx_type(&x->e_mbd,
+                                  x->e_mbd.mode_info_context->mbmi.segment_id);
+#endif
+
     vp8_build_inter_predictors_mb(&x->e_mbd);
 
     vp8_subtract_mb(rtcd, x);
 
 #if  CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if( tx_type == TX_8X8 )
          vp8_transform_mb_8x8(x);
     else
 #endif
@@ -1259,7 +1264,7 @@
          transform_mb(x);
 
 #if  CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if( tx_type == TX_8X8 )
         vp8_quantize_mb_8x8(x);
     else
 #endif
@@ -1268,7 +1273,7 @@
     if (x->optimize)
     {
 #if CONFIG_T8X8
-      if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+      if( tx_type == TX_8X8 )
         optimize_mb_8x8(x, rtcd);
       else
 #endif
@@ -1276,12 +1281,15 @@
     }
 
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if( tx_type == TX_8X8 )
         vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
     else
 #endif
         vp8_inverse_transform_mb(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) {
+
+#if CONFIG_T8X8
+    if( tx_type == TX_8X8 )
+    {
 #ifdef ENC_DEBUG
         if (enc_debug)
         {
@@ -1311,6 +1319,7 @@
         }
 #endif
     }
+#endif
 
     RECON_INVOKE(&rtcd->common->recon, recon_mb)
         (IF_RTCD(&rtcd->common->recon), &x->e_mbd);
@@ -1336,6 +1345,11 @@
 /* this function is used by first pass only */
 void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
 {
+#if CONFIG_T8X8
+    int tx_type = get_seg_tx_type(&x->e_mbd,
+                                  x->e_mbd.mode_info_context->mbmi.segment_id);
+#endif
+
     BLOCK *b = &x->block[0];
 
     vp8_build_inter16x16_predictors_mby(&x->e_mbd);
@@ -1343,7 +1357,7 @@
     ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride);
 
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if( tx_type == TX_8X8 )
           vp8_transform_mby_8x8(x);
     else
 #endif
@@ -1351,7 +1365,7 @@
 
     vp8_quantize_mby(x);
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if( tx_type == TX_8X8 )
           vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
     else
 #endif
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -481,16 +481,6 @@
                    (cpi->cq_target_quality > 16 ) ) ||
                  (cpi->ni_av_qi > 32);
 
-#if CONFIG_T8X8
-    // TODO
-    // For now 8x8TX mode just set segments up for 8x8 and 4x4 modes and exit.
-    //enable_segfeature(xd, 0, SEG_LVL_TRANSFORM);
-    //set_segdata( xd, 0, SEG_LVL_TRANSFORM, TX_4X4 );
-    //enable_segfeature(xd, 1, SEG_LVL_TRANSFORM);
-    //set_segdata( xd, 1, SEG_LVL_TRANSFORM, TX_8X8 );
-    return;
-#endif
-
     // For now at least dont enable seg features alongside cyclic refresh.
     if ( cpi->cyclic_refresh_mode_enabled ||
          (cpi->pass != 2) )
@@ -499,6 +489,19 @@
         vpx_memset( cpi->segmentation_map, 0, (cm->mb_rows * cm->mb_cols));
         return;
     }
+
+#if CONFIG_T8X8
+    // TODO
+    // For now 8x8TX mode just set segments up for 8x8 and 4x4 modes and exit.
+    enable_segfeature(xd, 0, SEG_LVL_TRANSFORM);
+    set_segdata( xd, 0, SEG_LVL_TRANSFORM, TX_4X4 );
+    enable_segfeature(xd, 2, SEG_LVL_TRANSFORM);
+    set_segdata( xd, 2, SEG_LVL_TRANSFORM, TX_8X8 );
+
+    // Turn on segmentation
+    vp8_enable_segmentation((VP8_PTR)cpi);
+    return;
+#endif
 
     // Disable and clear down for KF
     if ( cm->frame_type == KEY_FRAME  )
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -1041,12 +1041,17 @@
 static int rd_inter16x16_uv(VP8_COMP *cpi, MACROBLOCK *x, int *rate,
                             int *distortion, int fullpixel)
 {
+#if CONFIG_T8X8
+    int tx_type = get_seg_tx_type(&x->e_mbd,
+                                  x->e_mbd.mode_info_context->mbmi.segment_id);
+#endif
+
     vp8_build_inter16x16_predictors_mbuv(&x->e_mbd);
     ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), submbuv)(x->src_diff,
         x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
 
 #if CONFIG_T8X8
-    if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2)
+    if( tx_type == TX_8X8 )
        vp8_transform_mbuv_8x8(x);
     else
 #endif
--- a/vp8/encoder/tokenize.c
+++ b/vp8/encoder/tokenize.c
@@ -479,6 +479,10 @@
     int has_y2_block;
     int b;
 
+#if CONFIG_T8X8
+    int tx_type = get_seg_tx_type(x, x->mode_info_context->mbmi.segment_id);
+#endif
+
 //#if CONFIG_SEGFEATURES
     // If the MB is going to be skipped because of a segment level flag
     // exclude this from the skip count stats used to calculate the
@@ -502,7 +506,7 @@
 
     x->mode_info_context->mbmi.mb_skip_coeff =
 #if CONFIG_T8X8
-        (x->mode_info_context->mbmi.segment_id >= 2 ?
+        (( tx_type == TX_8X8 ) ?
          mb_is_skippable_8x8(x) :
          mb_is_skippable(x, has_y2_block));
 #else
@@ -516,7 +520,7 @@
         if (!cpi->common.mb_no_coeff_skip)
         {
 #if CONFIG_T8X8
-            if (x->mode_info_context->mbmi.segment_id >= 2)
+            if ( tx_type == TX_8X8 )
                 vp8_stuff_mb_8x8(cpi, x, t) ;
             else
 #endif
@@ -536,7 +540,7 @@
     if(has_y2_block)
     {
 #if CONFIG_T8X8
-        if (x->mode_info_context->mbmi.segment_id >= 2)
+        if ( tx_type == TX_8X8 )
         {
             ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context;
             ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context;
@@ -551,7 +555,7 @@
 
     }
 #if CONFIG_T8X8
-    if (x->mode_info_context->mbmi.segment_id >= 2)
+    if ( tx_type == TX_8X8 )
     {
         ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context;
         ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context;