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.
This commit is contained in:
Gwenole Beauchesne 2015-02-20 15:13:03 +01:00
parent 8c93c842ef
commit 6a465ae793
5 changed files with 112 additions and 4 deletions

View file

@ -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)
@ -297,6 +301,43 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture,
*height_ptr = GST_VAAPI_TEXTURE_HEIGHT (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

View file

@ -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,

View file

@ -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 ();

View file

@ -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,

View file

@ -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));