vaapipostproc: enable HDR10 tone mapping
authorU. Artie Eoff <ullysses.a.eoff@intel.com>
Thu, 13 Feb 2020 17:43:38 +0000 (09:43 -0800)
committerU. Artie Eoff <ullysses.a.eoff@intel.com>
Fri, 3 Apr 2020 16:23:32 +0000 (09:23 -0700)
gst/vaapi/gstvaapipostproc.c
gst/vaapi/gstvaapipostproc.h

index 990a9de..16efffe 100644 (file)
@@ -129,12 +129,37 @@ enum
   PROP_CROP_RIGHT,
   PROP_CROP_TOP,
   PROP_CROP_BOTTOM,
+  PROP_HDR_TONE_MAP,
 #ifndef GST_REMOVE_DEPRECATED
   PROP_SKIN_TONE_ENHANCEMENT,
 #endif
   PROP_SKIN_TONE_ENHANCEMENT_LEVEL,
 };
 
+#define GST_VAAPI_TYPE_HDR_TONE_MAP \
+    gst_vaapi_hdr_tone_map_get_type()
+
+static GType
+gst_vaapi_hdr_tone_map_get_type (void)
+{
+  static gsize g_type = 0;
+
+  static const GEnumValue enum_values[] = {
+    {GST_VAAPI_HDR_TONE_MAP_AUTO,
+        "Auto detection", "auto"},
+    {GST_VAAPI_HDR_TONE_MAP_DISABLED,
+        "Disable HDR tone mapping", "disabled"},
+    {0, NULL, NULL},
+  };
+
+  if (g_once_init_enter (&g_type)) {
+    const GType type =
+        g_enum_register_static ("GstVaapiHDRToneMap", enum_values);
+    g_once_init_leave (&g_type, type);
+  }
+  return g_type;
+}
+
 #define GST_VAAPI_TYPE_DEINTERLACE_MODE \
     gst_vaapi_deinterlace_mode_get_type()
 
@@ -516,6 +541,61 @@ set_best_deint_method (GstVaapiPostproc * postproc, guint flags,
 }
 
 static gboolean
+should_hdr_tone_map (GstVaapiPostproc * const postproc, const GstCaps * caps)
+{
+  switch (postproc->hdr_tone_map) {
+    case GST_VAAPI_HDR_TONE_MAP_AUTO:
+    {
+      GstVideoMasteringDisplayInfo minfo;
+      return gst_video_mastering_display_info_from_caps (&minfo, caps);
+    }
+    case GST_VAAPI_HDR_TONE_MAP_DISABLED:
+      return FALSE;
+    default:
+      GST_ERROR_OBJECT (postproc, "unhandled \"hdr-tone-map\" option");
+      break;
+  }
+  return FALSE;
+}
+
+static gboolean
+configure_hdr_tone_map (GstVaapiPostproc * const postproc, const GstCaps * caps)
+{
+  gboolean enable;
+
+  g_return_val_if_fail (postproc->has_vpp, FALSE);
+
+  enable = should_hdr_tone_map (postproc, caps);
+
+  if (!gst_vaapi_filter_set_hdr_tone_map (postproc->filter, enable))
+    goto fail_configure_hdr_tone_map;
+
+  if (enable) {
+    GstVideoMasteringDisplayInfo minfo;
+    GstVideoContentLightLevel linfo;
+
+    gst_video_mastering_display_info_from_caps (&minfo, caps);
+    gst_video_content_light_level_from_caps (&linfo, caps);
+
+    if (!gst_vaapi_filter_set_hdr_tone_map_meta (postproc->filter, &minfo,
+            &linfo))
+      goto fail_configure_hdr_tone_map;
+
+    postproc->flags |= GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP;
+  } else {
+    postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP);
+  }
+
+  return TRUE;
+
+fail_configure_hdr_tone_map:
+  {
+    postproc->flags &= ~(GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP);
+    return FALSE;
+  }
+}
+
+static gboolean
 check_filter_update (GstVaapiPostproc * postproc)
 {
   guint filter_flag = postproc->flags;
@@ -1650,6 +1730,21 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps,
       goto done;
   }
 
+  if (postproc->has_vpp) {
+    if (!gst_vaapi_filter_set_colorimetry (postproc->filter,
+            &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO
+                (postproc)),
+            &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO
+                (postproc))))
+      goto done;
+
+    if (!configure_hdr_tone_map (postproc,
+            GST_VAAPI_PLUGIN_BASE_SINK_PAD_CAPS (postproc)))
+      GST_WARNING_OBJECT (postproc,
+          "Failed to configure HDR tone mapping."
+          "  The driver may not support it.");
+  }
+
   if (!ensure_srcpad_buffer_pool (postproc, out_caps))
     goto done;
 
@@ -1660,13 +1755,6 @@ gst_vaapipostproc_set_caps (GstBaseTransform * trans, GstCaps * caps,
     gst_vaapipostproc_set_passthrough (trans);
   }
 
