gstreamer/gst/vaapi/gstvaapivideobuffer.c

344 lines
9.5 KiB
C
Raw Normal View History

2010-03-12 23:48:50 +00:00
/*
* gstvaapivideobuffer.c - Gstreamer/VA video buffer
2010-03-12 23:48:50 +00:00
*
* Copyright (C) 2010-2011 Splitted-Desktop Systems
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
* Copyright (C) 2011-2013 Intel Corporation
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
2010-03-12 23:48:50 +00:00
*
2011-06-14 11:51:41 +00:00
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
2010-03-12 23:48:50 +00:00
*
2011-06-14 11:51:41 +00:00
* This library is distributed in the hope that it will be useful,
2010-03-12 23:48:50 +00:00
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2011-06-14 11:51:41 +00:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
2010-03-12 23:48:50 +00:00
*
2011-06-14 11:51:41 +00:00
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
2010-03-12 23:48:50 +00:00
*/
2010-03-19 16:41:52 +00:00
/**
2010-03-24 08:16:32 +00:00
* SECTION:gstvaapivideobuffer
* @short_description: VA video buffer for GStreamer
2010-03-19 16:41:52 +00:00
*/
#include "gst/vaapi/sysdeps.h"
2010-03-12 23:48:50 +00:00
#include "gstvaapivideobuffer.h"
#if USE_X11 && !GST_CHECK_VERSION(1,1,0)
# include "gstvaapivideoconverter_x11.h"
#endif
#if USE_GLX && !GST_CHECK_VERSION(1,1,0)
# include "gstvaapivideoconverter_glx.h"
#endif
2010-03-12 23:48:50 +00:00
#if GST_CHECK_VERSION(1,1,0)
static inline GstBuffer *
gst_surface_buffer_new (void)
{
return gst_buffer_new ();
}
#elif GST_CHECK_VERSION(1,0,0)
#include <gst/video/gstsurfacemeta.h>
#define GST_VAAPI_SURFACE_META_CAST(obj) \
((GstVaapiSurfaceMeta *) (obj))
typedef struct _GstVaapiSurfaceMeta GstVaapiSurfaceMeta;
struct _GstVaapiSurfaceMeta
{
GstSurfaceMeta base;
GstBuffer *buffer;
};
#define GST_VAAPI_SURFACE_META_INFO \
gst_vaapi_surface_meta_get_info ()
static const GstMetaInfo *
gst_vaapi_surface_meta_get_info (void);
typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc) (GstSurfaceMeta *
meta, const gchar * type, GValue * dest);
#if USE_X11
static GstSurfaceConverter *
gst_vaapi_surface_create_converter_x11 (GstSurfaceMeta * base_meta,
const gchar * type, GValue * dest)
{
GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta);
return gst_vaapi_video_converter_x11_new (meta->buffer, type, dest);
}
#undef gst_vaapi_video_converter_x11_new
#define gst_vaapi_video_converter_x11_new \
gst_vaapi_surface_create_converter_x11
#endif
#if USE_GLX
static GstSurfaceConverter *
gst_vaapi_surface_create_converter_glx (GstSurfaceMeta * base_meta,
const gchar * type, GValue * dest)
{
GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta);
return gst_vaapi_video_converter_glx_new (meta->buffer, type, dest);
}
#undef gst_vaapi_video_converter_glx_new
#define gst_vaapi_video_converter_glx_new \
gst_vaapi_surface_create_converter_glx
#endif
static GstSurfaceConverter *
gst_vaapi_surface_create_converter (GstSurfaceMeta * base_meta,
const gchar * type, GValue * dest)
{
GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta);
GstVaapiVideoMeta *const vmeta =
gst_buffer_get_vaapi_video_meta (meta->buffer);
GstSurfaceConverterCreateFunc func;
if (G_UNLIKELY (!vmeta))
return NULL;
func = (GstSurfaceConverterCreateFunc)
gst_vaapi_video_meta_get_surface_converter (vmeta);
return func ? func (base_meta, type, dest) : NULL;
}
static gboolean
gst_vaapi_surface_meta_init (GstVaapiSurfaceMeta * meta, gpointer params,
GstBuffer * buffer)
{
meta->base.create_converter = gst_vaapi_surface_create_converter;
meta->buffer = buffer;
return TRUE;
}
static void
gst_vaapi_surface_meta_free (GstVaapiSurfaceMeta * meta, GstBuffer * buffer)
{
}
static gboolean
gst_vaapi_surface_meta_transform (GstBuffer * dst_buffer, GstMeta * meta,
GstBuffer * src_buffer, GQuark type, gpointer data)
{
GstVaapiVideoMeta *const src_vmeta =
gst_buffer_get_vaapi_video_meta (src_buffer);
if (GST_META_TRANSFORM_IS_COPY (type)) {
GstVaapiSurfaceMeta *const dst_smeta =
GST_VAAPI_SURFACE_META_CAST (gst_buffer_add_meta (dst_buffer,
GST_VAAPI_SURFACE_META_INFO, NULL));
/* Note: avoid meta lookups in gst_vaapi_surface_create_converter()
by directly calling the GstVaapiVideoMeta::surface_converter hook */
dst_smeta->base.create_converter = (GstSurfaceConverterCreateFunc)
gst_vaapi_video_meta_get_surface_converter (src_vmeta);
return TRUE;
}
return FALSE;
}
const GstMetaInfo *
gst_vaapi_surface_meta_get_info (void)
{
static gsize g_meta_info;
if (g_once_init_enter (&g_meta_info)) {
gsize meta_info =
GPOINTER_TO_SIZE (gst_meta_register (GST_SURFACE_META_API_TYPE,
"GstVaapiSurfaceMeta", sizeof (GstVaapiSurfaceMeta),
(GstMetaInitFunction) gst_vaapi_surface_meta_init,
(GstMetaFreeFunction) gst_vaapi_surface_meta_free,
(GstMetaTransformFunction) gst_vaapi_surface_meta_transform));
g_once_init_leave (&g_meta_info, meta_info);
}
return GSIZE_TO_POINTER (g_meta_info);
}
static GstBuffer *
gst_surface_buffer_new (void)
{
GstBuffer *const buffer = gst_buffer_new ();
if (buffer)
gst_buffer_add_meta (buffer, GST_VAAPI_SURFACE_META_INFO, NULL);
return buffer;
}
#else
#include <gst/video/gstsurfacebuffer.h>
#define GST_VAAPI_TYPE_VIDEO_BUFFER \
(gst_vaapi_video_buffer_get_type ())
#define GST_VAAPI_VIDEO_BUFFER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER, \
GstVaapiVideoBuffer))
#define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER, \
GstVaapiVideoBufferClass))
#define GST_VAAPI_IS_VIDEO_BUFFER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER))
#define GST_VAAPI_IS_VIDEO_BUFFER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER))
#define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER, \
GstVaapiVideoBufferClass))
typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass;
/**
* GstVaapiVideoBuffer:
*
* A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage).
*/
struct _GstVaapiVideoBuffer
{
/*< private >*/
GstSurfaceBuffer parent_instance;
};
/**
* GstVaapiVideoBufferClass:
*
* A #GstBuffer holding video objects
*/
struct _GstVaapiVideoBufferClass
{
/*< private >*/
GstSurfaceBufferClass parent_class;
};
GType
gst_vaapi_video_buffer_get_type (void) G_GNUC_CONST;
2010-03-12 23:48:50 +00:00
G_DEFINE_TYPE (GstVaapiVideoBuffer,
gst_vaapi_video_buffer, GST_TYPE_SURFACE_BUFFER);
2010-03-12 23:48:50 +00:00
typedef GstSurfaceConverter *
(*GstSurfaceConverterCreateFunc) (GstSurfaceBuffer * surface,
const gchar * type, GValue * dest);
2010-03-12 23:48:50 +00:00
static GstSurfaceConverter *
gst_vaapi_video_buffer_create_converter (GstSurfaceBuffer * surface,
const gchar * type, GValue * dest)
{
GstVaapiVideoMeta *const meta =
gst_buffer_get_vaapi_video_meta (GST_BUFFER (surface));
GstSurfaceConverterCreateFunc func;
2010-03-12 23:48:50 +00:00
g_return_val_if_fail (meta != NULL, NULL);
func = (GstSurfaceConverterCreateFunc)
gst_vaapi_video_meta_get_surface_converter (meta);
return func ? func (surface, type, dest) : NULL;
2010-03-12 23:48:50 +00:00
}
static void
gst_vaapi_video_buffer_class_init (GstVaapiVideoBufferClass * klass)
2010-03-12 23:48:50 +00:00
{
GstSurfaceBufferClass *const surface_class = GST_SURFACE_BUFFER_CLASS (klass);
2010-03-12 23:48:50 +00:00
surface_class->create_converter = gst_vaapi_video_buffer_create_converter;
2010-03-12 23:48:50 +00:00
}
static void
gst_vaapi_video_buffer_init (GstVaapiVideoBuffer * buffer)
2010-03-12 23:48:50 +00:00
{
}
static inline GstBuffer *
gst_surface_buffer_new (void)
{
return GST_BUFFER_CAST (gst_mini_object_new (GST_VAAPI_TYPE_VIDEO_BUFFER));
}
#endif
static GFunc
get_surface_converter (GstVaapiDisplay * display)
{
GFunc func;
switch (gst_vaapi_display_get_display_type (display)) {
#if USE_X11 && !GST_CHECK_VERSION(1,1,0)
case GST_VAAPI_DISPLAY_TYPE_X11:
func = (GFunc) gst_vaapi_video_converter_x11_new;
break;
#endif
#if USE_GLX && !GST_CHECK_VERSION(1,1,0)
case GST_VAAPI_DISPLAY_TYPE_GLX:
func = (GFunc) gst_vaapi_video_converter_glx_new;
break;
#endif
default:
func = NULL;
break;
}
return func;
}
static GstBuffer *
new_vbuffer (GstVaapiVideoMeta * meta)
2010-04-29 21:56:10 +00:00
{
GstBuffer *buffer;
g_return_val_if_fail (meta != NULL, NULL);
gst_vaapi_video_meta_set_surface_converter (meta,
get_surface_converter (gst_vaapi_video_meta_get_display (meta)));
buffer = gst_surface_buffer_new ();
if (buffer)
gst_buffer_set_vaapi_video_meta (buffer, meta);
gst_vaapi_video_meta_unref (meta);
return buffer;
2010-03-12 23:48:50 +00:00
}
GstBuffer *
gst_vaapi_video_buffer_new (GstVaapiVideoMeta * meta)
{
g_return_val_if_fail (meta != NULL, NULL);
return new_vbuffer (gst_vaapi_video_meta_ref (meta));
}
GstBuffer *
gst_vaapi_video_buffer_new_empty (void)
{
return gst_surface_buffer_new ();
}
GstBuffer *
gst_vaapi_video_buffer_new_from_pool (GstVaapiVideoPool * pool)
{
return new_vbuffer (gst_vaapi_video_meta_new_from_pool (pool));
}
GstBuffer *
gst_vaapi_video_buffer_new_from_buffer (GstBuffer * buffer)
{
GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer);
return meta ? new_vbuffer (gst_vaapi_video_meta_ref (meta)) : NULL;
}
GstBuffer *
gst_vaapi_video_buffer_new_with_image (GstVaapiImage * image)
{
return new_vbuffer (gst_vaapi_video_meta_new_with_image (image));
}
GstBuffer *
gst_vaapi_video_buffer_new_with_surface_proxy (GstVaapiSurfaceProxy * proxy)
{
return new_vbuffer (gst_vaapi_video_meta_new_with_surface_proxy (proxy));
}