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 "gstcompat.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 (USE_GLX || USE_EGL)
40 struct _GstVaapiVideoMetaTexture
42 GstVaapiTexture *texture;
43 GstVideoGLTextureType texture_type[4];
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)
76 memset (meta->texture_type, 0, sizeof (meta->texture_type));
79 case GST_VIDEO_FORMAT_RGBA:
80 meta->gl_format = GL_RGBA;
81 meta->texture_type[0] = GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
83 case GST_VIDEO_FORMAT_BGRA:
84 meta->gl_format = GL_BGRA_EXT;
85 /* FIXME: add GST_VIDEO_GL_TEXTURE_TYPE_BGRA extension */
86 meta->texture_type[0] = GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
89 goto error_unsupported_format;
94 error_unsupported_format:
95 GST_ERROR ("unsupported texture format %s",
96 gst_video_format_to_string (format));
101 meta_texture_ensure_info_from_buffer (GstVaapiVideoMetaTexture * meta,
105 GstVideoFormat format;
107 if (!buffer || !(vmeta = gst_buffer_get_video_meta (buffer))) {
108 format = DEFAULT_FORMAT;
112 const GstVideoFormatInfo *const fmt_info =
113 gst_video_format_get_info (vmeta->format);
114 format = (fmt_info && GST_VIDEO_FORMAT_INFO_IS_RGB (fmt_info)) ?
115 vmeta->format : DEFAULT_FORMAT;
116 meta->width = vmeta->width;
117 meta->height = vmeta->height;
119 return meta_texture_ensure_format (meta, format);
123 meta_texture_free (GstVaapiVideoMetaTexture * meta)
125 if (G_UNLIKELY (!meta))
128 gst_mini_object_replace ((GstMiniObject **) & meta->texture, NULL);
129 g_slice_free (GstVaapiVideoMetaTexture, meta);
132 static GstVaapiVideoMetaTexture *
133 meta_texture_new (void)
135 GstVaapiVideoMetaTexture *meta;
137 meta = g_slice_new (GstVaapiVideoMetaTexture);
141 meta->texture = NULL;
142 if (!meta_texture_ensure_info_from_buffer (meta, NULL))
149 meta_texture_free (meta);
154 static GstVaapiVideoMetaTexture *
155 meta_texture_copy (GstVaapiVideoMetaTexture * meta)
157 GstVaapiVideoMetaTexture *copy;
159 copy = meta_texture_new ();
163 memcpy (copy->texture_type, meta->texture_type, sizeof (meta->texture_type));
164 copy->gl_format = meta->gl_format;
165 copy->width = meta->width;
166 copy->height = meta->height;
168 gst_mini_object_replace ((GstMiniObject **) & copy->texture,
169 (GstMiniObject *) meta->texture);
174 gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
177 GstVaapiVideoMeta *const vmeta =
178 gst_buffer_get_vaapi_video_meta (meta->buffer);
179 GstVaapiVideoMetaTexture *const meta_texture = meta->user_data;
180 GstVaapiSurfaceProxy *const proxy =
181 gst_vaapi_video_meta_get_surface_proxy (vmeta);
182 GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy);
183 GstVaapiDisplay *const dpy = gst_vaapi_surface_get_display (surface);
184 GstVaapiTexture *texture = NULL;
186 if (!gst_vaapi_display_has_opengl (dpy))
189 if (meta_texture->texture
190 /* Check whether VA display changed */
191 && GST_VAAPI_TEXTURE_DISPLAY (meta_texture->texture) == dpy
192 /* Check whether texture id changed */
193 && (gst_vaapi_texture_get_id (meta_texture->texture) == texture_id[0])) {
194 texture = meta_texture->texture;
198 /* FIXME: should we assume target? */
200 gst_vaapi_texture_new_wrapped (dpy, texture_id[0],
201 GL_TEXTURE_2D, meta_texture->gl_format, meta_texture->width,
202 meta_texture->height);
205 if (meta_texture->texture != texture) {
206 gst_mini_object_replace ((GstMiniObject **) & meta_texture->texture,
207 (GstMiniObject *) texture);
213 gst_vaapi_texture_set_orientation_flags (meta_texture->texture,
214 get_texture_orientation_flags (meta->texture_orientation));
216 return gst_vaapi_texture_put_surface (meta_texture->texture, surface,
217 gst_vaapi_surface_proxy_get_crop_rect (proxy),
218 gst_vaapi_video_meta_get_render_flags (vmeta));
222 gst_buffer_add_texture_upload_meta (GstBuffer * buffer)
224 GstVaapiVideoMetaTexture *meta_texture;
229 meta_texture = meta_texture_new ();
233 if (!meta_texture_ensure_info_from_buffer (meta_texture, buffer))
236 return (GstMeta *) gst_buffer_add_video_gl_texture_upload_meta (buffer,
237 GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, 1,
238 meta_texture->texture_type, gst_vaapi_texture_upload, meta_texture,
239 (GBoxedCopyFunc) meta_texture_copy, (GBoxedFreeFunc) meta_texture_free);
244 meta_texture_free (meta_texture);
250 gst_buffer_ensure_texture_upload_meta (GstBuffer * buffer)
252 GstVideoGLTextureUploadMeta *const meta =
253 gst_buffer_get_video_gl_texture_upload_meta (buffer);
256 meta_texture_ensure_info_from_buffer (meta->user_data, buffer) :
257 (gst_buffer_add_texture_upload_meta (buffer) != NULL);