]> git.sesse.net Git - mlt/blob - src/modules/qt/consumer_qglsl.cpp
Fix clock hand for down direction
[mlt] / src / modules / qt / consumer_qglsl.cpp
1 /*
2  * consumer_qglsl.cpp
3  * Copyright (C) 2012 Dan Dennedy <dan@dennedy.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <framework/mlt.h>
21 #include <QApplication>
22 #include <QLocale>
23 #include <QGLWidget>
24 #include <QMutex>
25 #include <QWaitCondition>
26
27 #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
28 #include <X11/Xlib.h>
29 #endif
30
31 class GLWidget : public QGLWidget
32 {
33 private:
34         QGLWidget *renderContext;
35         bool isInitialized;
36         QMutex mutex;
37         QWaitCondition condition;
38
39 public:
40         GLWidget()
41 #ifdef Q_OS_MAC
42                 : QGLWidget()
43 #else
44                 : QGLWidget(0, 0, Qt::SplashScreen)
45 #endif
46                 , renderContext(0)
47                 , isInitialized(false)
48         {
49                 resize(0, 0);
50                 show();
51         }
52
53         ~GLWidget()
54         {
55                 delete renderContext;
56         }
57
58         bool createRenderContext()
59         {
60                 if (!isInitialized) {
61                         mutex.lock();
62                         condition.wait(&mutex);
63                         mutex.unlock();
64                 }
65                 if (!renderContext) {
66                         renderContext = new QGLWidget(0, this, Qt::SplashScreen);
67                         renderContext->resize(0, 0);
68                         renderContext->makeCurrent();
69                 }
70                 return renderContext->isValid();
71         }
72
73 protected:
74         void initializeGL()
75         {
76                 condition.wakeAll();
77                 isInitialized = true;
78         }
79 };
80
81 static void onThreadStarted(mlt_properties owner, mlt_consumer consumer)
82 {
83         mlt_service service = MLT_CONSUMER_SERVICE(consumer);
84         mlt_properties properties = MLT_CONSUMER_PROPERTIES(consumer);
85         mlt_filter filter = (mlt_filter) mlt_properties_get_data(properties, "glslManager", NULL);
86         mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter);
87
88         mlt_log_debug(service, "%s\n", __FUNCTION__);
89         GLWidget *widget = (GLWidget*) mlt_properties_get_data(properties, "GLWidget", NULL);
90         if (widget->createRenderContext()) {
91                 mlt_events_fire(filter_properties, "init glsl", NULL);
92                 if (!mlt_properties_get_int(filter_properties, "glsl_supported")) {
93                         mlt_log_fatal(service,
94                                 "OpenGL Shading Language rendering is not supported on this machine.\n" );
95                         mlt_events_fire(properties, "consumer-fatal-error", NULL);
96                 }
97         }
98 }
99
100 static void onCleanup(mlt_properties owner, mlt_consumer consumer)
101 {
102         GLWidget* widget = (GLWidget*) mlt_properties_get_data( MLT_CONSUMER_PROPERTIES(consumer), "GLWidget", NULL);
103         delete widget;
104         mlt_properties_set_data(MLT_CONSUMER_PROPERTIES(consumer), "GLWidget", NULL, 0, NULL, NULL);
105         qApp->processEvents();
106 }
107
108 extern "C" {
109
110 mlt_consumer consumer_qglsl_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
111 {
112         mlt_consumer consumer = mlt_factory_consumer(profile, "multi", arg);
113         if (consumer) {
114                 mlt_filter filter = mlt_factory_filter(profile, "glsl.manager", 0);
115                 if (filter) {
116 #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
117                         XInitThreads();
118 #endif
119                         mlt_properties properties = MLT_CONSUMER_PROPERTIES(consumer);
120                         mlt_properties_set_data(properties, "glslManager", filter, 0, (mlt_destructor) mlt_filter_close, NULL);
121                         mlt_events_register( properties, "consumer-cleanup", NULL );
122                         mlt_events_listen(properties, consumer, "consumer-thread-started", (mlt_listener) onThreadStarted);
123                         mlt_events_listen(properties, consumer, "consumer-cleanup", (mlt_listener) onCleanup);
124 #ifdef linux
125                         if ( getenv("DISPLAY") == 0 ) {
126                                 mlt_log_error(MLT_CONSUMER_SERVICE(consumer), "The qglsl consumer requires a X11 environment.\nPlease either run melt from an X session or use a fake X server like xvfb:\nxvfb-run -a melt (...)\n" );
127                         } else
128 #endif
129                         if (!qApp) {
130                                 int argc = 1;
131                                 char* argv[1];
132                                 argv[0] = (char*) "MLT qglsl consumer";
133                                 new QApplication(argc, argv);
134                                 const char *localename = mlt_properties_get_lcnumeric(properties);
135                                 QLocale::setDefault(QLocale(localename));
136                         }
137                         mlt_properties_set_data(properties, "GLWidget", new GLWidget, 0, NULL, NULL);
138                         qApp->processEvents();
139                         return consumer;
140                 }
141                 mlt_consumer_close(consumer);
142         }
143         return NULL;
144 }
145
146 }