From 6a465ae79365d4db1c2ab428b8faca601f6676a8 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 20 Feb 2015 15:13:03 +0100 Subject: [PATCH] plugins: add support for GstVideoGLTextureOrientation. Add support for GstVideoGLTextureOrientation modes. In particular, add orientation flags to the GstVaapiTexture wrapper and the GLX implementations. Default mode is that texture memory is laid out with top lines first, left row first. Flags indicate whether the X or Y axis need to be inverted. --- gst-libs/gst/vaapi/gstvaapitexture.c | 41 +++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapitexture.h | 25 +++++++++++++++++++ gst-libs/gst/vaapi/gstvaapitexture_glx.c | 18 +++++++++++--- gst-libs/gst/vaapi/gstvaapitexture_priv.h | 5 ++++ gst/vaapi/gstvaapivideometa_texture.c | 27 ++++++++++++++++++++ 5 files changed, 112 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index 380c45e..0ff118c 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -39,6 +39,10 @@ #undef gst_vaapi_texture_unref #undef gst_vaapi_texture_replace +#define GST_VAAPI_TEXTURE_ORIENTATION_FLAGS \ + (GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED | \ + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED) + static void gst_vaapi_texture_init (GstVaapiTexture * texture, GstVaapiID id, guint target, guint format, guint width, guint height) @@ -298,6 +302,43 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture, } /** + * gst_vaapi_texture_get_orientation_flags: + * @texture: a #GstVaapiTexture + * + * Retrieves the texture memory layout flags, i.e. orientation. + * + * Return value: the #GstVaapiTextureOrientationFlags. + */ +guint +gst_vaapi_texture_get_orientation_flags (GstVaapiTexture * texture) +{ + g_return_val_if_fail (texture != NULL, 0); + + return GST_VAAPI_TEXTURE_FLAGS (texture) & + GST_VAAPI_TEXTURE_ORIENTATION_FLAGS; +} + +/** + * gst_vaapi_texture_set_orientation_flags: + * @texture: a #GstVaapiTexture + * @flags: a bitmask of #GstVaapiTextureOrientationFlags + * + * Reset the texture orientation flags to the supplied set of + * @flags. This completely replaces the previously installed + * flags. So, should they still be needed, then they shall be + * retrieved first with gst_vaapi_texture_get_orientation_flags(). + */ +void +gst_vaapi_texture_set_orientation_flags (GstVaapiTexture * texture, guint flags) +{ + g_return_if_fail (texture != NULL); + g_return_if_fail ((flags & ~GST_VAAPI_TEXTURE_ORIENTATION_FLAGS) == 0); + + GST_VAAPI_TEXTURE_FLAG_UNSET (texture, GST_VAAPI_TEXTURE_ORIENTATION_FLAGS); + GST_VAAPI_TEXTURE_FLAG_SET (texture, flags); +} + +/** * gst_vaapi_texture_put_surface: * @texture: a #GstVaapiTexture * @surface: a #GstVaapiSurface diff --git a/gst-libs/gst/vaapi/gstvaapitexture.h b/gst-libs/gst/vaapi/gstvaapitexture.h index 316d52d..529ae27 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.h +++ b/gst-libs/gst/vaapi/gstvaapitexture.h @@ -80,6 +80,24 @@ G_BEGIN_DECLS typedef struct _GstVaapiTexture GstVaapiTexture; +/** + * GstVaapiTextureOrientationFlags: + * @GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED: indicates whether + * the right row comes first in memory. + * @GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED: indicates whether + * the bottom line comes first in memory. + * + * Additional flags to indicate whether the texture data is organized + * in memory with the X or Y, or both, axis inverted. e.g. if only + * @GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED is set, this means + * that the bottom line comes first in memory, with pixels laid out + * from the left to the right. + */ +typedef enum { + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED = 1 << 31, + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED = 1 << 30, +} GstVaapiTextureOrientationFlags; + GstVaapiTexture * gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format, guint width, guint height); @@ -117,6 +135,13 @@ void gst_vaapi_texture_get_size (GstVaapiTexture * texture, guint * width_ptr, guint * height_ptr); +guint +gst_vaapi_texture_get_orientation_flags (GstVaapiTexture * texture); + +void +gst_vaapi_texture_set_orientation_flags (GstVaapiTexture * texture, + guint flags); + gboolean gst_vaapi_texture_put_surface (GstVaapiTexture * texture, GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, diff --git a/gst-libs/gst/vaapi/gstvaapitexture_glx.c b/gst-libs/gst/vaapi/gstvaapitexture_glx.c index 6dbe52a..abaac94 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_glx.c +++ b/gst-libs/gst/vaapi/gstvaapitexture_glx.c @@ -312,6 +312,12 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, GLContextState old_cs; gboolean success = FALSE; + const GLfloat *txc, *tyc; + static const GLfloat g_texcoords[2][2] = { + {0.0f, 1.0f}, + {1.0f, 0.0f}, + }; + status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture), GST_VAAPI_OBJECT_ID (surface), texture->pixo->pixmap, crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, @@ -339,16 +345,20 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture, goto out_unbind_fbo; } + flags = GST_VAAPI_TEXTURE_FLAGS (texture); + txc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED)]; + tyc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED)]; + glColor4f (1.0f, 1.0f, 1.0f, 1.0f); glBegin (GL_QUADS); { - glTexCoord2f (0.0f, 0.0f); + glTexCoord2f (txc[0], tyc[0]); glVertex2i (0, 0); - glTexCoord2f (0.0f, 1.0f); + glTexCoord2f (txc[0], tyc[1]); glVertex2i (0, base_texture->height); - glTexCoord2f (1.0f, 1.0f); + glTexCoord2f (txc[1], tyc[1]); glVertex2i (base_texture->width, base_texture->height); - glTexCoord2f (1.0f, 0.0f); + glTexCoord2f (txc[1], tyc[0]); glVertex2i (base_texture->width, 0); } glEnd (); diff --git a/gst-libs/gst/vaapi/gstvaapitexture_priv.h b/gst-libs/gst/vaapi/gstvaapitexture_priv.h index 1f69d22..782ae78 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture_priv.h +++ b/gst-libs/gst/vaapi/gstvaapitexture_priv.h @@ -85,6 +85,11 @@ G_BEGIN_DECLS #define GST_VAAPI_TEXTURE_HEIGHT(texture) \ (GST_VAAPI_TEXTURE (texture)->height) +#define GST_VAAPI_TEXTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS +#define GST_VAAPI_TEXTURE_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET +#define GST_VAAPI_TEXTURE_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET +#define GST_VAAPI_TEXTURE_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET + /* GstVaapiTextureClass hooks */ typedef gboolean (*GstVaapiTextureAllocateFunc) (GstVaapiTexture * texture); typedef gboolean (*GstVaapiTexturePutSurfaceFunc) (GstVaapiTexture * texture, diff --git a/gst/vaapi/gstvaapivideometa_texture.c b/gst/vaapi/gstvaapivideometa_texture.c index 5052145..64efdcd 100644 --- a/gst/vaapi/gstvaapivideometa_texture.c +++ b/gst/vaapi/gstvaapivideometa_texture.c @@ -46,6 +46,29 @@ struct _GstVaapiVideoMetaTexture guint height; }; +static guint +get_texture_orientation_flags (GstVideoGLTextureOrientation orientation) +{ + guint flags; + + switch (orientation) { + case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_FLIP: + flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED; + break; + case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_FLIP_Y_NORMAL: + flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED; + break; + case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_FLIP_Y_FLIP: + flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED | + GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED; + break; + default: + flags = 0; + break; + } + return flags; +} + static gboolean meta_texture_ensure_format (GstVaapiVideoMetaTexture * meta, GstVideoFormat format) @@ -170,6 +193,10 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta, return FALSE; gst_vaapi_texture_unref (texture); } + + gst_vaapi_texture_set_orientation_flags (meta_texture->texture, + get_texture_orientation_flags (meta->texture_orientation)); + return gst_vaapi_texture_put_surface (meta_texture->texture, surface, gst_vaapi_surface_proxy_get_crop_rect (proxy), gst_vaapi_video_meta_get_render_flags (vmeta)); -- 2.7.4