-  if (postproc->has_vpp && !gst_vaapi_filter_set_colorimetry (postproc->filter,
-          &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO
-              (postproc)),
-          &GST_VIDEO_INFO_COLORIMETRY (GST_VAAPI_PLUGIN_BASE_SRC_PAD_INFO
-              (postproc))))
-    goto done;
-
   ret = TRUE;
 
 done:
@@ -2037,6 +2125,9 @@ gst_vaapipostproc_set_property (GObject * object,
       postproc->crop_bottom = g_value_get_uint (value);
       postproc->flags |= GST_VAAPI_POSTPROC_FLAG_CROP;
       break;
+    case PROP_HDR_TONE_MAP:
+      postproc->hdr_tone_map = g_value_get_enum (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2119,6 +2210,9 @@ gst_vaapipostproc_get_property (GObject * object,
     case PROP_CROP_BOTTOM:
       g_value_set_uint (value, postproc->crop_bottom);
       break;
+    case PROP_HDR_TONE_MAP:
+      g_value_set_enum (value, postproc->hdr_tone_map);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2174,6 +2268,22 @@ gst_vaapipostproc_class_init (GstVaapiPostprocClass * klass)
       &gst_vaapipostproc_src_factory);
 
   /**
+   * GstVaapiPostproc:hdr-tone-map:
+   *
+   * Selects whether HDR tone mapping should not be applied or if it
+   * should be only applied on content that has the HDR meta on the caps.
+   */
+  g_object_class_install_property
+      (object_class,
+      PROP_HDR_TONE_MAP,
+      g_param_spec_enum ("hdr-tone-map",
+          "HDR Tone Map",
+          "Apply HDR tone mapping algorithm",
+          GST_VAAPI_TYPE_HDR_TONE_MAP,
+          GST_VAAPI_HDR_TONE_MAP_AUTO,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
    * GstVaapiPostproc:deinterlace-mode:
    *
    * This selects whether the deinterlacing should always be applied
@@ -2487,6 +2597,7 @@ gst_vaapipostproc_init (GstVaapiPostproc * postproc)
 
   g_mutex_init (&postproc->postproc_lock);
   postproc->format = DEFAULT_FORMAT;
+  postproc->hdr_tone_map = GST_VAAPI_HDR_TONE_MAP_AUTO;
   postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE;
   postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD;
   postproc->field_duration = GST_CLOCK_TIME_NONE;
index c751c8b..9a0d52d 100644 (file)
@@ -50,6 +50,17 @@ typedef struct _GstVaapiPostprocClass GstVaapiPostprocClass;
 typedef struct _GstVaapiDeinterlaceState GstVaapiDeinterlaceState;
 
 /**
+ * GstVaapiHDRToneMap:
+ * @GST_VAAPI_TYPE_HDR_TONE_MAP_AUTO: Auto detect need for hdr tone map.
+ * @GST_VAAPI_TYPE_HDR_TONE_MAP_DISABLED: Never perform hdr tone map.
+ */
+typedef enum
+{
+  GST_VAAPI_HDR_TONE_MAP_AUTO = 0,
+  GST_VAAPI_HDR_TONE_MAP_DISABLED,
+} GstVaapiHDRToneMap;
+
+/**
  * GstVaapiDeinterlaceMode:
  * @GST_VAAPI_DEINTERLACE_MODE_AUTO: Auto detect needs for deinterlacing.
  * @GST_VAAPI_DEINTERLACE_MODE_INTERLACED: Force deinterlacing.
@@ -87,6 +98,7 @@ typedef enum
  * @GST_VAAPI_POSTPROC_FLAG_SIZE: Video scaling.
  * @GST_VAAPI_POSTPROC_FLAG_SCALE: Video scaling mode.
  * @GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION: Video rotation and flip/mirroring.
+ * @GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP: HDR tone mapping.
  * @GST_VAAPI_POSTPROC_FLAG_SKINTONE: Skin tone enhancement.
  * @GST_VAAPI_POSTPROC_FLAG_SKINTONE_LEVEL: Skin tone enhancement with value.
  *
@@ -106,6 +118,7 @@ typedef enum
   GST_VAAPI_POSTPROC_FLAG_VIDEO_DIRECTION =
       1 << GST_VAAPI_FILTER_OP_VIDEO_DIRECTION,
   GST_VAAPI_POSTPROC_FLAG_CROP        = 1 << GST_VAAPI_FILTER_OP_CROP,
+  GST_VAAPI_POSTPROC_FLAG_HDR_TONE_MAP = 1 << GST_VAAPI_FILTER_OP_HDR_TONE_MAP,
 #ifndef GST_REMOVE_DEPRECATED
   GST_VAAPI_POSTPROC_FLAG_SKINTONE    = 1 << GST_VAAPI_FILTER_OP_SKINTONE,
 #endif
@@ -159,6 +172,9 @@ struct _GstVaapiPostproc
   GstCaps *allowed_srcpad_caps;
   GstVideoInfo srcpad_info;
 
+  /* HDR Tone Mapping */
+  GstVaapiHDRToneMap hdr_tone_map;
+
   /* Deinterlacing */
   GstVaapiDeinterlaceMode deinterlace_mode;
   GstVaapiDeinterlaceMethod deinterlace_method;