subpicture: add support for global-alpha.
authorHolger Kaelberer <holger.k@elberer.de>
Tue, 15 May 2012 08:24:08 +0000 (10:24 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Fri, 11 Jan 2013 13:23:06 +0000 (14:23 +0100)
Add the necessary helpers in GstVaapiDisplay to determine whether subpictures
with global alpha are supported or not. Also add accessors in GstVaapiSubpicture
to address this feature.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
gst-libs/gst/vaapi/gstvaapidisplay.c
gst-libs/gst/vaapi/gstvaapidisplay.h
gst-libs/gst/vaapi/gstvaapisubpicture.c
gst-libs/gst/vaapi/gstvaapisubpicture.h
gst-libs/gst/vaapi/gstvaapisurface.c
tests/image.c
tests/test-subpicture.c

index a51c0b5..4677a79 100644 (file)
@@ -719,14 +719,16 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
         goto end;
 
     GST_DEBUG("%d subpicture formats", n);
-    for (i = 0; i < n; i++)
+    for (i = 0; i < n; i++) {
         GST_DEBUG("  %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc));
+        flags[i] = to_GstVaapiSubpictureFlags(flags[i]);
+    }
 
     priv->subpicture_formats =
         g_array_new(FALSE, FALSE, sizeof(GstVaapiFormatInfo));
     if (!priv->subpicture_formats)
         goto end;
-    append_formats(priv->subpicture_formats, formats, NULL, n);
+    append_formats(priv->subpicture_formats, formats, flags, n);
     g_array_sort(priv->subpicture_formats, compare_rgb_formats);
 
     if (!cached_info) {
@@ -1404,21 +1406,32 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display)
  * gst_vaapi_display_has_subpicture_format:
  * @display: a #GstVaapiDisplay
  * @format: a #GstVaapiFormat
+ * @flags: #GstVaapiSubpictureFlags, or zero
  *
- * Returns whether VA @display supports @format subpicture format.
+ * Returns whether VA @display supports @format subpicture format with
+ * the supplied @flags.
  *
  * Return value: %TRUE if VA @display supports @format subpicture format
  */
 gboolean
 gst_vaapi_display_has_subpicture_format(
     GstVaapiDisplay    *display,
-    GstVaapiImageFormat format
+    GstVaapiImageFormat format,
+    guint              *flags_ptr
 )
 {
+    const GstVaapiFormatInfo *fip;
+
     g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE);
     g_return_val_if_fail(format, FALSE);
 
-    return find_format(display->priv->subpicture_formats, format);
+    fip = find_format_info(display->priv->subpicture_formats, format);
+    if (!fip)
+        return FALSE;
+
+    if (flags_ptr)
+        *flags_ptr = fip->flags;
+    return TRUE;
 }
 
 /**
index d23b0ad..ddfb375 100644 (file)
@@ -231,7 +231,8 @@ gst_vaapi_display_get_subpicture_caps(GstVaapiDisplay *display);
 gboolean
 gst_vaapi_display_has_subpicture_format(
     GstVaapiDisplay    *display,
-    GstVaapiImageFormat format
+    GstVaapiImageFormat format,
+    guint              *flags_ptr
 );
 
 gboolean
index a09f246..86d40dc 100644 (file)
@@ -44,11 +44,15 @@ G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT)
 
 struct _GstVaapiSubpicturePrivate {
     GstVaapiImage      *image;
+    guint               flags;
+    gfloat              global_alpha;
 };
 
 enum {
     PROP_0,
 
+    PROP_FLAGS,
+    PROP_GLOBAL_ALPHA,
     PROP_IMAGE
 };
 
@@ -128,6 +132,13 @@ gst_vaapi_subpicture_set_property(
     GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object);
 
     switch (prop_id) {
+    case PROP_FLAGS:
+        subpicture->priv->flags = g_value_get_uint(value);
+        break;
+    case PROP_GLOBAL_ALPHA:
+        gst_vaapi_subpicture_set_global_alpha(subpicture,
+            g_value_get_float(value));
+        break;
     case PROP_IMAGE:
         gst_vaapi_subpicture_set_image(subpicture, g_value_get_object(value));
         break;
@@ -148,6 +159,13 @@ gst_vaapi_subpicture_get_property(
     GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object);
 
     switch (prop_id) {
+    case PROP_FLAGS:
+        g_value_set_uint(value, subpicture->priv->flags);
+        break;
+    case PROP_GLOBAL_ALPHA:
+        g_value_set_float(value,
+            gst_vaapi_subpicture_get_global_alpha(subpicture));
+        break;
     case PROP_IMAGE:
         g_value_set_object(value, gst_vaapi_subpicture_get_image(subpicture));
         break;
@@ -169,6 +187,34 @@ gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass)
     object_class->get_property = gst_vaapi_subpicture_get_property;
 
     /**
+     * GstVaapiSubpicture:flags:
+     *
+     * The #GstVaapiSubpictureFlags this subpicture requires.
+     */
+    g_object_class_install_property
+        (object_class,
+         PROP_FLAGS,
+         g_param_spec_uint("flags",
+                           "Flags",
+                           "The GstVaapiSubpictureFlags this subpicture requires",
+                           0, G_MAXUINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    /**
+     * GstVaapiSubpicture:global-alpha:
+     *
+     * The global-alpha value associated with this subpicture.
+     */
+    g_object_class_install_property
+        (object_class,
+         PROP_GLOBAL_ALPHA,
+         g_param_spec_float("global-alpha",
+                            "Global Alpha",
+                            "The global-alpha value associated with this subpicture",
+                            0.0f, 1.0f, 1.0f,
+                            G_PARAM_READWRITE));
+
+    /**
      * GstVaapiSubpicture:image:
      *
      * The #GstVaapiImage this subpicture is bound to.
@@ -190,11 +236,13 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture)
 
     subpicture->priv    = priv;
     priv->image         = NULL;
+    priv->global_alpha  = 1.0f;
 }
 
 /**
  * gst_vaapi_subpicture_new:
  * @image: a #GstVaapiImage
+ * @flags: #GstVaapiSubpictureFlags, or zero
  *
  * Creates a new #GstVaapiSubpicture with @image as source pixels. The
  * newly created object holds a reference on @image.
@@ -202,17 +250,30 @@ gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture)
  * Return value: the newly allocated #GstVaapiSubpicture object
  */
 GstVaapiSubpicture *
-gst_vaapi_subpicture_new(GstVaapiImage *image)
+gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags)
 {
+    GstVaapiDisplay *display;
+    GstVaapiImageFormat format;
+    guint va_flags;
+
     g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
 
     GST_DEBUG("create from image %" GST_VAAPI_ID_FORMAT,
               GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image)));
 
+    display = GST_VAAPI_OBJECT_DISPLAY(image);
+    format  = gst_vaapi_image_get_format(image);
+    if (!gst_vaapi_display_has_subpicture_format(display, format, &va_flags))
+        return NULL;
+    if (flags & ~va_flags)
+        return NULL;
+
     return g_object_new(GST_VAAPI_TYPE_SUBPICTURE,
-                        "display", GST_VAAPI_OBJECT_DISPLAY(image),
-                        "id",      GST_VAAPI_ID(VA_INVALID_ID),
-                        "image",   image,
+                        "display",      GST_VAAPI_OBJECT_DISPLAY(image),
+                        "id",           GST_VAAPI_ID(VA_INVALID_ID),
+                        "flags",        flags,
+                        "global-alpha", 1.0f,
+                        "image",        image,
                         NULL);
 }
 
