2 * gstvaapivideobuffer.c - Gstreamer/VA video buffer
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Copyright (C) 2011-2013 Intel Corporation
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
24 * SECTION:gstvaapivideobuffer
25 * @short_description: VA video buffer for GStreamer
28 #include "gst/vaapi/sysdeps.h"
29 #include "gstvaapivideobuffer.h"
30 #if USE_X11 && !GST_CHECK_VERSION(1,1,0)
31 # include "gstvaapivideoconverter_x11.h"
33 #if USE_GLX && !GST_CHECK_VERSION(1,1,0)
34 # include "gstvaapivideoconverter_glx.h"
37 #if GST_CHECK_VERSION(1,1,0)
38 static inline GstBuffer *
39 gst_surface_buffer_new(void)
41 return gst_buffer_new();
43 #elif GST_CHECK_VERSION(1,0,0)
44 #include <gst/video/gstsurfacemeta.h>
46 #define GST_VAAPI_SURFACE_META_CAST(obj) \
47 ((GstVaapiSurfaceMeta *)(obj))
49 typedef struct _GstVaapiSurfaceMeta GstVaapiSurfaceMeta;
50 struct _GstVaapiSurfaceMeta {
55 #define GST_VAAPI_SURFACE_META_INFO gst_vaapi_surface_meta_get_info()
56 static const GstMetaInfo *
57 gst_vaapi_surface_meta_get_info(void);
59 typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)(
60 GstSurfaceMeta *meta, const gchar *type, GValue *dest);
63 static GstSurfaceConverter *
64 gst_vaapi_surface_create_converter_x11(GstSurfaceMeta *base_meta,
65 const gchar *type, GValue *dest)
67 GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta);
69 return gst_vaapi_video_converter_x11_new(meta->buffer, type, dest);
72 #undef gst_vaapi_video_converter_x11_new
73 #define gst_vaapi_video_converter_x11_new \
74 gst_vaapi_surface_create_converter_x11
78 static GstSurfaceConverter *
79 gst_vaapi_surface_create_converter_glx(GstSurfaceMeta *base_meta,
80 const gchar *type, GValue *dest)
82 GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta);
84 return gst_vaapi_video_converter_glx_new(meta->buffer, type, dest);
87 #undef gst_vaapi_video_converter_glx_new
88 #define gst_vaapi_video_converter_glx_new \
89 gst_vaapi_surface_create_converter_glx
92 static GstSurfaceConverter *
93 gst_vaapi_surface_create_converter(GstSurfaceMeta *base_meta,
94 const gchar *type, GValue *dest)
96 GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta);
97 GstVaapiVideoMeta * const vmeta =
98 gst_buffer_get_vaapi_video_meta(meta->buffer);
99 GstSurfaceConverterCreateFunc func;
101 if (G_UNLIKELY(!vmeta))
104 func = (GstSurfaceConverterCreateFunc)
105 gst_vaapi_video_meta_get_surface_converter(vmeta);
107 return func ? func(base_meta, type, dest) : NULL;
111 gst_vaapi_surface_meta_init(GstVaapiSurfaceMeta *meta, gpointer params,
114 meta->base.create_converter = gst_vaapi_surface_create_converter;
115 meta->buffer = buffer;
120 gst_vaapi_surface_meta_free(GstVaapiSurfaceMeta *meta, GstBuffer *buffer)
125 gst_vaapi_surface_meta_transform(GstBuffer *dst_buffer, GstMeta *meta,
126 GstBuffer *src_buffer, GQuark type, gpointer data)
128 GstVaapiVideoMeta * const src_vmeta =
129 gst_buffer_get_vaapi_video_meta(src_buffer);
131 if (GST_META_TRANSFORM_IS_COPY(type)) {
132 GstVaapiSurfaceMeta * const dst_smeta = GST_VAAPI_SURFACE_META_CAST(
133 gst_buffer_add_meta(dst_buffer, GST_VAAPI_SURFACE_META_INFO, NULL));
135 /* Note: avoid meta lookups in gst_vaapi_surface_create_converter()
136 by directly calling the GstVaapiVideoMeta::surface_converter hook */
137 dst_smeta->base.create_converter = (GstSurfaceConverterCreateFunc)
138 gst_vaapi_video_meta_get_surface_converter(src_vmeta);
145 gst_vaapi_surface_meta_get_info(void)
147 static gsize g_meta_info;
149 if (g_once_init_enter(&g_meta_info)) {
150 gsize meta_info = GPOINTER_TO_SIZE(gst_meta_register(
151 GST_SURFACE_META_API_TYPE,
152 "GstVaapiSurfaceMeta", sizeof(GstVaapiSurfaceMeta),
153 (GstMetaInitFunction)gst_vaapi_surface_meta_init,
154 (GstMetaFreeFunction)gst_vaapi_surface_meta_free,
155 (GstMetaTransformFunction)gst_vaapi_surface_meta_transform));
156 g_once_init_leave(&g_meta_info, meta_info);
158 return GSIZE_TO_POINTER(g_meta_info);
162 gst_surface_buffer_new(void)
164 GstBuffer * const buffer = gst_buffer_new();
167 gst_buffer_add_meta(buffer, GST_VAAPI_SURFACE_META_INFO, NULL);
171 #include <gst/video/gstsurfacebuffer.h>
173 #define GST_VAAPI_TYPE_VIDEO_BUFFER \
174 (gst_vaapi_video_buffer_get_type())
176 #define GST_VAAPI_VIDEO_BUFFER(obj) \
177 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
178 GST_VAAPI_TYPE_VIDEO_BUFFER, \
179 GstVaapiVideoBuffer))
181 #define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \
182 (G_TYPE_CHECK_CLASS_CAST((klass), \
183 GST_VAAPI_TYPE_VIDEO_BUFFER, \
184 GstVaapiVideoBufferClass))
186 #define GST_VAAPI_IS_VIDEO_BUFFER(obj) \
187 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_BUFFER))
189 #define GST_VAAPI_IS_VIDEO_BUFFER_CLASS(klass) \
190 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_BUFFER))
192 #define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \
193 (G_TYPE_INSTANCE_GET_CLASS((obj), \
194 GST_VAAPI_TYPE_VIDEO_BUFFER, \
195 GstVaapiVideoBufferClass))
197 typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass;
200 * GstVaapiVideoBuffer:
202 * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage).
204 struct _GstVaapiVideoBuffer {
206 GstSurfaceBuffer parent_instance;
210 * GstVaapiVideoBufferClass:
212 * A #GstBuffer holding video objects
214 struct _GstVaapiVideoBufferClass {
216 GstSurfaceBufferClass parent_class;
220 gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST;
222 G_DEFINE_TYPE(GstVaapiVideoBuffer,
223 gst_vaapi_video_buffer,
224 GST_TYPE_SURFACE_BUFFER)
226 typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)(
227 GstSurfaceBuffer *surface, const gchar *type, GValue *dest);
229 static GstSurfaceConverter *
230 gst_vaapi_video_buffer_create_converter(GstSurfaceBuffer *surface,
231 const gchar *type, GValue *dest)
233 GstVaapiVideoMeta * const meta =
234 gst_buffer_get_vaapi_video_meta(GST_BUFFER(surface));
235 GstSurfaceConverterCreateFunc func;
237 g_return_val_if_fail(meta != NULL, NULL);
239 func = (GstSurfaceConverterCreateFunc)
240 gst_vaapi_video_meta_get_surface_converter(meta);
242 return func ? func(surface, type, dest) : NULL;
246 gst_vaapi_video_buffer_class_init(GstVaapiVideoBufferClass *klass)
248 GstSurfaceBufferClass * const surface_class =
249 GST_SURFACE_BUFFER_CLASS(klass);
251 surface_class->create_converter = gst_vaapi_video_buffer_create_converter;
255 gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer)
259 static inline GstBuffer *
260 gst_surface_buffer_new(void)
262 return GST_BUFFER_CAST(gst_mini_object_new(GST_VAAPI_TYPE_VIDEO_BUFFER));
267 get_surface_converter(GstVaapiDisplay *display)
271 switch (gst_vaapi_display_get_display_type(display)) {
272 #if USE_X11 && !GST_CHECK_VERSION(1,1,0)
273 case GST_VAAPI_DISPLAY_TYPE_X11:
274 func = (GFunc)gst_vaapi_video_converter_x11_new;
277 #if USE_GLX && !GST_CHECK_VERSION(1,1,0)
278 case GST_VAAPI_DISPLAY_TYPE_GLX:
279 func = (GFunc)gst_vaapi_video_converter_glx_new;
290 new_vbuffer(GstVaapiVideoMeta *meta)
294 g_return_val_if_fail(meta != NULL, NULL);
296 gst_vaapi_video_meta_set_surface_converter(meta,
297 get_surface_converter(gst_vaapi_video_meta_get_display(meta)));
299 buffer = gst_surface_buffer_new();
301 gst_buffer_set_vaapi_video_meta(buffer, meta);
302 gst_vaapi_video_meta_unref(meta);
307 gst_vaapi_video_buffer_new(GstVaapiVideoMeta *meta)
309 g_return_val_if_fail(meta != NULL, NULL);
311 return new_vbuffer(gst_vaapi_video_meta_ref(meta));
315 gst_vaapi_video_buffer_new_from_pool(GstVaapiVideoPool *pool)
317 return new_vbuffer(gst_vaapi_video_meta_new_from_pool(pool));
321 gst_vaapi_video_buffer_new_from_buffer(GstBuffer *buffer)
323 GstVaapiVideoMeta * const meta = gst_buffer_get_vaapi_video_meta(buffer);
325 return meta ? new_vbuffer(gst_vaapi_video_meta_ref(meta)) : NULL;
329 gst_vaapi_video_buffer_new_with_image(GstVaapiImage *image)
331 return new_vbuffer(gst_vaapi_video_meta_new_with_image(image));
335 gst_vaapi_video_buffer_new_with_surface(GstVaapiSurface *surface)
337 return new_vbuffer(gst_vaapi_video_meta_new_with_surface(surface));
341 gst_vaapi_video_buffer_new_with_surface_proxy(GstVaapiSurfaceProxy *proxy)
343 return new_vbuffer(gst_vaapi_video_meta_new_with_surface_proxy(proxy));