QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GStreamerLogging.cc
Go to the documentation of this file.
1#include "GStreamer.h"
2#include "GStreamerLogging.h"
4
5#include <QtCore/QString>
6
7#include <atomic>
8#include <memory>
9
10QGC_LOGGING_CATEGORY(GStreamerLoggingLog, "Video.GStreamer.GStreamerLogging")
11QGC_LOGGING_CATEGORY_ON(GStreamerAPILog, "Video.GStreamer.GStreamerAPI")
12
13namespace {
14
15std::atomic_bool g_externalPluginLoaderFailed {false};
16
17void glib_print_handler(const gchar *string)
18{
19 qCInfo(GStreamerLoggingLog) << string;
20}
21
22void glib_printerr_handler(const gchar *string)
23{
24 qCWarning(GStreamerLoggingLog) << string;
25}
26
27void glib_log_handler(const gchar *log_domain, GLogLevelFlags log_level,
28 const gchar *message, gpointer user_data)
29{
30 Q_UNUSED(user_data);
31 const QString domain = log_domain ? QString::fromUtf8(log_domain) : QStringLiteral("GLib");
32 const QString msg = QString::fromUtf8(message);
33
34 if (msg.contains(QStringLiteral("External plugin loader failed"), Qt::CaseInsensitive)) {
35 g_externalPluginLoaderFailed.store(true);
36 }
37
38 if (msg.contains(QStringLiteral("pygobject initialization failed"), Qt::CaseInsensitive)) {
39 qCDebug(GStreamerLoggingLog) << domain << msg;
40 return;
41 }
42
43 switch (log_level & G_LOG_LEVEL_MASK) {
44 case G_LOG_LEVEL_ERROR:
45 case G_LOG_LEVEL_CRITICAL:
46 qCCritical(GStreamerLoggingLog) << domain << msg;
47 break;
48 case G_LOG_LEVEL_WARNING:
49 qCWarning(GStreamerLoggingLog) << domain << msg;
50 break;
51 case G_LOG_LEVEL_MESSAGE:
52 case G_LOG_LEVEL_INFO:
53 qCInfo(GStreamerLoggingLog) << domain << msg;
54 break;
55 case G_LOG_LEVEL_DEBUG:
56 default:
57 qCDebug(GStreamerLoggingLog) << domain << msg;
58 break;
59 }
60}
61
62} // anonymous namespace
63
64namespace GStreamer
65{
66
68{
69 g_externalPluginLoaderFailed.store(false);
70}
71
73{
74 return g_externalPluginLoaderFailed.load();
75}
76
78{
79 g_set_print_handler(glib_print_handler);
80 g_set_printerr_handler(glib_printerr_handler);
81 g_log_set_default_handler(glib_log_handler, nullptr);
82}
83
84void qtGstLog(GstDebugCategory *category,
85 GstDebugLevel level,
86 const gchar *file,
87 const gchar *function,
88 gint line,
89 GObject *object,
90 GstDebugMessage *message,
91 gpointer data)
92{
93 Q_UNUSED(data);
94
95 if (level > gst_debug_category_get_threshold(category)) {
96 return;
97 }
98
99 QMessageLogger log(file, line, function);
100
101 struct GFree { void operator()(gchar *p) const { g_free(p); } };
102 const std::unique_ptr<gchar, GFree> object_info(
103 gst_info_strdup_printf("%" GST_PTR_FORMAT, object));
104
105 switch (level) {
106 case GST_LEVEL_ERROR:
107 log.critical(GStreamerAPILog, "%s %s", object_info.get(), gst_debug_message_get(message));
108 break;
109 case GST_LEVEL_WARNING:
110 log.warning(GStreamerAPILog, "%s %s", object_info.get(), gst_debug_message_get(message));
111 break;
112 case GST_LEVEL_FIXME:
113 case GST_LEVEL_INFO:
114 log.info(GStreamerAPILog, "%s %s", object_info.get(), gst_debug_message_get(message));
115 break;
116 case GST_LEVEL_DEBUG:
117#ifdef QT_DEBUG
118 // In release builds LOG/TRACE/MEMDUMP are intentionally dropped to reduce
119 // noise. Only debug builds route these verbose levels through Qt logging.
120 case GST_LEVEL_LOG:
121 case GST_LEVEL_TRACE:
122 case GST_LEVEL_MEMDUMP:
123#endif
124 log.debug(GStreamerAPILog, "%s %s", object_info.get(), gst_debug_message_get(message));
125 break;
126 default:
127 break;
128 }
129}
130
131} // namespace GStreamer
#define QGC_LOGGING_CATEGORY_ON(name, categoryStr)
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void qtGstLog(GstDebugCategory *category, GstDebugLevel level, const gchar *file, const gchar *function, gint line, GObject *object, GstDebugMessage *message, gpointer data)
bool didExternalPluginLoaderFail()
void redirectGLibLogging()
void resetExternalPluginLoaderFailure()