vaapipostproc: add skin tone enhancement
authorVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>
Fri, 22 May 2015 16:13:25 +0000 (18:13 +0200)
committerVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>
Mon, 8 Jun 2015 16:00:05 +0000 (18:00 +0200)
Added the 'skin-tone-enhancement' property to vaapostproc.

https://bugzilla.gnome.org/show_bug.cgi?id=744088

gst-libs/gst/vaapi/gstvaapifilter.c
gst-libs/gst/vaapi/gstvaapifilter.h
gst/vaapi/gstvaapipostproc.c
gst/vaapi/gstvaapipostproc.h

index 67cd539..3ca4b4b 100644 (file)
@@ -278,6 +278,7 @@ enum
   PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST,
   PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING,
   PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING,
+  PROP_SKINTONE = GST_VAAPI_FILTER_OP_SKINTONE,
 
   N_PROPERTIES
 };
@@ -399,6 +400,16 @@ init_properties (void)
       "Scaling method to use",
       GST_VAAPI_TYPE_SCALE_METHOD,
       DEFAULT_SCALING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+  /**
+   * GstVaapiFilter:skin-tone-enhancement:
+   *
+   * Apply the skin tone enhancement algorithm.
+   */
+  g_properties[PROP_SKINTONE] = g_param_spec_boolean ("skin-tone-enhancement",
+      "Skin tone enhancement",
+      "Apply the skin tone enhancement algorithm",
+      FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 }
 
 static void
@@ -447,6 +458,10 @@ op_data_new (GstVaapiFilterOp op, GParamSpec * pspec)
       op_data->va_cap_size = sizeof (VAProcFilterCap);
       op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer);
       break;
+    case GST_VAAPI_FILTER_OP_SKINTONE:
+      op_data->va_type = VAProcFilterSkinToneEnhancement;
+      op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer);
+      break;
     case GST_VAAPI_FILTER_OP_HUE:
       op_data->va_subtype = VAProcColorBalanceHue;
       goto op_colorbalance;
@@ -628,6 +643,11 @@ get_operations_ordered (GstVaapiFilter * filter, GPtrArray * default_ops)
       if (op_data->va_type != va_type)
         continue;
 
+      if (op_data->va_cap_size == 0) { /* no caps, like skintone */
+        g_ptr_array_add (ops, op_data_ref (op_data));
+        continue;
+      }
+
       if (!filter_caps) {
         filter_caps = vpp_get_filter_caps (filter, va_type,
             op_data->va_cap_size, &num_filter_caps);
@@ -878,6 +898,46 @@ op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
   return success;
 }
 
+/* Update skin tone enhancement */
+#if USE_VA_VPP
+gboolean
+op_set_skintone_unlocked (GstVaapiFilter * filter,
+   GstVaapiFilterOpData * op_data, gboolean value)
+{
+  VAProcFilterParameterBuffer *buf;
+
+  if (!op_data || !op_ensure_buffer (filter, op_data))
+    return FALSE;
+
+  op_data->is_enabled = value;
+  if (!op_data->is_enabled)
+    return TRUE;
+
+  buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
+  if (!buf)
+    return FALSE;
+  buf->type = op_data->va_type;
+  buf->value = 0;
+  vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
+  return TRUE;
+}
+#endif
+
+static inline gboolean
+op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
+   gboolean enhance)
+{
+  gboolean success = FALSE;
+
+#if USE_VA_VPP
+  GST_VAAPI_DISPLAY_LOCK (filter->display);
+  success = op_set_skintone_unlocked (filter, op_data, enhance);
+  GST_VAAPI_DISPLAY_UNLOCK (filter->display);
+#endif
+  return success;
+}
+
+
 static gboolean
 deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces)
 {
@@ -1300,6 +1360,10 @@ gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op,
     case GST_VAAPI_FILTER_OP_SCALING:
       return gst_vaapi_filter_set_scaling (filter, value ?
           g_value_get_enum (value) : DEFAULT_SCALING);
+    case GST_VAAPI_FILTER_OP_SKINTONE:
+      return op_set_skintone (filter, op_data,
+          (value ? g_value_get_boolean (value) :
+              G_PARAM_SPEC_BOOLEAN (op_data->pspec)->default_value));
     default:
       break;
   }
@@ -1789,3 +1853,23 @@ gst_vaapi_filter_set_scaling (GstVaapiFilter * filter,
   filter->scale_method = method;
   return TRUE;
 }
