summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2013-07-09 19:08:37 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2013-07-10 17:03:47 +0200
commita1b27c920b6c03d7770ece1ab6ec77a31a95559f (patch)
tree5e3bc25ecdbf6658523b34a16af98a3a0be861dd
parente3da054e482b85a80c4e323db1195237f8dd32ce (diff)
surface: allow creation with explicit pixel format.
Make it possible to create VA surfaces with a specific pixel format. This is a new capability brought in by VA-API >= 0.34.0. If that capability is not built-in (e.g. using VA-API < 0.34.0), then gst_vaapi_surface_new_with_format() will return NULL.
-rw-r--r--docs/reference/libs/libs-sections.txt2
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurface.c117
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurface.h15
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurface_priv.h13
4 files changed, 144 insertions, 3 deletions
diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt
index bd0229c3..827067ca 100644
--- a/docs/reference/libs/libs-sections.txt
+++ b/docs/reference/libs/libs-sections.txt
@@ -209,8 +209,10 @@ GstVaapiSurfaceRenderFlags
<TITLE>GstVaapiSurface</TITLE>
GstVaapiSurface
gst_vaapi_surface_new
+gst_vaapi_surface_new_with_format
gst_vaapi_surface_get_id
gst_vaapi_surface_get_chroma_type
+gst_vaapi_surface_get_format
gst_vaapi_surface_get_width
gst_vaapi_surface_get_height
gst_vaapi_surface_get_size
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c
index 9cd129d0..17535164 100644
--- a/gst-libs/gst/vaapi/gstvaapisurface.c
+++ b/gst-libs/gst/vaapi/gstvaapisurface.c
@@ -118,6 +118,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface,
if (!vaapi_check_status(status, "vaCreateSurfaces()"))
return FALSE;
+ surface->format = GST_VIDEO_FORMAT_ENCODED;
surface->chroma_type = chroma_type;
surface->width = width;
surface->height = height;
@@ -132,6 +133,64 @@ error_unsupported_chroma_type:
return FALSE;
}
+static gboolean
+gst_vaapi_surface_create_with_format(GstVaapiSurface *surface,
+ GstVideoFormat format, guint width, guint height)
+{
+#if VA_CHECK_VERSION(0,34,0)
+ GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface);
+ VASurfaceID surface_id;
+ VAStatus status;
+ guint chroma_type, va_chroma_format;
+ const VAImageFormat *va_format;
+ VASurfaceAttrib attrib;
+
+ va_format = gst_video_format_to_va_format(format);
+ if (!va_format)
+ goto error_unsupported_format;
+
+ chroma_type = gst_video_format_get_chroma_type(format);
+ if (!chroma_type)
+ goto error_unsupported_format;
+
+ va_chroma_format = from_GstVaapiChromaType(chroma_type);
+ if (!va_chroma_format)
+ goto error_unsupported_format;
+
+ attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
+ attrib.type = VASurfaceAttribPixelFormat;
+ attrib.value.type = VAGenericValueTypeInteger;
+ attrib.value.value.i = va_format->fourcc;
+
+ GST_VAAPI_DISPLAY_LOCK(display);
+ status = vaCreateSurfaces(
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
+ va_chroma_format, width, height,
+ &surface_id, 1,
+ &attrib, 1
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ if (!vaapi_check_status(status, "vaCreateSurfaces()"))
+ return FALSE;
+
+ surface->format = format;
+ surface->chroma_type = chroma_type;
+ surface->width = width;
+ surface->height = height;
+
+ GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id));
+ GST_VAAPI_OBJECT_ID(surface) = surface_id;
+ return TRUE;
+
+ /* ERRORS */
+error_unsupported_format:
+ GST_ERROR("unsupported format %u", gst_video_format_to_string(format));
+ return FALSE;
+#else
+ return FALSE;
+#endif
+}
+
#define gst_vaapi_surface_finalize gst_vaapi_surface_destroy
GST_VAAPI_OBJECT_DEFINE_CLASS(GstVaapiSurface, gst_vaapi_surface)
@@ -173,6 +232,46 @@ error:
}
/**
+ * gst_vaapi_surface_new_with_format:
+ * @display: a #GstVaapiDisplay
+ * @format: the surface format
+ * @width: the requested surface width
+ * @height: the requested surface height
+ *
+ * Creates a new #GstVaapiSurface with the specified pixel format and
+ * dimensions.
+ *
+ * Return value: the newly allocated #GstVaapiSurface object, or %NULL
+ * if creation of VA surface with explicit pixel format is not
+ * supported or failed.
+ */
+GstVaapiSurface *
+gst_vaapi_surface_new_with_format(
+ GstVaapiDisplay *display,
+ GstVideoFormat format,
+ guint width,
+ guint height
+)
+{
+ GstVaapiSurface *surface;
+
+ GST_DEBUG("size %ux%u, format %s", width, height,
+ gst_video_format_to_string(format));
+
+ surface = gst_vaapi_object_new(gst_vaapi_surface_class(), display);
+ if (!surface)
+ return NULL;
+
+ if (!gst_vaapi_surface_create_with_format(surface, format, width, height))
+ goto error;
+ return surface;
+
+error:
+ gst_vaapi_object_unref(surface);
+ return NULL;
+}
+
+/**
* gst_vaapi_surface_get_id:
* @surface: a #GstVaapiSurface
*
@@ -205,6 +304,24 @@ gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface)
}
/**
+ * gst_vaapi_surface_get_format:
+ * @surface: a #GstVaapiSurface
+ *
+ * Returns the #GstVideoFormat the @surface was created with.
+ *
+ * Return value: the #GstVideoFormat, or %GST_VIDEO_FORMAT_ENCODED if
+ * the surface was not created with an explicit video format, or if
+ * the underlying video format could not be determined
+ */
+GstVideoFormat
+gst_vaapi_surface_get_format(GstVaapiSurface *surface)
+{
+ g_return_val_if_fail(surface != NULL, 0);
+
+ return GST_VAAPI_SURFACE_FORMAT(surface);
+}
+
+/**
* gst_vaapi_surface_get_width:
* @surface: a #GstVaapiSurface
*
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h
index e6ceacca..13dbf4f9 100644
--- a/gst-libs/gst/vaapi/gstvaapisurface.h
+++ b/gst-libs/gst/vaapi/gstvaapisurface.h
@@ -27,6 +27,7 @@
#include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapiimage.h>
#include <gst/vaapi/gstvaapisubpicture.h>
+#include <gst/video/video.h>
#include <gst/video/video-overlay-composition.h>
G_BEGIN_DECLS
@@ -53,9 +54,6 @@ G_BEGIN_DECLS
/**
* GstVaapiChromaType:
- * @GST_VAAPI_CHROMA_TYPE_YUV420: 4:2:0 chroma format
- * @GST_VAAPI_CHROMA_TYPE_YUV422: 4:2:2 chroma format
- * @GST_VAAPI_CHROMA_TYPE_YUV444: 4:4:4 chroma format
* @GST_VAAPI_CHROMA_TYPE_YUV420: YUV 4:2:0 chroma format
* @GST_VAAPI_CHROMA_TYPE_YUV422: YUV 4:2:2 chroma format
* @GST_VAAPI_CHROMA_TYPE_YUV444: YUV 4:4:4 chroma format
@@ -139,12 +137,23 @@ gst_vaapi_surface_new(
guint height
);
+GstVaapiSurface *
+gst_vaapi_surface_new_with_format(
+ GstVaapiDisplay *display,
+ GstVideoFormat format,
+ guint width,
+ guint height
+);
+
GstVaapiID
gst_vaapi_surface_get_id(GstVaapiSurface *surface);
GstVaapiChromaType
gst_vaapi_surface_get_chroma_type(GstVaapiSurface *surface);
+GstVideoFormat
+gst_vaapi_surface_get_format(GstVaapiSurface *surface);
+
guint
gst_vaapi_surface_get_width(GstVaapiSurface *surface);
diff --git a/gst-libs/gst/vaapi/gstvaapisurface_priv.h b/gst-libs/gst/vaapi/gstvaapisurface_priv.h
index f7d04b8c..2114d721 100644
--- a/gst-libs/gst/vaapi/gstvaapisurface_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapisurface_priv.h
@@ -37,6 +37,7 @@ struct _GstVaapiSurface {
/*< private >*/
GstVaapiObject parent_instance;
+ GstVideoFormat format;
guint width;
guint height;
GstVaapiChromaType chroma_type;
@@ -67,6 +68,18 @@ struct _GstVaapiSurfaceClass {
GST_VAAPI_SURFACE(surface)->chroma_type
/**
+ * GST_VAAPI_SURFACE_SURFACE_FORMAT:
+ * @surface: a #GstVaapiSurface
+ *
+ * Macro that evaluates to the @surface format.
+ *
+ * This is an internal macro that does not do any run-time type check.
+ */
+#undef GST_VAAPI_SURFACE_FORMAT
+#define GST_VAAPI_SURFACE_FORMAT(surface) \
+ GST_VAAPI_SURFACE(surface)->format
+
+/**
* GST_VAAPI_SURFACE_SURFACE_WIDTH:
* @surface: a #GstVaapiSurface
*