Add VA surface, image, subpicture abstractions. Ported over from Gnash.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Thu, 4 Mar 2010 17:39:01 +0000 (17:39 +0000)
committergb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Thu, 4 Mar 2010 17:39:01 +0000 (17:39 +0000)
gst-libs/gst/vaapi/Makefile.am
gst-libs/gst/vaapi/gstvaapiimage.c [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapiimage.h [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapiimageformat.c [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapiimageformat.h [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapisurface.c [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapisurface.h [new file with mode: 0644]

index 3bb8981..edef4fa 100644 (file)
@@ -1,20 +1,37 @@
 lib_LTLIBRARIES = libgstvaapi-@GST_MAJORMINOR@.la
 
-libgstvaapi_@GST_MAJORMINOR@_la_SOURCES =      \
+libgstvaapi_source_c =                         \
        gstvaapidisplay.c                       \
+       gstvaapiimage.c                         \
+       gstvaapiimageformat.c                   \
+       gstvaapisubpicture.c                    \
+       gstvaapisurface.c                       \
        vaapi_utils.c                           \
        $(NULL)
 
-libgstvaapi_@GST_MAJORMINOR@include_HEADERS =  \
+libgstvaapi_source_h =                         \
        gstvaapidisplay.h                       \
+       gstvaapiimage.h                         \
+       gstvaapiimageformat.h                   \
+       gstvaapisubpicture.h                    \
+       gstvaapisurface.h                       \
        vaapi_debug.h                           \
        vaapi_utils.h                           \
        $(NULL)
 
-libgstvaapi_@GST_MAJORMINOR@includedir = \
+libgstvaapi_@GST_MAJORMINOR@_la_SOURCES =      \
+       $(libgstvaapi_source_c)                 \
+       $(NULL)
+
+libgstvaapi_@GST_MAJORMINOR@include_HEADERS =  \
+       $(libgstvaapi_source_h)                 \
+       $(NULL)
+
+libgstvaapi_@GST_MAJORMINOR@includedir =       \
        $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi
 
 libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS =       \
+       -I$(top_srcdir)/gst-libs                \
        $(GST_BASE_CFLAGS)                      \
        $(GST_CFLAGS)                           \
        $(LIBVA_CFLAGS)                         \
diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c
new file mode 100644 (file)
index 0000000..2c6c8d8
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ *  gstvaapiimage.c - VA image abstraction
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include "vaapi_utils.h"
+#include "gstvaapiimage.h"
+#include <va/va_backend.h>
+
+#define DEBUG 1
+#include "vaapi_debug.h"
+
+G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, G_TYPE_OBJECT);
+
+#define GST_VAAPI_IMAGE_GET_PRIVATE(obj)                \
+    (G_TYPE_INSTANCE_GET_PRIVATE((obj),                 \
+                                 GST_VAAPI_TYPE_IMAGE, \
+                                 GstVaapiImagePrivate))
+
+struct _GstVaapiImagePrivate {
+    GstVaapiDisplay    *display;
+    VAImage             image;
+    guchar             *image_data;
+    guint               width;
+    guint               height;
+    GstVaapiImageFormat format;
+};
+
+enum {
+    PROP_0,
+
+    PROP_DISPLAY,
+    PROP_IMAGE_ID,
+    PROP_WIDTH,
+    PROP_HEIGHT,
+    PROP_FORMAT
+};
+
+static void
+gst_vaapi_image_destroy(GstVaapiImage *image)
+{
+    GstVaapiImagePrivate * const priv = image->priv;
+    VADisplay dpy = gst_vaapi_display_get_display(priv->display);
+    VAStatus status;
+
+    gst_vaapi_image_unmap(image);
+
+    if (priv->image.image_id != VA_INVALID_ID) {
+        status = vaDestroyImage(dpy, priv->image.image_id);
+        if (!vaapi_check_status(status, "vaDestroyImage()"))
+            g_warning("failed to destroy image 0x%08x\n", priv->image.image_id);
+        priv->image.image_id = VA_INVALID_ID;
+    }
+
+    if (priv->display) {
+        g_object_unref(priv->display);
+        priv->display = NULL;
+    }
+}
+
+static gboolean
+gst_vaapi_image_create(GstVaapiImage *image)
+{
+    GstVaapiImagePrivate * const priv = image->priv;
+    const VAImageFormat *format;
+    VAStatus status;
+
+    if (!gst_vaapi_display_has_image_format(priv->display, priv->format))
+        return FALSE;
+
+    format = gst_vaapi_image_format_get_va_format(priv->format);
+
+    g_return_val_if_fail(format, FALSE);
+
+    status = vaCreateImage(
+        gst_vaapi_display_get_display(priv->display),
+        (VAImageFormat *)format,
+        priv->width,
+        priv->height,
+        &priv->image
+    );
+    if (!vaapi_check_status(status, "vaCreateImage()"))
+        return FALSE;
+
+    return TRUE;
+}
+
+static void
+gst_vaapi_image_finalize(GObject *object)
+{
+    gst_vaapi_image_destroy(GST_VAAPI_IMAGE(object));
+
+    G_OBJECT_CLASS(gst_vaapi_image_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_image_set_property(
+    GObject      *object,
+    guint         prop_id,
+    const GValue *value,
+    GParamSpec   *pspec
+)
+{
+    GstVaapiImage        * const image = GST_VAAPI_IMAGE(object);
+    GstVaapiImagePrivate * const priv  = image->priv;
+
+    switch (prop_id) {
+    case PROP_DISPLAY:
+        priv->display = g_object_ref(g_value_get_pointer(value));
+        break;
+    case PROP_WIDTH:
+        priv->width = g_value_get_uint(value);
+        break;
+    case PROP_HEIGHT:
+        priv->height = g_value_get_uint(value);
+        break;
+    case PROP_FORMAT:
+        priv->format = g_value_get_uint(value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+gst_vaapi_image_get_property(
+    GObject    *object,
+    guint       prop_id,
+    GValue     *value,
+    GParamSpec *pspec
+)
+{
+    GstVaapiImage        * const image = GST_VAAPI_IMAGE(object);
+    GstVaapiImagePrivate * const priv  = image->priv;
+
+    switch (prop_id) {
+    case PROP_DISPLAY:
+        g_value_set_pointer(value, g_object_ref(priv->display));
+        break;
+    case PROP_IMAGE_ID:
+        g_value_set_uint(value, gst_vaapi_image_get_id(image));
+        break;
+    case PROP_WIDTH:
+        g_value_set_uint(value, gst_vaapi_image_get_width(image));
+        break;
+    case PROP_HEIGHT:
+        g_value_set_uint(value, gst_vaapi_image_get_height(image));
+        break;
+    case PROP_FORMAT:
+        g_value_set_uint(value, gst_vaapi_image_get_format(image));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static GObject *
+gst_vaapi_image_constructor(
+    GType                  type,
+    guint                  n_params,
+    GObjectConstructParam *params
+)
+{
+    GstVaapiImage *image;
+    GObjectClass *parent_class;
+    GObject *object;
+
+    D(bug("gst_vaapi_image_constructor()\n"));
+
+    parent_class = G_OBJECT_CLASS(gst_vaapi_image_parent_class);
+    object = parent_class->constructor (type, n_params, params);
+
+    if (object) {
+        image = GST_VAAPI_IMAGE(object);
+        if (!gst_vaapi_image_create(image)) {
+            gst_vaapi_image_destroy(image);
+            object = NULL;
+        }
+    }
+    return object;
+}
+
+static void
+gst_vaapi_image_class_init(GstVaapiImageClass *klass)
+{
+    GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+
+    g_type_class_add_private(klass, sizeof(GstVaapiImagePrivate));
+
+    object_class->finalize     = gst_vaapi_image_finalize;
+    object_class->set_property = gst_vaapi_image_set_property;
+    object_class->get_property = gst_vaapi_image_get_property;
+    object_class->constructor  = gst_vaapi_image_constructor;
+
+    g_object_class_install_property
+        (object_class,
+         PROP_DISPLAY,
+         g_param_spec_object("display",
+                             "display",
+                             "GStreamer Va display",
+                             GST_VAAPI_TYPE_DISPLAY,
+                             G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_IMAGE_ID,
+         g_param_spec_uint("id",
+                           "VA image id",
+                           "VA image id",
+                           0, G_MAXUINT32, VA_INVALID_ID,
+                           G_PARAM_READABLE));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_WIDTH,
+         g_param_spec_uint("width",
+                           "width",
+                           "Image width",
+                           0, G_MAXUINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_HEIGHT,
+         g_param_spec_uint("height",
+                           "height",
+                           "Image height",
+                           0, G_MAXUINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_FORMAT,
+         g_param_spec_uint("format",
+                           "format",
+                           "Image format",
+                           0, G_MAXUINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gst_vaapi_image_init(GstVaapiImage *image)
+{
+    GstVaapiImagePrivate *priv = GST_VAAPI_IMAGE_GET_PRIVATE(image);
+
+    D(bug("gst_vaapi_image_init()\n"));
+
+    image->priv          = priv;
+    priv->display        = NULL;
+    priv->image_data     = NULL;
+    priv->width          = 0;
+    priv->height         = 0;
+    priv->format         = 0;
+
+    memset(&priv->image, 0, sizeof(priv->image));
+    priv->image.image_id = VA_INVALID_ID;
+    priv->image.buf      = VA_INVALID_ID;
+}
+
+GstVaapiImage *
+gst_vaapi_image_new(
+    GstVaapiDisplay    *display,
+    guint               width,
+    guint               height,
+    GstVaapiImageFormat format
+)
+{
+    D(bug("gst_vaapi_image_new(): size %ux%u, format 0x%x\n",
+          width, height, format));
+
+    return g_object_new(GST_VAAPI_TYPE_IMAGE,
+                        "display", display,
+                        "width",   width,
+                        "height",  height,
+                        "format",  format,
+                        NULL);
+}
+
+VAImageID
+gst_vaapi_image_get_id(GstVaapiImage *image)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID);
+
+    return image->priv->image.image_id;
+}
+
+GstVaapiDisplay *
+gst_vaapi_image_get_display(GstVaapiImage *image)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
+
+    return g_object_ref(image->priv->display);
+}
+
+guint
+gst_vaapi_image_get_width(GstVaapiImage *image)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
+
+    return image->priv->width;
+}
+
+guint
+gst_vaapi_image_get_height(GstVaapiImage *image)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
+
+    return image->priv->height;
+}
+
+guint
+gst_vaapi_image_get_format(GstVaapiImage *image)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
+
+    return image->priv->format;
+}
+
+static inline gboolean
+_gst_vaapi_image_is_mapped(GstVaapiImage *image)
+{
+    return image->priv->image_data != NULL;
+}
+
+gboolean
+gst_vaapi_image_is_mapped(GstVaapiImage *image)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
+
+    return _gst_vaapi_image_is_mapped(image);
+}
+
+gboolean
+gst_vaapi_image_map(GstVaapiImage *image)
+{
+    void *image_data;
+    VAStatus status;
+
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
+
+    if (_gst_vaapi_image_is_mapped(image))
+        return TRUE;
+
+    status = vaMapBuffer(
+        gst_vaapi_display_get_display(image->priv->display),
+        image->priv->image.buf,
+        &image_data
+    );
+    if (!vaapi_check_status(status, "vaMapBuffer()"))
+        return FALSE;
+
+    image->priv->image_data = image_data;
+    return TRUE;
+}
+
+gboolean
+gst_vaapi_image_unmap(GstVaapiImage *image)
+{
+    VAStatus status;
+
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
+
+    if (!_gst_vaapi_image_is_mapped(image))
+        return FALSE;
+
+    status = vaUnmapBuffer(
+        gst_vaapi_display_get_display(image->priv->display),
+        image->priv->image.buf
+    );
+    if (!vaapi_check_status(status, "vaUnmapBuffer()"))
+        return FALSE;
+
+    image->priv->image_data = NULL;
+    return TRUE;
+}
+
+guint
+gst_vaapi_image_get_plane_count(GstVaapiImage *image)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
+    g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
+
+    return image->priv->image.num_planes;
+}
+
+guchar *
+gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
+    g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL);
+    g_return_val_if_fail(plane < image->priv->image.num_planes, NULL);
+
+    return image->priv->image_data + image->priv->image.offsets[plane];
+}
+
+guint
+gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
+    g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
+    g_return_val_if_fail(plane < image->priv->image.num_planes, 0);
+
+    return image->priv->image.pitches[plane];
+}
diff --git a/gst-libs/gst/vaapi/gstvaapiimage.h b/gst-libs/gst/vaapi/gstvaapiimage.h
new file mode 100644 (file)
index 0000000..aa92314
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  gstvaapiimage.h - VA image abstraction
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef GST_VAAPI_IMAGE_H
+#define GST_VAAPI_IMAGE_H
+
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiimageformat.h>
+
+G_BEGIN_DECLS
+
+#define GST_VAAPI_TYPE_IMAGE \
+    (gst_vaapi_image_get_type())
+
+#define GST_VAAPI_IMAGE(obj)                            \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj),                  \
+                                GST_VAAPI_TYPE_IMAGE,   \
+                                GstVaapiImage))
+
+#define GST_VAAPI_IMAGE_CLASS(klass)                    \
+    (G_TYPE_CHECK_CLASS_CAST((klass),                   \
+                             GST_VAAPI_TYPE_IMAGE,      \
+                             GstVaapiImageClass))
+
+#define GST_VAAPI_IS_IMAGE(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IMAGE))
+
+#define GST_VAAPI_IS_IMAGE_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IMAGE))
+
+#define GST_VAAPI_IMAGE_GET_CLASS(obj)                  \
+    (G_TYPE_INSTANCE_GET_CLASS((obj),                   \
+                               GST_VAAPI_TYPE_IMAGE,    \
+                               GstVaapiImage))
+
+typedef struct _GstVaapiImage                   GstVaapiImage;
+typedef struct _GstVaapiImagePrivate            GstVaapiImagePrivate;
+typedef struct _GstVaapiImageClass              GstVaapiImageClass;
+
+struct _GstVaapiImage {
+    /*< private >*/
+    GObject parent_instance;
+
+    GstVaapiImagePrivate *priv;
+};
+
+struct _GstVaapiImageClass {
+    /*< private >*/
+    GObjectClass parent_class;
+};
+
+GType
+gst_vaapi_image_get_type(void);
+
+GstVaapiImage *
+gst_vaapi_image_new(
+    GstVaapiDisplay    *display,
+    guint               width,
+    guint               height,
+    GstVaapiImageFormat format
+);
+
+VAImageID
+gst_vaapi_image_get_id(GstVaapiImage *image);
+
+GstVaapiDisplay *
+gst_vaapi_image_get_display(GstVaapiImage *image);
+
+guint
+gst_vaapi_image_get_width(GstVaapiImage *image);
+
+guint
+gst_vaapi_image_get_height(GstVaapiImage *image);
+
+guint
+gst_vaapi_image_get_format(GstVaapiImage *image);
+
+gboolean
+gst_vaapi_image_is_mapped(GstVaapiImage *image);
+
+gboolean
+gst_vaapi_image_map(GstVaapiImage *image);
+
+gboolean
+gst_vaapi_image_unmap(GstVaapiImage *image);
+
+guint
+gst_vaapi_image_get_plane_count(GstVaapiImage *image);
+
+guchar *
+gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane);
+
+guint
+gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_IMAGE_H */
diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.c b/gst-libs/gst/vaapi/gstvaapiimageformat.c
new file mode 100644 (file)
index 0000000..3303063
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *  gstvaapiimageformat.c - VA image format abstraction
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include "config.h"
+#include <glib.h>
+#include "gstvaapiimageformat.h"
+
+typedef enum _GstVaapiImageFormatType           GstVaapiImageFormatType;
+typedef struct _GstVaapiImageFormatMap          GstVaapiImageFormatMap;
+
+enum _GstVaapiImageFormatType {
+    GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR = 1,
+    GST_VAAPI_IMAGE_FORMAT_TYPE_RGB,
+    GST_VAAPI_IMAGE_FORMAT_TYPE_INDEXED
+};
+
+struct _GstVaapiImageFormatMap {
+    GstVaapiImageFormatType     type;
+    GstVaapiImageFormat         format;
+    VAImageFormat               va_format;
+};
+
+#define DEF(TYPE, FORMAT) \
+    GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE, GST_VAAPI_IMAGE_##FORMAT
+#define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP)                            \
+    { DEF(YCBCR, FORMAT),                                               \
+        { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, }
+#define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A)            \
+    { DEF(RGB, FORMAT),                                                 \
+        { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, }
+#define DEF_IDX(FORMAT, FOURCC, ENDIAN, BPP, NPE, EB, C0,C1,C2,C3)      \
+    { DEF(TYPE, FORMAT),                                                \
+        { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }
+
+static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = {
+    DEF_YUV(NV12, ('N','V','1','2'), LSB, 12),
+    DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12),
+    DEF_YUV(I420, ('I','4','2','0'), LSB, 12),
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+    DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32,
+            32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
+    DEF_RGB(ABGR, ('A','B','G','R'), MSB, 32,
+            32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
+#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
+    DEF_RGB(BGRA, ('B','G','R','A'), LSB, 32,
+            32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
+    DEF_RGB(RGBA, ('R','G','B','A'), LSB, 32,
+            32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
+#endif
+    { 0, }
+};
+
+#undef DEF_IDX
+#undef DEF_RGB
+#undef DEF_YUV
+#undef DEF
+
+static const GstVaapiImageFormatMap *get_map(const VAImageFormat *va_format)
+{
+    const GstVaapiImageFormatMap *m;
+
+    for (m = gst_vaapi_image_formats; m->format; m++)
+        if (m->va_format.fourcc == va_format->fourcc &&
+            (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB ?
+             (m->va_format.byte_order == va_format->byte_order &&
+              m->va_format.red_mask   == va_format->red_mask   &&
+              m->va_format.green_mask == va_format->green_mask &&
+              m->va_format.blue_mask  == va_format->blue_mask  &&
+              m->va_format.alpha_mask == va_format->alpha_mask) :
+             TRUE))
+            return m;
+    return NULL;
+}
+
+static const GstVaapiImageFormatMap *
+get_map_from_gst_vaapi_image_format(GstVaapiImageFormat format)
+{
+    const GstVaapiImageFormatMap *m;
+
+    for (m = gst_vaapi_image_formats; m->format; m++)
+        if (m->format == format)
+            return m;
+    return NULL;
+}
+
+gboolean
+gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format)
+{
+    const GstVaapiImageFormatMap *m;
+
+    m = get_map_from_gst_vaapi_image_format(format);
+
+    g_return_val_if_fail(m, FALSE);
+
+    return m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB;
+}
+
+gboolean
+gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format)
+{
+    const GstVaapiImageFormatMap *m;
+
+    m = get_map_from_gst_vaapi_image_format(format);
+
+    g_return_val_if_fail(m, FALSE);
+
+    return m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR;
+}
+
+GstVaapiImageFormat
+gst_vaapi_image_format(const VAImageFormat *va_format)
+{
+    const GstVaapiImageFormatMap * const m = get_map(va_format);
+
+    g_return_val_if_fail(m, 0);
+
+    return m->format;
+}
+
+GstVaapiImageFormat
+gst_vaapi_image_format_from_fourcc(guint32 fourcc)
+{
+    return (GstVaapiImageFormat)fourcc;
+}
+
+const VAImageFormat *
+gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format)
+{
+    const GstVaapiImageFormatMap *m;
+
+    m = get_map_from_gst_vaapi_image_format(format);
+
+    g_return_val_if_fail(m, NULL);
+
+    return &m->va_format;
+}
diff --git a/gst-libs/gst/vaapi/gstvaapiimageformat.h b/gst-libs/gst/vaapi/gstvaapiimageformat.h
new file mode 100644 (file)
index 0000000..8998733
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  gstvaapiimageformat.h - VA image format abstraction
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef GST_VAAPI_IMAGE_FORMAT_H
+#define GST_VAAPI_IMAGE_FORMAT_H
+
+#include <va/va.h>
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef enum _GstVaapiImageFormat               GstVaapiImageFormat;
+
+enum _GstVaapiImageFormat {
+    /** Planar YUV 4:2:0, 12-bit, 1 plane for Y and 1 plane for UV */
+    GST_VAAPI_IMAGE_NV12 = VA_FOURCC('N','V','1','2'),
+    /** Planar YUV 4:2:0, 12-bit, 3 planes for Y V U */
+    GST_VAAPI_IMAGE_YV12 = VA_FOURCC('Y','V','1','2'),
+    /** Planar YUV 4:2:0, 12-bit, 3 planes for Y U V */
+    GST_VAAPI_IMAGE_I420 = VA_FOURCC('I','4','2','0'),
+    /** Packed RGB 8:8:8, 32-bit, A R G B */
+    GST_VAAPI_IMAGE_ARGB = VA_FOURCC('A','R','G','B'),
+    /** Packed RGB 8:8:8, 32-bit, R G B A */
+    GST_VAAPI_IMAGE_RGBA = VA_FOURCC('R','G','B','A'),
+    /** Packed RGB 8:8:8, 32-bit, A R G B */
+    GST_VAAPI_IMAGE_ABGR = VA_FOURCC('A','B','G','R'),
+    /** Packed RGB 8:8:8, 32-bit, R G B A */
+    GST_VAAPI_IMAGE_BGRA = VA_FOURCC('B','G','R','A'),
+};
+
+gboolean
+gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format);
+
+gboolean
+gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format);
+
+GstVaapiImageFormat
+gst_vaapi_image_format(const VAImageFormat *va_format);
+
+GstVaapiImageFormat
+gst_vaapi_image_format_from_fourcc(guint32 fourcc);
+
+const VAImageFormat *
+gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format);
+
+G_END_DECLS
+
+#endif /* GST_GST_VAAPI_IMAGE_H */
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c
new file mode 100644 (file)
index 0000000..2f52850
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ *  gstvaapisurface.c - VA surface abstraction
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include "config.h"
+#include "vaapi_utils.h"
+#include "gstvaapisurface.h"
+#include <va/va_backend.h>
+
+#define DEBUG 1
+#include "vaapi_debug.h"
+
+G_DEFINE_TYPE(GstVaapiSurface, gst_vaapi_surface, G_TYPE_OBJECT);
+
+#define GST_VAAPI_SURFACE_GET_PRIVATE(obj)                      \
+    (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
+                                 GST_VAAPI_TYPE_SURFACE,       \
+                                 GstVaapiSurfacePrivate))
+
+struct _GstVaapiSurfacePrivate {
+    GstVaapiDisplay    *display;
+    VASurfaceID         surface_id;
+    guint               width;
+    guint               height;
+    guint               format;
+};
+
+enum {
+    PROP_0,
+
+    PROP_DISPLAY,
+    PROP_SURFACE_ID,
+    PROP_WIDTH,
+    PROP_HEIGHT,
+    PROP_FORMAT
+};
+
+static void
+gst_vaapi_surface_destroy(GstVaapiSurface *surface)
+{
+    GstVaapiSurfacePrivate * const priv = surface->priv;
+    VADisplay dpy = gst_vaapi_display_get_display(priv->display);
+    VAStatus status;
+
+    if (priv->surface_id != VA_INVALID_SURFACE) {
+        status = vaDestroySurfaces(dpy, &priv->surface_id, 1);
+        if (!vaapi_check_status(status, "vaDestroySurfaces()"))
+            g_warning("failed to destroy surface 0x%08x\n", priv->surface_id);
+        priv->surface_id = VA_INVALID_SURFACE;
+    }
+
+    if (priv->display) {
+        g_object_unref(priv->display);
+        priv->display = NULL;
+    }
+}
+
+static gboolean
+gst_vaapi_surface_create(GstVaapiSurface *surface)
+{
+    GstVaapiSurfacePrivate * const priv = surface->priv;
+    VASurfaceID surface_id;
+    VAStatus status;
+
+    status = vaCreateSurfaces(
+        gst_vaapi_display_get_display(priv->display),
+        priv->width,
+        priv->height,
+        priv->format,
+        1, &surface_id
+    );
+    if (!vaapi_check_status(status, "vaCreateSurfaces()"))
+        return FALSE;
+
+    priv->surface_id = surface_id;
+    return TRUE;
+}
+
+static void
+gst_vaapi_surface_finalize(GObject *object)
+{
+    gst_vaapi_surface_destroy(GST_VAAPI_SURFACE(object));
+
+    G_OBJECT_CLASS(gst_vaapi_surface_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_surface_set_property(GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+    GstVaapiSurface        * const surface = GST_VAAPI_SURFACE(object);
+    GstVaapiSurfacePrivate * const priv    = surface->priv;
+
+    switch (prop_id) {
+    case PROP_DISPLAY:
+        priv->display = g_object_ref(g_value_get_pointer(value));
+        break;
+    case PROP_WIDTH:
+        priv->width = g_value_get_uint(value);
+        break;
+    case PROP_HEIGHT:
+        priv->height = g_value_get_uint(value);
+        break;
+    case PROP_FORMAT:
+        priv->format = g_value_get_uint(value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+gst_vaapi_surface_get_property(GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+    GstVaapiSurface        * const surface = GST_VAAPI_SURFACE(object);
+    GstVaapiSurfacePrivate * const priv    = surface->priv;
+
+    switch (prop_id) {
+    case PROP_DISPLAY:
+        g_value_set_pointer(value, g_object_ref(priv->display));
+        break;
+    case PROP_SURFACE_ID:
+        g_value_set_uint(value, gst_vaapi_surface_get_id(surface));
+        break;
+    case PROP_WIDTH:
+        g_value_set_uint(value, gst_vaapi_surface_get_width(surface));
+        break;
+    case PROP_HEIGHT:
+        g_value_set_uint(value, gst_vaapi_surface_get_height(surface));
+        break;
+    case PROP_FORMAT:
+        g_value_set_uint(value, gst_vaapi_surface_get_format(surface));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static GObject *
+gst_vaapi_surface_constructor(GType                  type,
+                              guint                  n_params,
+                              GObjectConstructParam *params)
+{
+    GstVaapiSurface *surface;
+    GObjectClass *parent_class;
+    GObject *object;
+
+    D(bug("gst_vaapi_surface_constructor()\n"));
+
+    parent_class = G_OBJECT_CLASS(gst_vaapi_surface_parent_class);
+    object = parent_class->constructor (type, n_params, params);
+
+    if (object) {
+        surface = GST_VAAPI_SURFACE(object);
+        if (!gst_vaapi_surface_create(surface)) {
+            gst_vaapi_surface_destroy(surface);
+            object = NULL;
+        }
+    }
+    return object;
+}
+
+static void
+gst_vaapi_surface_class_init(GstVaapiSurfaceClass *klass)
+{
+    GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+
+    g_type_class_add_private(klass, sizeof(GstVaapiSurfacePrivate));
+
+    object_class->finalize     = gst_vaapi_surface_finalize;
+    object_class->set_property = gst_vaapi_surface_set_property;
+    object_class->get_property = gst_vaapi_surface_get_property;
+    object_class->constructor  = gst_vaapi_surface_constructor;
+
+    g_object_class_install_property
+        (object_class,
+         PROP_DISPLAY,
+         g_param_spec_object("display",
+                             "display",
+                             "GStreamer Va display",
+                             GST_VAAPI_TYPE_DISPLAY,
+                             G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_SURFACE_ID,
+         g_param_spec_uint("id",
+                           "VA surface id",
+                           "VA surface id",
+                           0, G_MAXUINT32, VA_INVALID_SURFACE,
+                           G_PARAM_READABLE));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_WIDTH,
+         g_param_spec_uint("width",
+                           "width",
+                           "VA surface width",
+                           0, G_MAXINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_HEIGHT,
+         g_param_spec_uint("height",
+                           "height",
+                           "VA surface height",
+                           0, G_MAXINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_FORMAT,
+         g_param_spec_uint("format",
+                           "format",
+                           "VA surface format",
+                           0, G_MAXUINT32, 0,
+                           G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gst_vaapi_surface_init(GstVaapiSurface *surface)
+{
+    GstVaapiSurfacePrivate *priv = GST_VAAPI_SURFACE_GET_PRIVATE(surface);
+
+    D(bug("gst_vaapi_surface_init()\n"));
+
+    surface->priv       = priv;
+    priv->display       = NULL;
+    priv->surface_id    = VA_INVALID_SURFACE;
+    priv->width         = 0;
+    priv->height        = 0;
+    priv->format        = 0;
+}
+
+GstVaapiSurface *
+gst_vaapi_surface_new(GstVaapiDisplay *display,
+                      guint            width,
+                      guint            height,
+                      guint            format)
+{
+    D(bug("gst_vaapi_surface_new(): size %ux%u, format 0x%x\n",
+          width, height, format));
+
+    return g_object_new(GST_VAAPI_TYPE_SURFACE,
+                        "display", display,
+                        "width", width,
+                        "height", height,
+                        "format", format,
+                        NULL);
+}
+
+VASurfaceID
+gst_vaapi_surface_get_id(GstVaapiSurface *surface)
+{
+    GstVaapiSurfacePrivate * const priv = surface->priv;
+
+    g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), VA_INVALID_SURFACE);
+
+    return priv->surface_id;
+}
+
+guint
+gst_vaapi_surface_get_width(GstVaapiSurface *surface)
+{
+    GstVaapiSurfacePrivate * const priv = surface->priv;
+
+    g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
+
+    return priv->width;
+}
+
+guint
+gst_vaapi_surface_get_height(GstVaapiSurface *surface)
+{
+    GstVaapiSurfacePrivate * const priv = surface->priv;
+
+    g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
+
+    return priv->height;
+}
+
+guint
+gst_vaapi_surface_get_format(GstVaapiSurface *surface)
+{
+    GstVaapiSurfacePrivate *priv = surface->priv;
+
+    g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
+
+    return priv->format;
+}
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h
new file mode 100644 (file)
index 0000000..cbbd1ba
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  gstvaapisurface.h - VA surface abstraction
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef GST_VAAPI_SURFACE_H
+#define GST_VAAPI_SURFACE_H
+
+#include <gst/vaapi/gstvaapidisplay.h>
+
+G_BEGIN_DECLS
+
+#define GST_VAAPI_TYPE_SURFACE \
+    (gst_vaapi_surface_get_type())
+
+#define GST_VAAPI_SURFACE(obj)                          \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj),                  \
+                                GST_VAAPI_TYPE_SURFACE, \
+                                GstVaapiSurface))
+
+#define GST_VAAPI_SURFACE_CLASS(klass)                  \
+    (G_TYPE_CHECK_CLASS_CAST((klass),                   \
+                             GST_VAAPI_TYPE_SURFACE,    \
+                             GstVaapiSurfaceClass))
+
+#define GST_VAAPI_IS_SURFACE(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SURFACE))
+
+#define GST_VAAPI_IS_SURFACE_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SURFACE))
+
+#define GST_VAAPI_SURFACE_GET_CLASS(obj)                \
+    (G_TYPE_INSTANCE_GET_CLASS((obj),                   \
+                               GST_VAAPI_TYPE_SURFACE,  \
+                               GstVaapiSurface))
+
+typedef struct _GstVaapiSurface                 GstVaapiSurface;
+typedef struct _GstVaapiSurfacePrivate          GstVaapiSurfacePrivate;
+typedef struct _GstVaapiSurfaceClass            GstVaapiSurfaceClass;
+
+struct _GstVaapiSurface {
+    /*< private >*/
+    GObject parent_instance;
+
+    GstVaapiSurfacePrivate *priv;
+};
+
+struct _GstVaapiSurfaceClass {
+    /*< private >*/
+    GObjectClass parent_class;
+};
+
+GType
+gst_vaapi_surface_get_type(void);
+
+GstVaapiSurface *
+gst_vaapi_surface_new(GstVaapiDisplay *display,
+                      guint            width,
+                      guint            height,
+                      guint            format);
+
+VASurfaceID
+gst_vaapi_surface_get_id(GstVaapiSurface *surface);
+
+guint
+gst_vaapi_surface_get_width(GstVaapiSurface *surface);
+
+guint
+gst_vaapi_surface_get_height(GstVaapiSurface *surface);
+
+guint
+gst_vaapi_surface_get_format(GstVaapiSurface *surface);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_SURFACE_H */