2 * gstvaapivideometa_texture.c - GStreamer/VA video meta (GLTextureUpload)
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6 * Copyright (C) 2011-2014 Intel Corporation
7 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8 * Copyright (C) 2013 Igalia
9 * Author: Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free
23 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301 USA
27 #include "gst/vaapi/sysdeps.h"
28 #include "gst/vaapi/ogl_compat.h"
29 #include "gstvaapivideometa.h"
30 #include "gstvaapivideometa_texture.h"
31 #include "gstvaapipluginutil.h"
34 #include <gst/vaapi/gstvaapitexture_glx.h>
37 #define DEFAULT_FORMAT GST_VIDEO_FORMAT_RGBA
39 #if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
40 struct _GstVaapiVideoMetaTexture
42 GstVaapiTexture *texture;
43 GstVideoGLTextureType texture_type;
50 get_texture_orientation_flags (GstVideoGLTextureOrientation orientation)
54 switch (orientation) {
55 case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_FLIP:
56 flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED;
58 case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_FLIP_Y_NORMAL:
59 flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED;
61 case GST_VIDEO_GL_TEXTURE_ORIENTATION_X_FLIP_Y_FLIP:
62 flags = GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED |
63 GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED;
73 meta_texture_ensure_format (GstVaapiVideoMetaTexture * meta,
74 GstVideoFormat format)
77 case GST_VIDEO_FORMAT_RGBA:
78 meta->gl_format = GL_RGBA;
79 meta->texture_type = GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
81 case GST_VIDEO_FORMAT_BGRA:
82 meta->gl_format = GL_BGRA_EXT;
83 /* FIXME: add GST_VIDEO_GL_TEXTURE_TYPE_BGRA extension */
84 meta->texture_type = GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
87 goto error_unsupported_format;
92 error_unsupported_format:
93 GST_ERROR ("unsupported texture format %s",
94 gst_video_format_to_string (format));
99 meta_texture_ensure_info_from_buffer (GstVaapiVideoMetaTexture * meta,
103 GstVideoFormat format;
105 if (!buffer || !(vmeta = gst_buffer_get_video_meta (buffer))) {
106 format = DEFAULT_FORMAT;
110 const GstVideoFormatInfo *const fmt_info =
111 gst_video_format_get_info (vmeta->format);
112 format = (fmt_info && GST_VIDEO_FORMAT_INFO_IS_RGB (fmt_info)) ?
113 vmeta->format : DEFAULT_FORMAT;
114 meta->width = vmeta->width;
115 meta->height = vmeta->height;
117 return meta_texture_ensure_format (meta, format);
121 meta_texture_free (GstVaapiVideoMetaTexture * meta)
123 if (G_UNLIKELY (!meta))
126 gst_vaapi_texture_replace (&meta->texture, NULL);
127 g_slice_free (GstVaapiVideoMetaTexture, meta);
130 static GstVaapiVideoMetaTexture *
131 meta_texture_new (void)
133 GstVaapiVideoMetaTexture *meta;
135 meta = g_slice_new (GstVaapiVideoMetaTexture);
139 meta->texture = NULL;
140 if (!meta_texture_ensure_info_from_buffer (meta, NULL))
145 meta_texture_free (meta);
149 static GstVaapiVideoMetaTexture *
150 meta_texture_copy (GstVaapiVideoMetaTexture * meta)
152 GstVaapiVideoMetaTexture *copy;
154 copy = meta_texture_new ();
158 copy->texture_type = meta->texture_type;
159 copy->gl_format = meta->gl_format;
160 copy->width = meta->width;
161 copy->height = meta->height;
162 gst_vaapi_texture_replace (©->texture, meta->texture);
167 gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
170 GstVaapiVideoMeta *const vmeta =
171 gst_buffer_get_vaapi_video_meta (meta->buffer);
172 GstVaapiVideoMetaTexture *const meta_texture = meta->user_data;
173 GstVaapiSurfaceProxy *const proxy =
174 gst_vaapi_video_meta_get_surface_proxy (vmeta);
175 GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy);
176 GstVaapiDisplay *const dpy = GST_VAAPI_OBJECT_DISPLAY (surface);
178 if (!gst_vaapi_display_has_opengl (dpy))
181 if (!meta_texture->texture ||
182 /* Check whether VA display changed */
183 GST_VAAPI_OBJECT_DISPLAY (meta_texture->texture) != dpy ||
184 /* Check whether texture id changed */
185 gst_vaapi_texture_get_id (meta_texture->texture) != texture_id[0]) {
186 /* FIXME: should we assume target? */
187 GstVaapiTexture *const texture =
188 gst_vaapi_texture_new_wrapped (dpy, texture_id[0],
189 GL_TEXTURE_2D, meta_texture->gl_format, meta_texture->width,
190 meta_texture->height);
191 gst_vaapi_texture_replace (&meta_texture->texture, texture);
194 gst_vaapi_texture_unref (texture);
197 gst_vaapi_texture_set_orientation_flags (meta_texture->texture,
198 get_texture_orientation_flags (meta->texture_orientation));
200 return gst_vaapi_texture_put_surface (meta_texture->texture, surface,
201 gst_vaapi_surface_proxy_get_crop_rect (proxy),
202 gst_vaapi_video_meta_get_render_flags (vmeta));
206 gst_buffer_add_texture_upload_meta (GstBuffer * buffer)
208 GstVideoGLTextureUploadMeta *meta = NULL;
209 GstVaapiVideoMetaTexture *meta_texture;
214 meta_texture = meta_texture_new ();
218 if (!meta_texture_ensure_info_from_buffer (meta_texture, buffer))
221 meta = gst_buffer_add_video_gl_texture_upload_meta (buffer,
222 GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL,
223 1, &meta_texture->texture_type, gst_vaapi_texture_upload,
224 meta_texture, (GBoxedCopyFunc) meta_texture_copy,
225 (GBoxedFreeFunc) meta_texture_free);
231 meta_texture_free (meta_texture);
236 gst_buffer_ensure_texture_upload_meta (GstBuffer * buffer)
238 GstVideoGLTextureUploadMeta *const meta =
239 gst_buffer_get_video_gl_texture_upload_meta (buffer);
242 meta_texture_ensure_info_from_buffer (meta->user_data, buffer) :
243 gst_buffer_add_texture_upload_meta (buffer);