VideoStreaming.cc 7.01 KB
Newer Older
1
/****************************************************************************
2
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/
9 10 11 12 13


/**
 * @file
 *   @brief QGC Video Streaming Initialization
Gus Grubba's avatar
Gus Grubba committed
14
 *   @author Gus Grubba <gus@auterion.com>
15 16 17 18 19
 */

#include <QtQml>
#include <QDebug>

20 21
#include "VideoReceiver.h"

22 23
#if defined(QGC_GST_STREAMING)
#include <gst/gst.h>
24 25 26 27 28 29 30 31 32 33 34 35 36

#include "QGCLoggingCategory.h"

QGC_LOGGING_CATEGORY(GstreamerLog, "GstreamerLog")

static void qt_gst_log(GstDebugCategory * category,
                       GstDebugLevel      level,
                       const gchar      * file,
                       const gchar      * function,
                       gint               line,
                       GObject          * object,
                       GstDebugMessage  * message,
                       gpointer           data)
37
{
38 39
    if (level > gst_debug_category_get_threshold(category)) {
        return;
40
    }
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

    QMessageLogger log(file, line, function);

    char* object_info = gst_info_strdup_printf("%" GST_PTR_FORMAT, static_cast<void*>(object));

    switch (level) {
    default:
    case GST_LEVEL_ERROR:
        log.critical(GstreamerLog, "%s %s", object_info, gst_debug_message_get(message));
        break;
    case GST_LEVEL_WARNING:
        log.warning(GstreamerLog, "%s %s", object_info, gst_debug_message_get(message));
        break;
    case GST_LEVEL_FIXME:
    case GST_LEVEL_INFO:
        log.info(GstreamerLog, "%s %s", object_info, gst_debug_message_get(message));
        break;
    case GST_LEVEL_DEBUG:
    case GST_LEVEL_LOG:
    case GST_LEVEL_TRACE:
    case GST_LEVEL_MEMDUMP:
        log.debug(GstreamerLog, "%s %s", object_info, gst_debug_message_get(message));
        break;
    }

    g_free(object_info);
    object_info = nullptr;
68
}
69 70

#if defined(__ios__)
71 72
#include "gst_ios_init.h"
#endif
73 74
#else
#include "GLVideoItemStub.h"
75 76 77 78 79 80 81
#endif

#include "VideoStreaming.h"

#if defined(QGC_GST_STREAMING)
    G_BEGIN_DECLS
    // The static plugins we use
82
#if defined(__android__) || defined(__ios__)
83
    GST_PLUGIN_STATIC_DECLARE(coreelements);
84
    GST_PLUGIN_STATIC_DECLARE(playback);
85 86
    GST_PLUGIN_STATIC_DECLARE(libav);
    GST_PLUGIN_STATIC_DECLARE(rtp);
87
    GST_PLUGIN_STATIC_DECLARE(rtsp);
88 89 90
    GST_PLUGIN_STATIC_DECLARE(udp);
    GST_PLUGIN_STATIC_DECLARE(videoparsersbad);
    GST_PLUGIN_STATIC_DECLARE(x264);
91
    GST_PLUGIN_STATIC_DECLARE(rtpmanager);
92 93
    GST_PLUGIN_STATIC_DECLARE(isomp4);
    GST_PLUGIN_STATIC_DECLARE(matroska);
94
    GST_PLUGIN_STATIC_DECLARE(mpegtsdemux);
95
    GST_PLUGIN_STATIC_DECLARE(opengl);
96 97
#if defined(__android__)
    GST_PLUGIN_STATIC_DECLARE(androidmedia);
98 99 100
#elif defined(__ios__)
    GST_PLUGIN_STATIC_DECLARE(applemedia);
#endif
101
#endif
102
    GST_PLUGIN_STATIC_DECLARE(qmlgl);
103
    GST_PLUGIN_STATIC_DECLARE(qgc);
104 105 106
    G_END_DECLS
#endif

dogmaphobic's avatar
dogmaphobic committed
107
#if defined(QGC_GST_STREAMING)
108
#if (defined(Q_OS_MAC) && defined(QGC_INSTALL_RELEASE)) || defined(Q_OS_WIN)
dogmaphobic's avatar
dogmaphobic committed
109 110 111 112 113 114
static void qgcputenv(const QString& key, const QString& root, const QString& path)
{
    QString value = root + path;
    qputenv(key.toStdString().c_str(), QByteArray(value.toStdString().c_str()));
}
#endif
Don Gagne's avatar
Don Gagne committed
115
#endif
dogmaphobic's avatar
dogmaphobic committed
116