@@ -273,7 +334,7 @@ gst_vaapi_subpicture_new_from_overlay_rectangle(
         return NULL;
     }
 
-    subpicture = gst_vaapi_subpicture_new(image);
+    subpicture = gst_vaapi_subpicture_new(image, 0);
     g_object_unref(image);
     return subpicture;
 }
@@ -295,6 +356,22 @@ gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture)
 }
 
 /**
+ * gst_vaapi_subpicture_get_flags:
+ * @subpicture: a #GstVaapiSubpicture
+ *
+ * Returns the @subpicture flags.
+ *
+ * Return value: the @subpicture flags
+ */
+guint
+gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 0);
+
+    return subpicture->priv->flags;
+}
+
+/**
  * gst_vaapi_subpicture_get_image:
  * @subpicture: a #GstVaapiSubpicture
  *
@@ -332,3 +409,64 @@ gst_vaapi_subpicture_set_image(
     subpicture->priv->image = g_object_ref(image);
     gst_vaapi_subpicture_create(subpicture);
 }
+
+/**
+ * gst_vaapi_subpicture_get_global_alpha:
+ * @subpicture: a #GstVaapiSubpicture
+ *
+ * Returns the value of global_alpha, set for this @subpicture.
+ *
+ * Return value: the global_alpha value of this @subpicture
+ */
+gfloat
+gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), 1.0);
+
+    return subpicture->priv->global_alpha;
+}
+
+/**
+ * gst_vaapi_subpicture_set_global_alpha:
+ * @subpicture: a #GstVaapiSubpicture
+ * @global_alpha: value for global-alpha (range: 0.0 to 1.0, inclusive)
+ *
+ * Sets the global_alpha value of @subpicture. This function calls
+ * vaSetSubpictureGlobalAlpha() if the format of @subpicture, i.e.
+ * the current VA driver supports it.
+ *
+ * Return value: %TRUE if global_alpha could be set, %FALSE otherwise
+ */
+gboolean
+gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture,
+    gfloat global_alpha)
+{
+    GstVaapiSubpicturePrivate *priv;
+    GstVaapiDisplay *display;
+    VAStatus status;
+
+    g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), FALSE);
+
+    priv = subpicture->priv;
+
+    if (!(priv->flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA))
+        return FALSE;
+
+    if (priv->global_alpha == global_alpha)
+        return TRUE;
+
+    display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
+
+    GST_VAAPI_DISPLAY_LOCK(display);
+    status = vaSetSubpictureGlobalAlpha(
+        GST_VAAPI_DISPLAY_VADISPLAY(display),
+        GST_VAAPI_OBJECT_ID(subpicture),
+        global_alpha
+    );
+    GST_VAAPI_DISPLAY_UNLOCK(display);
+    if (!vaapi_check_status(status, "vaSetSubpictureGlobalAlpha()"))
+        return FALSE;
+
+    priv->global_alpha = global_alpha;
+    return TRUE;
+}
index 7a2bdae..80c05d3 100644 (file)
@@ -99,7 +99,7 @@ GType
 gst_vaapi_subpicture_get_type(void) G_GNUC_CONST;
 
 GstVaapiSubpicture *
