3 * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
4 * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
5 * Copyright (C) 2010 Nuno Santos <nunosantos@imaginando.net>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 #include <QApplication>
25 #include <QCloseEvent>
27 #include <gst/video/video.h>
28 #include <gst/gl/gstglmemory.h>
30 #include "gstthread.h"
31 #include "qglrenderer.h"
35 extern void *qt_current_nsopengl_context();
38 QGLRenderer::QGLRenderer(const QString &videoLocation,
41 videoLoc(videoLocation),
50 QGLRenderer::~QGLRenderer()
55 QGLRenderer::initializeGL()
57 GstGLContext *context;
58 GstGLDisplay *display;
60 display = gst_gl_display_new ();
62 /* FIXME: Allow the choice at runtime */
63 #if defined(GST_GL_HAVE_PLATFORM_WGL)
64 context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (), GST_GL_PLATFORM_WGL, GST_GL_API_OPENGL);
65 #elif defined (GST_GL_HAVE_PLATFORM_CGL)
66 context = gst_gl_context_new_wrapped (display, (guintptr) qt_current_nsopengl_context(), GST_GL_PLATFORM_CGL, GST_GL_API_OPENGL);
67 #elif defined(GST_GL_HAVE_PLATFORM_GLX)
68 context = gst_gl_context_new_wrapped (display, (guintptr) glXGetCurrentContext (), GST_GL_PLATFORM_GLX, GST_GL_API_OPENGL);
70 gst_object_unref (display);
72 // We need to unset Qt context before initializing gst-gl plugin.
73 // Otherwise the attempt to share gst-gl context with Qt will fail.
76 new GstThread(context, this->videoLoc, SLOT(newFrame()), this);
79 QObject::connect(this->gst_thread, SIGNAL(finished()),
81 QObject::connect(this, SIGNAL(closeRequested()),
82 this->gst_thread, SLOT(stop()), Qt::QueuedConnection);
84 qglClearColor(QApplication::palette().color(QPalette::Active,
86 //glShadeModel(GL_FLAT);
87 //glEnable(GL_DEPTH_TEST);
88 //glEnable(GL_CULL_FACE);
89 glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
91 this->gst_thread->start();
95 QGLRenderer::resizeGL(int width, int height)
97 // Reset The Current Viewport And Perspective Transformation
98 glViewport(0, 0, width, height);
100 glMatrixMode(GL_PROJECTION);
103 gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
104 glMatrixMode(GL_MODELVIEW);
108 QGLRenderer::newFrame()
110 Pipeline *pipeline = this->gst_thread->getPipeline();
114 /* frame is initialized as null */
116 pipeline->queue_output_buf.put(this->frame);
118 this->frame = pipeline->queue_input_buf.get();
120 /* direct call to paintGL (no queued) */
125 QGLRenderer::paintGL()
127 static GLfloat xrot = 0;
128 static GLfloat yrot = 0;
129 static GLfloat zrot = 0;
136 GstVideoFrame v_frame;
137 GstVideoMeta *v_meta;
139 mem = gst_buffer_peek_memory (this->frame, 0);
140 v_meta = gst_buffer_get_video_meta (this->frame);
142 if (gst_is_gl_memory (mem)) {
143 gst_video_info_set_format (&v_info, v_meta->format, v_meta->width,
146 gst_video_frame_map (&v_frame, &v_info, this->frame,
147 (GstMapFlags) (GST_MAP_READ | GST_MAP_GL));
149 tex_id = *(guint *) v_frame.data[0];
152 glEnable(GL_DEPTH_TEST);
154 glEnable(GL_TEXTURE_2D);
155 glBindTexture(GL_TEXTURE_2D, tex_id);
156 if(glGetError () != GL_NO_ERROR)
158 qDebug ("failed to bind texture that comes from gst-gl");
159 emit closeRequested();
163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
169 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
171 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
172 glMatrixMode(GL_MODELVIEW);
175 glTranslatef(0.0f,0.0f,-5.0f);
177 glRotatef(xrot,1.0f,0.0f,0.0f);
178 glRotatef(yrot,0.0f,1.0f,0.0f);
179 glRotatef(zrot,0.0f,0.0f,1.0f);
183 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
184 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
185 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
186 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
188 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
189 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
190 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
191 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
193 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
194 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
195 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
196 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
198 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
199 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
200 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
201 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
203 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
204 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
205 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
206 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
208 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
209 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
210 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
211 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
218 glBindTexture(GL_TEXTURE_2D, 0);
223 QGLRenderer::closeEvent(QCloseEvent* event)
225 if(this->closing == false)
227 this->closing = true;
228 emit closeRequested();