]> granicus.if.org Git - libvpx/commitdiff
Segment Feature Signaling
authorPaul Wilkins <paulwilkins@google.com>
Wed, 14 Sep 2011 17:20:25 +0000 (18:20 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Thu, 15 Sep 2011 09:19:09 +0000 (10:19 +0100)
Plumbing for tuning new segment features on and off.

Change-Id: If86cd6f103296b73030e8af7cf85c5b9bbffdbaf

vp8/common/blockd.h
vp8/common/loopfilter.c
vp8/decoder/decodframe.c
vp8/decoder/threading.c
vp8/encoder/bitstream.c
vp8/encoder/ethreading.c
vp8/encoder/onyx_if.c
vp8/encoder/onyx_int.h
vp8/encoder/picklpf.c
vp8/encoder/quantize.c

index 72f848c03436f80af576f047b8eb6276c310253a..65ad435592947a690a26873ba5785a81ff13d70e 100644 (file)
@@ -254,6 +254,9 @@ typedef struct MacroBlockD
 
     // Segment features
     signed char segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];
+#if CONFIG_SEGFEATURES
+    unsigned int segment_feature_mask[MAX_MB_SEGMENTS];
+#endif
 
     /* mode_based Loop filter adjustment */
     unsigned char mode_ref_lf_delta_enabled;
