]> git.sesse.net Git - vlc/blob - bindings/phonon/vlc/vlcloader.cpp
DirectSound: cosmetics and error path fix
[vlc] / bindings / phonon / vlc / vlcloader.cpp
1 /*****************************************************************************
2  * VLC backend for the Phonon library                                        *
3  * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com>               *
4  * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com>                *
5  * Copyright (C) 2009 Fathi Boudra <fabo@kde.org>                            *
6  *                                                                           *
7  * This program is free software; you can redistribute it and/or             *
8  * modify it under the terms of the GNU Lesser General Public                *
9  * License as published by the Free Software Foundation; either              *
10  * version 3 of the License, or (at your option) any later version.          *
11  *                                                                           *
12  * This program 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  * Lesser General Public License for more details.                           *
16  *                                                                           *
17  * You should have received a copy of the GNU Lesser General Public          *
18  * License along with this package; if not, write to the Free Software       *
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
20  *****************************************************************************/
21
22 #include "vlcloader.h"
23
24 #include <QtCore/QDebug>
25 #include <QtCore/QDir>
26 #include <QtCore/QLibrary>
27 #include <QtCore/QSettings>
28 #include <QtCore/QString>
29 #include <QtCore/QStringList>
30
31 // Global variables
32 libvlc_instance_t *vlc_instance = 0;
33 libvlc_exception_t *vlc_exception = new libvlc_exception_t();
34 libvlc_media_player_t *vlc_current_media_player = 0;
35
36 namespace Phonon
37 {
38 namespace VLC {
39
40 bool vlcInit()
41 {
42     // Global variables
43     vlc_instance = 0;
44     vlc_exception = new libvlc_exception_t();
45
46     QString path = vlcPath();
47     if (!path.isEmpty()) {
48         QString pluginsPath = QString("--plugin-path=") + QDir::toNativeSeparators(QFileInfo(vlcPath()).dir().path());
49 #if defined(Q_OS_UNIX)
50         pluginsPath.append("/vlc");
51 #elif defined(Q_OS_WIN)
52         pluginsPath.append("\\plugins");
53 #endif
54         QByteArray p = path.toLatin1();
55         QByteArray pp = pluginsPath.toLatin1();
56         // VLC command line options. See vlc --full-help
57         const char *vlcArgs[] = {
58             p.constData(),
59             pp.constData(),
60             "--verbose=2",
61             "--intf=dummy",
62             "--extraintf=logger",
63             "--ignore-config",
64             "--reset-plugins-cache",
65             "--no-media-library",
66             "--no-one-instance",
67             "--no-osd",
68             "--no-stats",
69             "--no-video-title-show"
70         };
71
72         libvlc_exception_init(vlc_exception);
73
74         // Create and initialize a libvlc instance (it should be done only once)
75         vlc_instance = libvlc_new(sizeof(vlcArgs) / sizeof(*vlcArgs),
76                                   vlcArgs,
77                                   vlc_exception);
78         vlcExceptionRaised();
79
80         return true;
81     } else {
82         return false;
83     }
84 }
85
86 void vlcRelease()
87 {
88     libvlc_release(vlc_instance);
89     vlcExceptionRaised();
90     vlcUnload();
91 }
92
93 void vlcExceptionRaised()
94 {
95     if (libvlc_exception_raised(vlc_exception)) {
96         qDebug() << "libvlc exception:" << libvlc_exception_get_message(vlc_exception);
97         libvlc_exception_clear(vlc_exception);
98     }
99 }
100
101 #if defined(Q_OS_UNIX)
102 static bool libGreaterThan(const QString &lhs, const QString &rhs)
103 {
104     QStringList lhsparts = lhs.split(QLatin1Char('.'));
105     QStringList rhsparts = rhs.split(QLatin1Char('.'));
106     Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
107
108     for (int i = 1; i < rhsparts.count(); ++i) {
109         if (lhsparts.count() <= i)
110             // left hand side is shorter, so it's less than rhs
111             return false;
112
113         bool ok = false;
114         int b = 0;
115         int a = lhsparts.at(i).toInt(&ok);
116         if (ok)
117             b = rhsparts.at(i).toInt(&ok);
118         if (ok) {
119             // both toInt succeeded
120             if (a == b)
121                 continue;
122             return a > b;
123         } else {
124             // compare as strings;
125             if (lhsparts.at(i) == rhsparts.at(i))
126                 continue;
127             return lhsparts.at(i) > rhsparts.at(i);
128         }
129     }
130
131     // they compared strictly equally so far
132     // lhs cannot be less than rhs
133     return true;
134 }
135 #endif
136
137 static QStringList findAllLibVlc()
138 {
139     QStringList paths;
140 #if defined(Q_OS_UNIX)
141     paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
142             .split(QLatin1Char(':'), QString::SkipEmptyParts);
143     paths << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
144
145     QStringList foundVlcs;
146     foreach (const QString &path, paths) {
147         QDir dir = QDir(path);
148         QStringList entryList = dir.entryList(QStringList() << QLatin1String("libvlc.*"), QDir::Files);
149
150         qSort(entryList.begin(), entryList.end(), libGreaterThan);
151         foreach (const QString &entry, entryList)
152             foundVlcs << path + QLatin1Char('/') + entry;
153     }
154
155     return foundVlcs;
156 #elif defined(Q_OS_WIN)
157     // Read VLC version and installation directory from Windows registry
158     QSettings settings(QSettings::SystemScope, "VideoLAN", "VLC");
159     QString vlcVersion = settings.value("Version").toString();
160     QString vlcInstallDir = settings.value("InstallDir").toString();
161     if (vlcVersion.startsWith("1.0") && !vlcInstallDir.isEmpty()) {
162         paths << vlcInstallDir + QLatin1Char('\\') + "libvlc.dll";
163         return paths;
164     } else {
165         return QString();
166     }
167 #endif
168 }
169
170 static QLibrary *vlcLibrary = 0;
171
172 QString vlcPath()
173 {
174     static QString path;
175     if (!path.isEmpty()) {
176         return path;
177     }
178
179     vlcLibrary = new QLibrary();
180     QStringList paths = findAllLibVlc();
181     foreach(path, paths) {
182         vlcLibrary->setFileName(path);
183
184         if (vlcLibrary->resolve("libvlc_exception_init")) {
185             return path;
186         } else {
187             qDebug("Cannot resolve the symbol or load VLC library");
188         }
189         qWarning() << vlcLibrary->errorString();
190     }
191
192     vlcUnload();
193
194     return QString();
195 }
196
197 void vlcUnload()
198 {
199     vlcLibrary->unload();
200     delete vlcLibrary;
201     vlcLibrary = 0;
202 }
203
204 }
205 } // Namespace Phonon::VLC