-gst_vaapi_subpicture_new(GstVaapiImage *image);
+gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags);
 
 GstVaapiSubpicture *
 gst_vaapi_subpicture_new_from_overlay_rectangle(
@@ -110,6 +110,9 @@ gst_vaapi_subpicture_new_from_overlay_rectangle(
 GstVaapiID
 gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture);
 
+guint
+gst_vaapi_subpicture_get_flags(GstVaapiSubpicture *subpicture);
+
 GstVaapiImage *
 gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture);
 
@@ -119,6 +122,13 @@ gst_vaapi_subpicture_set_image(
     GstVaapiImage      *image
 );
 
+gfloat
+gst_vaapi_subpicture_get_global_alpha(GstVaapiSubpicture *subpicture);
+
+gboolean
+gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture,
+    gfloat global_alpha);
+
 G_END_DECLS
 
 #endif /* GST_VAAPI_SUBPICTURE_H */
index 745495d..46ad45e 100644 (file)
@@ -723,7 +723,7 @@ _gst_vaapi_surface_associate_subpicture(
         &surface_id, 1,
         src_rect->x, src_rect->y, src_rect->width, src_rect->height,
         dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height,
-        0
+        from_GstVaapiSubpictureFlags(gst_vaapi_subpicture_get_flags(subpicture))
     );
     GST_VAAPI_DISPLAY_UNLOCK(display);
     if (!vaapi_check_status(status, "vaAssociateSubpicture()"))
index 39a8ac5..289e2a3 100644 (file)
@@ -341,12 +341,12 @@ image_upload(GstVaapiImage *image, GstVaapiSurface *surface)
     g_print("could not upload %" GST_FOURCC_FORMAT" image to surface\n",
             GST_FOURCC_ARGS(format));
 
-    if (!gst_vaapi_display_has_subpicture_format(display, format))
+    if (!gst_vaapi_display_has_subpicture_format(display, format, NULL))
         return FALSE;
 
     g_print("trying as a subpicture\n");
 
-    subpicture = gst_vaapi_subpicture_new(image);
+    subpicture = gst_vaapi_subpicture_new(image, 0);
     if (!subpicture)
         g_error("could not create VA subpicture");
 
index 11d018b..6a1620c 100644 (file)
@@ -192,7 +192,7 @@ main(int argc, char *argv[])
     if (!gst_vaapi_image_update_from_buffer (subtitle_image, buffer, NULL))
         g_error ("could not update VA image with subtitle data");
 
-    subpicture = gst_vaapi_subpicture_new (subtitle_image);
+    subpicture = gst_vaapi_subpicture_new (subtitle_image, 0);
 
     /* We position it as a subtitle, centered at the bottom. */
     sub_rect.x = (surf_width - subinfo.width) / 2;