117
void initializeVideoStreaming(int &argc, char* argv[], int gstDebuglevel)
118 119
{
#if defined(QGC_GST_STREAMING)
120
    #ifdef Q_OS_MAC
121 122 123 124 125 126 127 128 129 130
        #ifdef QGC_INSTALL_RELEASE
            QString currentDir = QCoreApplication::applicationDirPath();
            qgcputenv("GST_PLUGIN_SCANNER",           currentDir, "/../Frameworks/GStreamer.framework/Versions/1.0/libexec/gstreamer-1.0/gst-plugin-scanner");
            qgcputenv("GTK_PATH",                     currentDir, "/../Frameworks/GStreamer.framework/Versions/Current");
            qgcputenv("GIO_EXTRA_MODULES",            currentDir, "/../Frameworks/GStreamer.framework/Versions/Current/lib/gio/modules");
            qgcputenv("GST_PLUGIN_SYSTEM_PATH_1_0",   currentDir, "/../Frameworks/GStreamer.framework/Versions/Current/lib/gstreamer-1.0");
            qgcputenv("GST_PLUGIN_SYSTEM_PATH",       currentDir, "/../Frameworks/GStreamer.framework/Versions/Current/lib/gstreamer-1.0");
            qgcputenv("GST_PLUGIN_PATH_1_0",          currentDir, "/../Frameworks/GStreamer.framework/Versions/Current/lib/gstreamer-1.0");
            qgcputenv("GST_PLUGIN_PATH",              currentDir, "/../Frameworks/GStreamer.framework/Versions/Current/lib/gstreamer-1.0");
        #endif
Don Gagne's avatar
Don Gagne committed
131 132 133
    #elif defined(Q_OS_WIN)
        QString currentDir = QCoreApplication::applicationDirPath();
        qgcputenv("GST_PLUGIN_PATH", currentDir, "/gstreamer-plugins");
134
    #endif
135

136 137 138 139 140
    //-- If gstreamer debugging is not configured via environment then use internal QT logging
    if (qgetenv("GST_DEBUG").isEmpty()) {
        gst_debug_set_default_threshold(static_cast<GstDebugLevel>(gstDebuglevel));
        gst_debug_remove_log_function(gst_debug_log_default);
        gst_debug_add_log_function(qt_gst_log, nullptr, nullptr);
141 142 143
    }

    // Initialize GStreamer
144
#if defined(__ios__)
145 146 147
    //-- iOS specific initialization
    gst_ios_pre_init();
#endif
148

149 150
    GError* error = nullptr;
    if (!gst_init_check(&argc, &argv, &error)) {
151
        qCCritical(VideoReceiverLog) << "gst_init_check() failed: " << error->message;
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
        g_error_free(error);
    }

    // The static plugins we use
#if defined(__android__) || defined(__ios__)
    GST_PLUGIN_STATIC_REGISTER(coreelements);
    GST_PLUGIN_STATIC_REGISTER(playback);
    GST_PLUGIN_STATIC_REGISTER(libav);
    GST_PLUGIN_STATIC_REGISTER(rtp);
    GST_PLUGIN_STATIC_REGISTER(rtsp);
    GST_PLUGIN_STATIC_REGISTER(udp);
    GST_PLUGIN_STATIC_REGISTER(videoparsersbad);
    GST_PLUGIN_STATIC_REGISTER(x264);
    GST_PLUGIN_STATIC_REGISTER(rtpmanager);
    GST_PLUGIN_STATIC_REGISTER(isomp4);
    GST_PLUGIN_STATIC_REGISTER(matroska);
168
    GST_PLUGIN_STATIC_REGISTER(mpegtsdemux);
169 170 171 172 173 174 175 176 177 178 179
    GST_PLUGIN_STATIC_REGISTER(opengl);

#if defined(__android__)
    GST_PLUGIN_STATIC_REGISTER(androidmedia);
#elif defined(__ios__)
    GST_PLUGIN_STATIC_REGISTER(applemedia);
#endif
#endif

#if defined(__ios__)
    gst_ios_post_init();
180
#endif
181

182 183 184 185
    /* the plugin must be loaded before loading the qml file to register the
     * GstGLVideoItem qml item
     * FIXME Add a QQmlExtensionPlugin into qmlglsink to register GstGLVideoItem
     * with the QML engine, then remove this */
186 187 188 189 190 191 192 193
    GstElement *sink = gst_element_factory_make("qmlglsink", nullptr);

    if (sink == nullptr) {
        GST_PLUGIN_STATIC_REGISTER(qmlgl);
        sink = gst_element_factory_make("qmlglsink", nullptr);
    }

    if (sink != nullptr) {
194
        gst_object_unref(sink);
195
        sink = nullptr;
196
    } else {
197
        qCCritical(VideoReceiverLog) << "unable to find qmlglsink - you need to build it yourself and add to GST_PLUGIN_PATH";
198
    }
199 200

    GST_PLUGIN_STATIC_REGISTER(qgc);
201
#else
202
    qmlRegisterType<GLVideoItemStub>("org.freedesktop.gstreamer.GLVideoItem", 1, 0, "GstGLVideoItem");
203 204
    Q_UNUSED(argc)
    Q_UNUSED(argv)
205
    Q_UNUSED(gstDebuglevel)
206
#endif
207
}