+
+/**
+ * gst_vaapi_filter_set_skintone:
+ * @filter: a #GstVaapiFilter
+ * @enhance: %TRUE if enable the skin tone enhancement algorithm
+ *
+ * Applies the skin tone enhancement algorithm.
+ *
+ * Return value: %TRUE if the operation is supported, %FALSE
+ * otherwise.
+  **/
+gboolean
+gst_vaapi_filter_set_skintone (GstVaapiFilter * filter,
+    gboolean enhance)
+{
+  g_return_val_if_fail (filter != NULL, FALSE);
+
+  return op_set_skintone (filter,
+      find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE), enhance);
+}
index 0f25a86..6364803 100644 (file)
@@ -41,6 +41,7 @@ typedef struct _GstVaapiFilterOpInfo            GstVaapiFilterOpInfo;
  * @GST_VAAPI_FILTER_OP_BRIGHTNESS: Change brightness (float).
  * @GST_VAAPI_FILTER_OP_CONTRAST: Change contrast (float).
  * @GST_VAAPI_FILTER_OP_SCALING: Change scaling method (#GstVaapiScaleMethod).
+ * @GST_VAAPI_FILTER_OP_SKINTONE: Skin tone enhancement (bool).
  *
  * The set of operations that could be applied to the filter.
  */
@@ -55,6 +56,7 @@ typedef enum {
   GST_VAAPI_FILTER_OP_CONTRAST,
   GST_VAAPI_FILTER_OP_DEINTERLACING,
   GST_VAAPI_FILTER_OP_SCALING,
+  GST_VAAPI_FILTER_OP_SKINTONE,
 } GstVaapiFilterOp;
 
 /**
@@ -240,4 +242,8 @@ gboolean
 gst_vaapi_filter_set_scaling (GstVaapiFilter * filter,
     GstVaapiScaleMethod method);
 
+gboolean
+gst_vaapi_filter_set_skintone (GstVaapiFilter * filter,
+    gboolean enhance);
+
 #endif /* GST_VAAPI_FILTER_H */
index 1b8acb9..baa5a73 100644 (file)
@@ -104,6 +104,7 @@ enum
   PROP_BRIGHTNESS,
   PROP_CONTRAST,
   PROP_SCALE_METHOD,
+  PROP_SKIN_TONE_ENHANCEMENT,
 };
 
 #define DEFAULT_FORMAT                  GST_VIDEO_FORMAT_ENCODED
@@ -522,6 +523,11 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf,
       !gst_vaapi_filter_set_scaling (postproc->filter, postproc->scale_method))
     return GST_FLOW_NOT_SUPPORTED;
 
+  if ((postproc->flags & GST_VAAPI_POSTPROC_FLAG_SKINTONE) &&
+      !gst_vaapi_filter_set_skintone (postproc->filter,
+           postproc->skintone_enhance))
+    return GST_FLOW_NOT_SUPPORTED;
+
   inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf);
   if (!inbuf_meta)
     goto error_invalid_buffer;
@@ -1352,6 +1358,10 @@ gst_vaapipostproc_set_property (GObject * object,
       postproc->scale_method = g_value_get_enum (value);
       postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SCALE;
       break;
+    case PROP_SKIN_TONE_ENHANCEMENT:
+      postproc->skintone_enhance = g_value_get_boolean (value);
+      postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SKINTONE;
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1404,6 +1414,9 @@ gst_vaapipostproc_get_property (GObject * object,
     case PROP_SCALE_METHOD:
       g_value_set_enum (value, postproc->scale_method);
       break;
+    case PROP_SKIN_TONE_ENHANCEMENT:
+      g_value_set_boolean (value, postproc->skintone_enhance);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1619,6 +1632,16 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass)
     g_object_class_install_property (object_class,
         PROP_SCALE_METHOD, filter_op->pspec);
 
+  /**
+   * GstVaapiPostproc:skin-tone-enhancement:
+   *
+   * Apply the skin tone enhancement algorithm.
+   */
+  filter_op = find_filter_op (filter_ops, GST_VAAPI_FILTER_OP_SKINTONE);
+  if (filter_op)
+    g_object_class_install_property (object_class,
+        PROP_SKIN_TONE_ENHANCEMENT, filter_op->pspec);
+
   g_ptr_array_unref (filter_ops);
 }
 
index a74043d..dc50fb3 100644 (file)
@@ -86,6 +86,7 @@ typedef enum
  * @GST_VAAPI_POSTPROC_FLAG_DEINTERLACE: Deinterlacing.
  * @GST_VAAPI_POSTPROC_FLAG_SIZE: Video scaling.
  * @GST_VAAPI_POSTPROC_FLAG_SCALE: Video scaling mode.
+ * @GST_VAAPI_POSTPROC_FLAG_SKINTONE: Skin tone enhancement.
  *
  * The set of operations that are to be performed for each frame.
  */
@@ -100,6 +101,7 @@ typedef enum
   GST_VAAPI_POSTPROC_FLAG_CONTRAST    = 1 << GST_VAAPI_FILTER_OP_CONTRAST,
   GST_VAAPI_POSTPROC_FLAG_DEINTERLACE = 1 << GST_VAAPI_FILTER_OP_DEINTERLACING,
   GST_VAAPI_POSTPROC_FLAG_SCALE       = 1 << GST_VAAPI_FILTER_OP_SCALING,
+  GST_VAAPI_POSTPROC_FLAG_SKINTONE    = 1 << GST_VAAPI_FILTER_OP_SKINTONE,
 
   /* Additional custom flags */
   GST_VAAPI_POSTPROC_FLAG_CUSTOM      = 1 << 20,
@@ -164,6 +166,8 @@ struct _GstVaapiPostproc
   gfloat brightness;
   gfloat contrast;
 
+  gboolean skintone_enhance;
+
   guint get_va_surfaces:1;
   guint has_vpp:1;
   guint use_vpp:1;