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) \
--- /dev/null
+/*
+ * 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];
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 */