Tizen 2.0 Release
[framework/multimedia/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapivideoconverter_glx.c
1 /*
2  *  gstvaapivideoconverter_glx.c - Gst VA video converter
3  *
4  *  Copyright (C) 2011 Intel Corporation
5  *  Copyright (C) 2011 Collabora Ltd.
6  *    Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public License
10  *  as published by the Free Software Foundation; either version 2.1
11  *  of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free
20  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301 USA
22  */
23
24 #include "sysdeps.h"
25 #include <string.h>
26 #include "gstvaapivideoconverter_glx.h"
27 #include "gstvaapivideobuffer.h"
28 #include "gstvaapitexture.h"
29
30 static void gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface *iface);
31
32 G_DEFINE_TYPE_WITH_CODE (GstVaapiVideoConverterGLX, gst_vaapi_video_converter_glx,
33                          G_TYPE_OBJECT,
34                          G_IMPLEMENT_INTERFACE (GST_TYPE_SURFACE_CONVERTER,
35                                                 gst_vaapi_video_converter_glx_iface_init));
36
37 struct _GstVaapiVideoConverterGLXPrivate {
38     GstVaapiTexture *texture;
39 };
40
41 static void
42 gst_vaapi_video_converter_glx_dispose(GObject *object)
43 {
44     GstVaapiVideoConverterGLXPrivate *priv =
45       GST_VAAPI_VIDEO_CONVERTER_GLX (object)->priv;
46
47     g_clear_object(&priv->texture);
48
49     G_OBJECT_CLASS (gst_vaapi_video_converter_glx_parent_class)->dispose (object);
50 }
51
52 static void
53 gst_vaapi_video_converter_glx_class_init(GstVaapiVideoConverterGLXClass *klass)
54 {
55     GObjectClass *object_class = G_OBJECT_CLASS (klass);
56
57     g_type_class_add_private (klass, sizeof (GstVaapiVideoConverterGLXPrivate));
58     object_class->dispose = gst_vaapi_video_converter_glx_dispose;
59 }
60
61 static void
62 gst_vaapi_video_converter_glx_init(GstVaapiVideoConverterGLX *buffer)
63 {
64     buffer->priv = G_TYPE_INSTANCE_GET_PRIVATE(buffer,
65                                                GST_VAAPI_TYPE_VIDEO_CONVERTER,
66                                                GstVaapiVideoConverterGLXPrivate);
67 }
68
69 static void
70 gst_vaapi_video_converter_glx_iface_init (GstSurfaceConverterInterface *iface) {
71   iface->upload = gst_vaapi_video_converter_glx_upload;
72 }
73
74 /**
75  * gst_vaapi_video_converter_glx_new:
76  * @surface: the #GstSurfaceBuffer
77  * @type: type of the target buffer (must be "opengl")
78  * @dest: target of the conversion (must be GL texture id)
79  *
80  * Creates an empty #GstBuffer. The caller is responsible for
81  * completing the initialization of the buffer with the
82  * gst_vaapi_video_converter_glx_set_*() functions.
83  *
84  * Return value: the newly allocated #GstBuffer, or %NULL on error
85  */
86 GstSurfaceConverter *
87 gst_vaapi_video_converter_glx_new(GstSurfaceBuffer *surface, const gchar *type,
88     GValue *dest)
89 {
90     GstVaapiVideoBuffer *buffer = GST_VAAPI_VIDEO_BUFFER (surface);
91     GstVaapiDisplay *display = gst_vaapi_video_buffer_get_display (buffer);
92     GstVaapiTexture *texture;
93     GstVaapiVideoConverterGLX *converter = NULL;
94
95     /* We only support Open GL texture conversion */
96     if (strcmp(type, "opengl") || !G_VALUE_HOLDS_UINT (dest))
97         return NULL;
98
99     /* FIXME Should we assume target and format ? */
100     texture = gst_vaapi_texture_new_with_texture (display,
101                                                   g_value_get_uint (dest),
102                                                   GL_TEXTURE_2D,
103                                                   GL_BGRA);
104
105     if (texture) {
106       converter = g_object_new (GST_VAAPI_TYPE_VIDEO_CONVERTER, NULL);
107       converter->priv->texture = texture;
108     }
109
110     return GST_SURFACE_CONVERTER (converter);
111 }
112
113 gboolean
114 gst_vaapi_video_converter_glx_upload (GstSurfaceConverter *converter,
115     GstSurfaceBuffer *buffer)
116 {
117   GstVaapiVideoConverterGLXPrivate *priv =
118     GST_VAAPI_VIDEO_CONVERTER_GLX (converter)->priv;
119   GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER (buffer);
120   GstVaapiSurface *surface = gst_vaapi_video_buffer_get_surface (vbuffer);
121   GstVaapiDisplay *new_dpy, *old_dpy;
122   GstVideoOverlayComposition * const composition =
123     gst_video_buffer_get_overlay_composition (GST_BUFFER (buffer));
124
125   new_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface));
126   old_dpy = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (priv->texture));
127
128   if (old_dpy != new_dpy) {
129     guint texture = gst_vaapi_texture_get_id (priv->texture);
130     g_object_unref (priv->texture);
131     priv->texture = gst_vaapi_texture_new_with_texture (new_dpy,
132                                                         texture,
133                                                         GL_TEXTURE_2D,
134                                                         GL_BGRA);
135   }
136
137   if (!gst_vaapi_surface_set_subpictures_from_composition (surface,
138            composition, TRUE))
139         GST_WARNING ("could not update subtitles");
140
141   return gst_vaapi_texture_put_surface (priv->texture, surface,
142       gst_vaapi_video_buffer_get_render_flags (vbuffer));
143 }