shithub: libvpx

Download patch

ref: f1a300acc4e2af7f4407492a59a7063e6d2ad37d
parent: 755b3daf90ee0858fb98124bc77b1db164eef335
author: Jerome Jiang <jianj@google.com>
date: Wed May 31 10:57:10 EDT 2017

vp8: Clean up skin detection.

Use only the average of center 2x2 pixels in vp8.

Change-Id: I2b23ff19a90827226273e0fca49e90c734eda59b

--- a/vp8/common/skin_detection.c
+++ b/vp8/common/skin_detection.c
@@ -30,7 +30,8 @@
 static const int y_high = 220;
 
 // Evaluates the Mahalanobis distance measure for the input CbCr values.
-static int evaluate_skin_color_difference(int cb, int cr, int idx) {
+static int evaluate_skin_color_difference(const int cb, const int cr,
+                                          const int idx) {
   const int cb_q6 = cb << 6;
   const int cr_q6 = cr << 6;
   const int cb_diff_q12 =
@@ -49,7 +50,7 @@
 }
 
 // Checks if the input yCbCr values corresponds to skin color.
-int skin_pixel(int y, int cb, int cr, int motion) {
+int skin_pixel(const int y, const int cb, const int cr, const int motion) {
   if (y < y_low || y > y_high) {
     return 0;
   } else {
@@ -84,14 +85,14 @@
 }
 
 int compute_skin_block(const uint8_t *y, const uint8_t *u, const uint8_t *v,
-                       int stride, int strideuv, int consec_zeromv,
-                       int curr_motion_magn) {
+                       const int stride, const int strideuv,
+                       const int consec_zeromv, const int curr_motion_magn) {
   // No skin if block has been zero/small motion for long consecutive time.
   if (consec_zeromv > 60 && curr_motion_magn == 0) {
     return 0;
   } else {
     int motion = 1;
-    // Take center pixel in block to determine is_skin.
+    // Take the average of center 2x2 pixels.
     const int ysource = (y[7 * stride + 7] + y[7 * stride + 8] +
                          y[8 * stride + 7] + y[8 * stride + 8]) >>
                         2;
@@ -118,8 +119,6 @@
   const int src_ystride = cpi->Source->y_stride;
   const int src_uvstride = cpi->Source->uv_stride;
 
-  // Use center pixel or average of center 2x2 pixels.
-  const int mode_filter = 0;
   YV12_BUFFER_CONFIG skinmap;
   memset(&skinmap, 0, sizeof(skinmap));
   if (vp8_yv12_alloc_frame_buffer(&skinmap, cm->Width, cm->Height,
@@ -132,42 +131,21 @@
   // Loop through blocks and set skin map based on center pixel of block.
   // Set y to white for skin block, otherwise set to source with gray scale.
   // Ignore rightmost/bottom boundary blocks.
-  for (mb_row = 0; mb_row < cm->mb_rows - 1; mb_row += 1) {
+  for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 1) {
     num_bl = 0;
-    for (mb_col = 0; mb_col < cm->mb_cols - 1; mb_col += 1) {
+    for (mb_col = 0; mb_col < cm->mb_cols; mb_col += 1) {
       int is_skin = 0;
-      if (mode_filter == 1) {
-        // Use 2x2 average at center.
-        uint8_t ysource = src_y[8 * src_ystride + 8];
-        uint8_t usource = src_u[4 * src_uvstride + 4];
-        uint8_t vsource = src_v[4 * src_uvstride + 4];
-        const uint8_t ysource2 = src_y[(8 + 1) * src_ystride + 8];
-        const uint8_t usource2 = src_u[(4 + 1) * src_uvstride + 4];
-        const uint8_t vsource2 = src_v[(4 + 1) * src_uvstride + 4];
-        const uint8_t ysource3 = src_y[8 * src_ystride + (8 + 1)];
-        const uint8_t usource3 = src_u[4 * src_uvstride + (4 + 1)];
-        const uint8_t vsource3 = src_v[4 * src_uvstride + (4 + 1)];
-        const uint8_t ysource4 = src_y[(8 + 1) * src_ystride + (8 + 1)];
-        const uint8_t usource4 = src_u[(4 + 1) * src_uvstride + (4 + 1)];
-        const uint8_t vsource4 = src_v[(4 + 1) * src_uvstride + (4 + 1)];
-        ysource = (ysource + ysource2 + ysource3 + ysource4) >> 2;
-        usource = (usource + usource2 + usource3 + usource4) >> 2;
-        vsource = (vsource + vsource2 + vsource3 + vsource4) >> 2;
-        is_skin = skin_pixel(ysource, usource, vsource, 1);
-      } else {
-        int consec_zeromv = 0;
-        const int bl_index = mb_row * cm->mb_cols + mb_col;
-        const int bl_index1 = bl_index + 1;
-        const int bl_index2 = bl_index + cm->mb_cols;
-        const int bl_index3 = bl_index2 + 1;
-        consec_zeromv =
-            VPXMIN(cpi->consec_zero_last[bl_index],
-                   VPXMIN(cpi->consec_zero_last[bl_index1],
-                          VPXMIN(cpi->consec_zero_last[bl_index2],
-                                 cpi->consec_zero_last[bl_index3])));
-        is_skin = compute_skin_block(src_y, src_u, src_v, src_ystride,
-                                     src_uvstride, consec_zeromv, 0);
-      }
+      int consec_zeromv = 0;
+      const int bl_index = mb_row * cm->mb_cols + mb_col;
+      const int bl_index1 = bl_index + 1;
+      const int bl_index2 = bl_index + cm->mb_cols;
+      const int bl_index3 = bl_index2 + 1;
+      consec_zeromv = VPXMIN(cpi->consec_zero_last[bl_index],
+                             VPXMIN(cpi->consec_zero_last[bl_index1],
+                                    VPXMIN(cpi->consec_zero_last[bl_index2],
+                                           cpi->consec_zero_last[bl_index3])));
+      is_skin = compute_skin_block(src_y, src_u, src_v, src_ystride,
+                                   src_uvstride, consec_zeromv, 0);
       for (i = 0; i < 16; i++) {
         for (j = 0; j < 16; j++) {
           if (is_skin)