index 346a43560db01f8ef0f063ad75516a3912839a37..a8855531ec127d1d4cadc7c3de63e48a18c438c1 100644 (file)
@@ -215,8 +215,14 @@ void vp8_loop_filter_frame_init(VP8_COMMON *cm,
         int lvl_seg = default_filt_lvl;
         int lvl_ref, lvl_mode;
 
-        /* Note the baseline filter values for each segment */
-        if (mbd->segmentation_enabled)
+
+        // Set the baseline filter values for each segment
+#if CONFIG_SEGFEATURES
+        if ( mbd->segmentation_enabled &&
+             ( mbd->segment_feature_mask[seg] & (1 << SEG_LVL_ALT_LF) ) )
+#else
+        if ( mbd->segmentation_enabled )
+#endif
         {
             /* Abs value */
             if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
index 33102f2747584407d0e19214340b5f706aa58cff..69f2905d44ff70de8263da052bac519062e00e0c 100644 (file)
@@ -72,21 +72,27 @@ void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd)
 {
     int i;
     int QIndex;
-    MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
     VP8_COMMON *const pc = & pbi->common;
+    int segment_id = xd->mode_info_context->mbmi.segment_id;
 
-    /* Decide whether to use the default or alternate baseline Q value. */
-    if (xd->segmentation_enabled)
+
+    // Set the Q baseline allowing for any segment level adjustment
+#if CONFIG_SEGFEATURES
+    if ( xd->segmentation_enabled &&
+         ( xd->segment_feature_mask[segment_id] & (1 << SEG_LVL_ALT_Q) ) )
+#else
+    if ( xd->segmentation_enabled )
+#endif
     {
         /* Abs Value */
         if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)
-            QIndex = xd->segment_feature_data[mbmi->segment_id][SEG_LVL_ALT_Q];
+            QIndex = xd->segment_feature_data[segment_id][SEG_LVL_ALT_Q];
 
         /* Delta Value */
         else
         {
             QIndex = pc->base_qindex +
-                xd->segment_feature_data[mbmi->segment_id][SEG_LVL_ALT_Q];
+                xd->segment_feature_data[segment_id][SEG_LVL_ALT_Q];
             QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;    /* Clamp to valid range */
         }
     }
@@ -727,8 +733,15 @@ static void init_frame(VP8D_COMP *pbi)
         vp8_default_coef_probs(pc);
         vp8_kf_default_bmode_probs(pc->kf_bmode_prob);
 
-        /* reset the segment feature data to 0 with delta coding (Default state). */
-        vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
+        // Reset the segment feature data to the default stats:
+        // Features disabled, 0, with delta coding (Default state).
+#if CONFIG_SEGFEATURES
+        vpx_memset(xd->segment_feature_mask, 0,
+                   sizeof(xd->segment_feature_mask));
+#endif
+        vpx_memset(xd->segment_feature_data, 0,
+                   sizeof(xd->segment_feature_data));
+
         xd->mb_segement_abs_delta = SEGMENT_DELTADATA;
 
         /* reset the mode ref deltasa for loop filter */
@@ -937,9 +950,15 @@ int vp8_decode_frame(VP8D_COMP *pbi)
         {
             xd->mb_segement_abs_delta = (unsigned char)vp8_read_bit(bc);
 
-            vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
+            // Clear down feature data structure
+            vpx_memset(xd->segment_feature_data, 0,
+                       sizeof(xd->segment_feature_data));
 
 #if CONFIG_SEGFEATURES
+            // Clear down feature enabled masks
+            vpx_memset(xd->segment_feature_mask, 0,
+                       sizeof(xd->segment_feature_mask));
+
             // For each segmentation...
             for (j = 0; j < MAX_MB_SEGMENTS; j++)
             {
@@ -955,16 +974,23 @@ int vp8_decode_frame(VP8D_COMP *pbi)
                 for (j = 0; j < MAX_MB_SEGMENTS; j++)
                 {
 #endif
-                    /* Frame level data */
+                    // Is the feature enabled
                     if (vp8_read_bit(bc))
                     {
+#if CONFIG_SEGFEATURES
+                        // Update the feature data and mask
+                        xd->segment_feature_mask[j] |= (1 << i);
+#endif
+
                         xd->segment_feature_data[j][i] = (signed char)vp8_read_literal(bc, mb_feature_data_bits[i]);
 
                         if (vp8_read_bit(bc))
                             xd->segment_feature_data[j][i] = -xd->segment_feature_data[j][i];
                     }
                     else
+                    {
                         xd->segment_feature_data[j][i] = 0;
+                    }
                 }
             }
         }
index fdde04a88093a30f6f98a68f8505e15ae7e91355..b60b7e8bffcde05a04f1de53ccb0cc1f11ed20a0 100644 (file)
@@ -66,7 +66,15 @@ static void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_D
         vp8_build_block_doffsets(mbd);
         mbd->segmentation_enabled    = xd->segmentation_enabled;
         mbd->mb_segement_abs_delta     = xd->mb_segement_abs_delta;
-        vpx_memcpy(mbd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
+
+        vpx_memcpy(mbd->segment_feature_data,
+                   xd->segment_feature_data,
+                   sizeof(xd->segment_feature_data));
+#if CONFIG_SEGFEATURES
+        vpx_memcpy(mbd->segment_feature_mask,
+                   xd->segment_feature_mask,
+                   sizeof(xd->segment_feature_mask));
+#endif
 
         /*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/
         vpx_memcpy(mbd->ref_lf_deltas, xd->ref_lf_deltas, sizeof(xd->ref_lf_deltas));
index c4901bf7ba37e954eedbfd32f31feb7b2b15e208..e872a433d39f3f31c465c784ce5492e163d08877 100644 (file)
@@ -1862,11 +1862,18 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
                 {
                     Data = xd->segment_feature_data[j][i];
 
-                    // Frame level data
+#if CONFIG_SEGFEATURES
+                    // If the feature is enabled...
+                    if ( xd->segment_feature_mask[j] & (0x01 << i))
+#else
+                    // If the feature is enabled...Indicated by non zero
+                    // value in VP8
                     if (Data)
+#endif
                     {
                         vp8_write_bit(bc, 1);
 
+                        // Encode the relevant feature data
                         if (Data < 0)
                         {
                             Data = - Data;
index 6b9dff8d997a732001b408aa95a18ee80333342f..4820729eaf6058cc7f4a3e5ca33a7889c748189f 100644 (file)
@@ -395,7 +395,16 @@ static void setup_mbby_copy(MACROBLOCK *mbdst, MACROBLOCK *mbsrc)
         zd->subpixel_predict16x16    = xd->subpixel_predict16x16;
         zd->segmentation_enabled     = xd->segmentation_enabled;
         zd->mb_segement_abs_delta      = xd->mb_segement_abs_delta;
-        vpx_memcpy(zd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
+
+        vpx_memcpy(zd->segment_feature_data,
+                   xd->segment_feature_data,
+                   sizeof(xd->segment_feature_data));
+
+#if CONFIG_SEGFEATURES
+        vpx_memcpy(zd->segment_feature_mask,
+                   xd->segment_feature_mask,
+                   sizeof(xd->segment_feature_mask));
+#endif
 
         for (i = 0; i < 25; i++)
         {
index 866f542b8d634f1e08b6d18e2243114352434f85..c97e108252c70a604c755cfac6ec45dcacc991d3 100644 (file)
@@ -317,23 +317,29 @@ extern FILE *vpxlogc;
 
 static void setup_features(VP8_COMP *cpi)
 {
+    MACROBLOCKD *xd = &cpi->mb.e_mbd;
+
     // Set up default state for MB feature flags
 #if CONFIG_SEGMENTATION
-    cpi->mb.e_mbd.segmentation_enabled = 1;
+    xd->segmentation_enabled = 1;
 #else
-    cpi->mb.e_mbd.segmentation_enabled = 0;
+    xd->segmentation_enabled = 0;
 #endif
-    cpi->mb.e_mbd.update_mb_segmentation_map = 0;
-    cpi->mb.e_mbd.update_mb_segmentation_data = 0;
-    vpx_memset(cpi->mb.e_mbd.mb_segment_tree_probs, 255, sizeof(cpi->mb.e_mbd.mb_segment_tree_probs));
-    vpx_memset(cpi->mb.e_mbd.segment_feature_data, 0, sizeof(cpi->mb.e_mbd.segment_feature_data));
+    xd->update_mb_segmentation_map = 0;
+    xd->update_mb_segmentation_data = 0;
+    vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
+    vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
 
-    cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 0;
-    cpi->mb.e_mbd.mode_ref_lf_delta_update = 0;
-    vpx_memset(cpi->mb.e_mbd.ref_lf_deltas, 0, sizeof(cpi->mb.e_mbd.ref_lf_deltas));
-    vpx_memset(cpi->mb.e_mbd.mode_lf_deltas, 0, sizeof(cpi->mb.e_mbd.mode_lf_deltas));
-    vpx_memset(cpi->mb.e_mbd.last_ref_lf_deltas, 0, sizeof(cpi->mb.e_mbd.ref_lf_deltas));
-    vpx_memset(cpi->mb.e_mbd.last_mode_lf_deltas, 0, sizeof(cpi->mb.e_mbd.mode_lf_deltas));
+#if CONFIG_SEGFEATURES
+    vpx_memset(xd->segment_feature_mask, 0, sizeof(xd->segment_feature_mask));
+#endif
+
+    xd->mode_ref_lf_delta_enabled = 0;
+    xd->mode_ref_lf_delta_update = 0;
+    vpx_memset(xd->ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas));
+    vpx_memset(xd->mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas));
+    vpx_memset(xd->last_ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas));
+    vpx_memset(xd->last_mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas));
 
     set_default_lf_deltas(cpi);
 
@@ -439,7 +445,14 @@ static void set_segment_data(VP8_PTR ptr, signed char *feature_data, unsigned ch
     VP8_COMP *cpi = (VP8_COMP *)(ptr);
 
     cpi->mb.e_mbd.mb_segement_abs_delta = abs_delta;
-    vpx_memcpy(cpi->segment_feature_data, feature_data, sizeof(cpi->segment_feature_data));
+    vpx_memcpy(cpi->segment_feature_data, feature_data,
+               sizeof(cpi->segment_feature_data));
+
+#if CONFIG_SEGFEATURES
+    // TBD ?? Set the feature mask
+    // vpx_memset(xd->segment_feature_mask, 0, sizeof(xd->segment_feature_mask));
+#endif
+
 }
 
 
index b01392c8edb49b8836a269acfe9ff219d86e191c..00e7788f90a1146d6d4d859b7d63ba4b302281ae 100644 (file)
@@ -479,6 +479,9 @@ typedef struct VP8_COMP
 
     // Segment data (can be deltas or absolute values)
     signed char segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];
+#if CONFIG_SEGFEATURES
+unsigned int segment_feature_mask[MAX_MB_SEGMENTS];
+#endif
 
     // segment threashold for encode breakout
     int  segment_encode_breakout[MAX_MB_SEGMENTS];
index 0585d66e2c0425e4043bc73ac558b8f1176b127b..c6c5ec056a18a7d23480bfb698bb5892985bd97f 100644 (file)
@@ -257,12 +257,19 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
 void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val)
 {
     MACROBLOCKD *mbd = &cpi->mb.e_mbd;
-    (void) filt_val;
+    int i;
 
-    mbd->segment_feature_data[0][SEG_LVL_ALT_LF] = cpi->segment_feature_data[0][SEG_LVL_ALT_LF];
-    mbd->segment_feature_data[1][SEG_LVL_ALT_LF] = cpi->segment_feature_data[1][SEG_LVL_ALT_LF];
-    mbd->segment_feature_data[2][SEG_LVL_ALT_LF] = cpi->segment_feature_data[2][SEG_LVL_ALT_LF];
-    mbd->segment_feature_data[3][SEG_LVL_ALT_LF] = cpi->segment_feature_data[3][SEG_LVL_ALT_LF];
+    for ( i = 0; i < MAX_MB_SEGMENTS;  i++ )
+    {
+        mbd->segment_feature_data[i][SEG_LVL_ALT_LF] =
+            cpi->segment_feature_data[i][SEG_LVL_ALT_LF];
+
+#if CONFIG_SEGFEATURES
+        mbd->segment_feature_mask[i] &= ~(1 << SEG_LVL_ALT_LF);
+        mbd->segment_feature_mask[i] |=
+            cpi->segment_feature_mask[i] & (1 << SEG_LVL_ALT_LF);
+#endif
+    }
 }
 
 void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
index 13009bb3f1b2f99d1abbf8463ba7c4accd4f8044..156989fc322471c1fa5603dd2ed4cd3c6d3817cd 100644 (file)
@@ -1167,19 +1167,28 @@ void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x)
     int QIndex;
     MACROBLOCKD *xd = &x->e_mbd;
     int zbin_extra;
+    int segment_id = xd->mode_info_context->mbmi.segment_id;
 
-    // Select the baseline MB Q index.
-    if (xd->segmentation_enabled)
+    // Select the baseline MB Q index allowing for any segment level change.
+#if CONFIG_SEGFEATURES
+    if ( xd->segmentation_enabled &&
+         ( xd->segment_feature_mask[segment_id] & (0x01 << SEG_LVL_ALT_Q) ) )
+#else
+    if ( xd->segmentation_enabled )
+#endif
     {
         // Abs Value
         if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)
+            QIndex = xd->segment_feature_data[segment_id][SEG_LVL_ALT_Q];
 
-            QIndex = xd->segment_feature_data[xd->mode_info_context->mbmi.segment_id][SEG_LVL_ALT_Q];
         // Delta Value
         else
         {
-            QIndex = cpi->common.base_qindex + xd->segment_feature_data[xd->mode_info_context->mbmi.segment_id][SEG_LVL_ALT_Q];
-            QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;    // Clamp to valid range
+            QIndex = cpi->common.base_qindex +
+                     xd->segment_feature_data[segment_id][SEG_LVL_ALT_Q];
+
+            // Clamp to valid range
+            QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;
         }
     }
     else
@@ -1294,6 +1303,7 @@ void vp8_set_quantizer(struct VP8_COMP *cpi, int Q)
     MACROBLOCKD *mbd = &cpi->mb.e_mbd;
     int update = 0;
     int new_delta_q;
+    int i;
     cm->base_qindex = Q;
 
     /* if any of the delta_q values are changing update flag has to be set */
@@ -1315,11 +1325,18 @@ void vp8_set_quantizer(struct VP8_COMP *cpi, int Q)
     cm->y2dc_delta_q = new_delta_q;
 
 
-    // Set Segment specific quatizers
-    mbd->segment_feature_data[0][SEG_LVL_ALT_Q] = cpi->segment_feature_data[0][SEG_LVL_ALT_Q];
-    mbd->segment_feature_data[1][SEG_LVL_ALT_Q] = cpi->segment_feature_data[1][SEG_LVL_ALT_Q];
-    mbd->segment_feature_data[2][SEG_LVL_ALT_Q] = cpi->segment_feature_data[2][SEG_LVL_ALT_Q];
-    mbd->segment_feature_data[3][SEG_LVL_ALT_Q] = cpi->segment_feature_data[3][SEG_LVL_ALT_Q];
+    // Set Segment specific quatizers if enabled
+    for ( i = 0; i < MAX_MB_SEGMENTS;  i++ )
+    {
+        mbd->segment_feature_data[i][SEG_LVL_ALT_Q] =
+            cpi->segment_feature_data[i][SEG_LVL_ALT_Q];
+
+#if CONFIG_SEGFEATURES
+        mbd->segment_feature_mask[i] &= ~(1 << SEG_LVL_ALT_Q);
+        mbd->segment_feature_mask[i] |=
+            cpi->segment_feature_mask[i] & (1 << SEG_LVL_ALT_Q);
+#endif
+    }
 
     /* quantizer has to be reinitialized for any delta_q changes */
     if(update)