vaapidecode: handle flush() vmethod
[platform/upstream/gstreamer.git] / gst / vaapi / gstvaapivideoconverter_glx.c
1 /*
2  *  gstvaapivideoconverter_glx.c - Gst VA video converter
3  *
4  *  Copyright (C) 2011-2013 Intel Corporation
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
6  *  Copyright (C) 2011 Collabora Ltd.
7  *    Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
8  *
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.
13  *
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.
18  *
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
23  */
24
25 #include "gst/vaapi/sysdeps.h"
26 #include <gst/vaapi/gstvaapitexture_glx.h>
27 #include "gstvaapivideoconverter_glx.h"
28 #include "gstvaapivideoconverter_x11.h"
29 #include "gstvaapipluginutil.h"
30 #include "gstvaapivideometa.h"
31
32 #if GST_CHECK_VERSION(1,0,0)
33 typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *,
34     GstBuffer *);
35 #else
36 typedef gboolean (*GstSurfaceUploadFunction) (GstSurfaceConverter *,
37     GstSurfaceBuffer *);
38 #endif
39
40 static void
41 gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface * iface);
42
43 G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterGLX,
44     gst_vaapi_video_converter_glx,
45     G_TYPE_OBJECT,
46     G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER,
47         gst_vaapi_video_converter_glx_iface_init));
48
49 #define GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE(obj) \
50   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, \
51       GstVaapiVideoConverterGLXPrivate))
52
53 struct _GstVaapiVideoConverterGLXPrivate
54 {
55   GstVaapiTexture *texture;
56 };
57
58 static gboolean
59 gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self,
60     GstBuffer * buffer);
61
62 static void
63 gst_vaapi_video_converter_glx_dispose (GObject * object)
64 {
65   GstVaapiVideoConverterGLXPrivate *const priv =
66       GST_VAAPI_VIDEO_CONVERTER_GLX (object)->priv;
67
68   gst_vaapi_texture_replace (&priv->texture, NULL);
69
70   G_OBJECT_CLASS (gst_vaapi_video_converter_glx_parent_class)->dispose (object);
71 }
72
73 static void
74 gst_vaapi_video_converter_glx_class_init (GstVaapiVideoConverterGLXClass *
75     klass)
76 {
77   GObjectClass *const object_class = G_OBJECT_CLASS (klass);
78
79   g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterGLXPrivate));
80
81   object_class->dispose = gst_vaapi_video_converter_glx_dispose;
82 }
83
84 static void
85 gst_vaapi_video_converter_glx_init (GstVaapiVideoConverterGLX * buffer)
86 {
87   buffer->priv = GST_VAAPI_VIDEO_CONVERTER_GLX_GET_PRIVATE (buffer);
88 }
89
90 static void
91 gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface * iface)
92 {
93   iface->upload = (GstSurfaceUploadFunction)
94       gst_vaapi_video_converter_glx_upload;
95 }
96
97 /**
98  * gst_vaapi_video_converter_glx_new:
99  * @surface: the #GstSurfaceBuffer
100  * @type: type of the target buffer (must be "opengl")
101  * @dest: target of the conversion (must be GL texture id)
102  *
103  * Creates an empty #GstBuffer. The caller is responsible for
104  * completing the initialization of the buffer with the
105  * gst_vaapi_video_converter_glx_set_*() functions.
106  *
107  * Return value: the newly allocated #GstBuffer, or %NULL on error
108  */
109 GstSurfaceConverter *
110 gst_vaapi_video_converter_glx_new (GstBuffer * buffer, const gchar * type,
111     GValue * dest)
112 {
113   GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer);
114   GstVaapiTexture *texture;
115   GstVaapiVideoConverterGLX *converter;
116
117   /* Check for "opengl" request, or chain up to X11 converter */
118   if (strcmp (type, "opengl") != 0 || !G_VALUE_HOLDS_UINT (dest))
119     return gst_vaapi_video_converter_x11_new (buffer, type, dest);
120
121   /* FIXME Should we assume target and format ? */
122   texture =
123       gst_vaapi_texture_glx_new_wrapped (gst_vaapi_video_meta_get_display
124       (meta), g_value_get_uint (dest), GL_TEXTURE_2D, GL_BGRA);
125   if (!texture)
126     return NULL;
127
128   converter = g_object_new (GST_VAAPI_TYPE_VIDEO_CONVERTER_GLX, NULL);
129   converter->priv->texture = texture;
130   return GST_SURFACE_CONVERTER (converter);
131 }
132
133 gboolean
134 gst_vaapi_video_converter_glx_upload (GstSurfaceConverter * self,
135     GstBuffer * buffer)
136 {
137   GstVaapiVideoConverterGLXPrivate *const priv =
138       GST_VAAPI_VIDEO_CONVERTER_GLX (self)->priv;
139   GstVaapiVideoMeta *const meta = gst_buffer_get_vaapi_video_meta (buffer);
140   GstVaapiSurfaceProxy *const proxy =
141       gst_vaapi_video_meta_get_surface_proxy (meta);
142   GstVaapiSurface *const surface = gst_vaapi_surface_proxy_get_surface (proxy);
143   GstVaapiDisplay *new_dpy, *old_dpy;
144
145   new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface));
146   old_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->texture));
147
148   if (old_dpy != new_dpy) {
149     const guint texture = gst_vaapi_texture_get_id (priv->texture);
150
151     gst_vaapi_texture_replace (&priv->texture, NULL);
152     priv->texture = gst_vaapi_texture_glx_new_wrapped (new_dpy,
153         texture, GL_TEXTURE_2D, GL_BGRA);
154   }
155
156   if (!gst_vaapi_apply_composition (surface, buffer))
157     GST_WARNING ("could not update subtitles");
158
159   return gst_vaapi_texture_put_surface (priv->texture, surface,
160       gst_vaapi_surface_proxy_get_crop_rect (proxy),
161       gst_vaapi_video_meta_get_render_flags (meta));
162 }