2 * gstvaapivideobuffer.c - Gstreamer/VA video buffer
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6 * Copyright (C) 2011-2013 Intel Corporation
7 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA
26 * SECTION:gstvaapivideobuffer
27 * @short_description: VA video buffer for GStreamer
30 #include "gst/vaapi/sysdeps.h"
31 #include "gstvaapivideobuffer.h"
32 #if USE_X11 && !GST_CHECK_VERSION(1,1,0)
33 # include "gstvaapivideoconverter_x11.h"
35 #if USE_GLX && !GST_CHECK_VERSION(1,1,0)
36 # include "gstvaapivideoconverter_glx.h"
39 #if GST_CHECK_VERSION(1,1,0)
40 static inline GstBuffer *
41 gst_surface_buffer_new (void)
43 return gst_buffer_new ();
45 #elif GST_CHECK_VERSION(1,0,0)
46 #include <gst/video/gstsurfacemeta.h>
48 #define GST_VAAPI_SURFACE_META_CAST(obj) \
49 ((GstVaapiSurfaceMeta *) (obj))
51 typedef struct _GstVaapiSurfaceMeta GstVaapiSurfaceMeta;
52 struct _GstVaapiSurfaceMeta
58 #define GST_VAAPI_SURFACE_META_INFO \
59 gst_vaapi_surface_meta_get_info ()
61 static const GstMetaInfo *
62 gst_vaapi_surface_meta_get_info (void);
64 typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc) (GstSurfaceMeta *
65 meta, const gchar * type, GValue * dest);
68 static GstSurfaceConverter *
69 gst_vaapi_surface_create_converter_x11 (GstSurfaceMeta * base_meta,
70 const gchar * type, GValue * dest)
72 GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta);
74 return gst_vaapi_video_converter_x11_new (meta->buffer, type, dest);
77 #undef gst_vaapi_video_converter_x11_new
78 #define gst_vaapi_video_converter_x11_new \
79 gst_vaapi_surface_create_converter_x11
83 static GstSurfaceConverter *
84 gst_vaapi_surface_create_converter_glx (GstSurfaceMeta * base_meta,
85 const gchar * type, GValue * dest)
87 GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta);
89 return gst_vaapi_video_converter_glx_new (meta->buffer, type, dest);
92 #undef gst_vaapi_video_converter_glx_new
93 #define gst_vaapi_video_converter_glx_new \
94 gst_vaapi_surface_create_converter_glx
97 static GstSurfaceConverter *
98 gst_vaapi_surface_create_converter (GstSurfaceMeta * base_meta,
99 const gchar * type, GValue * dest)
101 GstVaapiSurfaceMeta *const meta = GST_VAAPI_SURFACE_META_CAST (base_meta);
102 GstVaapiVideoMeta *const vmeta =
103 gst_buffer_get_vaapi_video_meta (meta->buffer);
104 GstSurfaceConverterCreateFunc func;
106 if (G_UNLIKELY (!vmeta))
109 func = (GstSurfaceConverterCreateFunc)
110 gst_vaapi_video_meta_get_surface_converter (vmeta);
112 return func ? func (base_meta, type, dest) : NULL;
116 gst_vaapi_surface_meta_init (GstVaapiSurfaceMeta * meta, gpointer params,
119 meta->base.create_converter = gst_vaapi_surface_create_converter;
120 meta->buffer = buffer;
125 gst_vaapi_surface_meta_free (GstVaapiSurfaceMeta * meta, GstBuffer * buffer)
130 gst_vaapi_surface_meta_transform (GstBuffer * dst_buffer, GstMeta * meta,
131 GstBuffer * src_buffer, GQuark type, gpointer data)
133 GstVaapiVideoMeta *const src_vmeta =
134 gst_buffer_get_vaapi_video_meta (src_buffer);
136 if (GST_META_TRANSFORM_IS_COPY (type)) {
137 GstVaapiSurfaceMeta *const dst_smeta =
138 GST_VAAPI_SURFACE_META_CAST (gst_buffer_add_meta (dst_buffer,
139 GST_VAAPI_SURFACE_META_INFO, NULL));
141 /* Note: avoid meta lookups in gst_vaapi_surface_create_converter()
142 by directly calling the GstVaapiVideoMeta::surface_converter hook */
143 dst_smeta->base.create_converter = (GstSurfaceConverterCreateFunc)
144 gst_vaapi_video_meta_get_surface_converter (src_vmeta);
151 gst_vaapi_surface_meta_get_info (void)
153 static gsize g_meta_info;
155 if (g_once_init_enter (&g_meta_info)) {
157 GPOINTER_TO_SIZE (gst_meta_register (GST_SURFACE_META_API_TYPE,
158 "GstVaapiSurfaceMeta", sizeof (GstVaapiSurfaceMeta),
159 (GstMetaInitFunction) gst_vaapi_surface_meta_init,
160 (GstMetaFreeFunction) gst_vaapi_surface_meta_free,
161 (GstMetaTransformFunction) gst_vaapi_surface_meta_transform));
162 g_once_init_leave (&g_meta_info, meta_info);
164 return GSIZE_TO_POINTER (g_meta_info);
168 gst_surface_buffer_new (void)
170 GstBuffer *const buffer = gst_buffer_new ();
173 gst_buffer_add_meta (buffer, GST_VAAPI_SURFACE_META_INFO, NULL);
177 #include <gst/video/gstsurfacebuffer.h>
179 #define GST_VAAPI_TYPE_VIDEO_BUFFER \
180 (gst_vaapi_video_buffer_get_type ())
181 #define GST_VAAPI_VIDEO_BUFFER(obj) \
182 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER, \
183 GstVaapiVideoBuffer))
184 #define GST_VAAPI_VIDEO_BUFFER_CLASS(klass) \
185 (G_TYPE_CHECK_CLASS_CAST ((klass), GST_VAAPI_TYPE_VIDEO_BUFFER, \
186 GstVaapiVideoBufferClass))
187 #define GST_VAAPI_IS_VIDEO_BUFFER(obj) \
188 (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))
191 #define GST_VAAPI_VIDEO_BUFFER_GET_CLASS(obj) \
192 (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_VAAPI_TYPE_VIDEO_BUFFER, \
193 GstVaapiVideoBufferClass))
195 typedef struct _GstVaapiVideoBufferClass GstVaapiVideoBufferClass;
198 * GstVaapiVideoBuffer:
200 * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage).
202 struct _GstVaapiVideoBuffer
205 GstSurfaceBuffer parent_instance;
209 * GstVaapiVideoBufferClass:
211 * A #GstBuffer holding video objects
213 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, GST_TYPE_SURFACE_BUFFER);
225 typedef GstSurfaceConverter *
226 (*GstSurfaceConverterCreateFunc) (GstSurfaceBuffer * surface,
227 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 = GST_SURFACE_BUFFER_CLASS (klass);
250 surface_class->create_converter = gst_vaapi_video_buffer_create_converter;
254 gst_vaapi_video_buffer_init (GstVaapiVideoBuffer * buffer)
258 static inline GstBuffer *
259 gst_surface_buffer_new (void)
261 return GST_BUFFER_CAST (gst_mini_object_new (GST_VAAPI_TYPE_VIDEO_BUFFER));
266 get_surface_converter (GstVaapiDisplay * display)
270 switch (gst_vaapi_display_get_display_type (display)) {
271 #if USE_X11 && !GST_CHECK_VERSION(1,1,0)
272 case GST_VAAPI_DISPLAY_TYPE_X11:
273 func = (GFunc) gst_vaapi_video_converter_x11_new;
276 #if USE_GLX && !GST_CHECK_VERSION(1,1,0)
277 case GST_VAAPI_DISPLAY_TYPE_GLX:
278 func = (GFunc) gst_vaapi_video_converter_glx_new;
289 new_vbuffer (GstVaapiVideoMeta * meta)
293 g_return_val_if_fail (meta != NULL, NULL);
295 gst_vaapi_video_meta_set_surface_converter (meta,
296 get_surface_converter (gst_vaapi_video_meta_get_display (meta)));
298 buffer = gst_surface_buffer_new ();
300 gst_buffer_set_vaapi_video_meta (buffer, meta);
301 gst_vaapi_video_meta_unref (meta);
306 gst_vaapi_video_buffer_new (GstVaapiVideoMeta * meta)
308 g_return_val_if_fail (meta != NULL, NULL);
310 return new_vbuffer (gst_vaapi_video_meta_ref (meta));
314 gst_vaapi_video_buffer_new_empty (void)
316 return gst_surface_buffer_new ();
320 gst_vaapi_video_buffer_new_from_pool (GstVaapiVideoPool * pool)
322 return new_vbuffer (gst_vaapi_video_meta_new_from_pool (pool));
326 gst_vaapi_video_buffer_new_from_buffer (GstBuffer * buffer)
328 GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer);
330 return meta ? new_vbuffer (gst_vaapi_video_meta_ref (meta)) : NULL;
334 gst_vaapi_video_buffer_new_with_image (GstVaapiImage * image)
336 return new_vbuffer (gst_vaapi_video_meta_new_with_image (image));
340 gst_vaapi_video_buffer_new_with_surface_proxy (GstVaapiSurfaceProxy * proxy)
342 return new_vbuffer (gst_vaapi_video_meta_new_with_surface_proxy (proxy));