QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
VideoBackend.cc
Go to the documentation of this file.
1#include "VideoBackend.h"
2
3#include "AppMessages.h"
4#include "QGCApplication.h"
5
6#include <QtCore/QThread>
7#include <QtQuick/QQuickWindow>
8
9#ifdef QGC_GST_STREAMING
10#include "GStreamer.h"
11#include "GStreamerHelpers.h"
12#include "SettingsManager.h"
13#include "VideoSettings.h"
14#include "Fact.h"
15#else
17#endif
18
19#ifdef QGC_GST_STREAMING
20namespace {
21
22bool d3d12ZeroCopyUnsupported()
23{
24#if defined(Q_OS_WIN) && defined(QGC_HAS_GST_D3D12_GPU_PATH)
25 return QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D12 ||
26 qEnvironmentVariable("QSG_RHI_BACKEND").compare(QLatin1String("d3d12"), Qt::CaseInsensitive) == 0;
27#else
28 return false;
29#endif
30}
31
32} // namespace
33#endif
34
35bool VideoBackend::gpuZeroCopyAllowedForCurrentGraphicsApi(bool forceCpuVideoPath, bool forceSoftwareDecoder)
36{
37#ifdef QGC_GST_STREAMING
38 return !forceCpuVideoPath && !forceSoftwareDecoder && !d3d12ZeroCopyUnsupported();
39#else
40 Q_UNUSED(forceCpuVideoPath);
41 Q_UNUSED(forceSoftwareDecoder);
42 return false;
43#endif
44}
45
47{
48#ifdef QGC_GST_STREAMING
49 return GStreamer::createVideoReceiver(parent);
50#else
52#endif
53}
54
55void *VideoBackend::createSink(QQuickItem *widget, QObject *parent)
56{
57 [[maybe_unused]] const bool onGuiThread = (QThread::currentThread() == qApp->thread());
58 Q_ASSERT(onGuiThread);
59#ifdef QGC_GST_STREAMING
60 Q_UNUSED(widget);
61 Q_UNUSED(parent);
64 config.conversionElement = vs->videoConversionElement()->rawValue().toString().toUtf8();
65 config.disablePixelAspectRatio = vs->disablePixelAspectRatio()->rawValue().toBool();
66 const bool forceCpu = vs->forceCpuVideoPath()->rawValue().toBool();
67 const bool swDecoder = vs->forceVideoDecoder()->rawValue().toInt() == GStreamer::ForceVideoDecoderSoftware;
68 config.gpuZeroCopy = gpuZeroCopyAllowedForCurrentGraphicsApi(forceCpu, swDecoder);
70#else
71 return QtMultimediaReceiver::createVideoSink(widget, parent);
72#endif
73}
74
76{
77#ifdef QGC_GST_STREAMING
79#else
81#endif
82}
83
85{
86 return qgcApp() && QGC::runningUnitTests() && !qEnvironmentVariableIsSet("QGC_TEST_ENABLE_GSTREAMER");
87}
88
90{
91#ifdef QGC_GST_STREAMING
93 return { r.ok, r.error };
94#else
95 return {};
96#endif
97}
98
99bool VideoBackend::initialize(const QStringList &arguments, const EnvPrepResult &envResult)
100{
101#ifdef QGC_GST_STREAMING
102 return GStreamer::initialize(arguments, { envResult.ok, envResult.error });
103#else
104 Q_UNUSED(arguments);
105 Q_UNUSED(envResult);
106 return true;
107#endif
108}
109
111{
112#ifdef QGC_GST_STREAMING
114#else
115 Q_UNUSED(rawOption);
116#endif
117}
118
119void VideoBackend::onMainWindowReady(QQuickWindow *window)
120{
121#ifdef QGC_GST_STREAMING
123#else
124 Q_UNUSED(window);
125#endif
126}
127
128void VideoBackend::bindDebugLevelFact(Fact *fact, QObject *context)
129{
130#ifdef QGC_GST_STREAMING
131 GStreamer::bindDebugLevelFact(fact, context);
132#else
133 Q_UNUSED(fact);
134 Q_UNUSED(context);
135#endif
136}
137
138void VideoBackend::attachSink(QObject *receiver, void *sink, QQuickItem *widget)
139{
140#ifdef QGC_GST_STREAMING
141 GStreamer::attachAppSink(receiver, sink, widget);
142#else
143 Q_UNUSED(receiver);
144 Q_UNUSED(sink);
145 Q_UNUSED(widget);
146#endif
147}
Config config
#define qgcApp()
#define qApp
A Fact is used to hold a single value within the system.
Definition Fact.h:17
static VideoReceiver * createVideoReceiver(QObject *parent)
static void releaseVideoSink(void *sink)
static void * createVideoSink(QQuickItem *widget, QObject *parent=nullptr)
static SettingsManager * instance()
VideoSettings * videoSettings() const
void bindDebugLevelFact(Fact *fact, QObject *context)
Definition GStreamer.cc:387
void onMainWindowReady(QQuickWindow *window)
Definition GStreamer.cc:449
VideoReceiver * createVideoReceiver(QObject *parent)
Definition GStreamer.cc:312
void setCodecPriorities(int rawOption)
Overload taking the raw forceVideoDecoder setting value; the cast/range-check lives in the impl.
void releaseVideoSink(void *sink)
Definition GStreamer.cc:304
void * createVideoSink(const VideoSinkConfig &config)
Definition GStreamer.cc:276
bool initialize(const QStringList &arguments, const Environment::ValidationResult &envResult)
Definition GStreamer.cc:258
void attachAppSink(QObject *receiver, void *sink, QQuickItem *widget)
Definition GStreamer.cc:367
@ ForceVideoDecoderSoftware
Definition GStreamer.h:20
Environment::ValidationResult prepareEnvironment()
Definition GStreamer.cc:159
bool runningUnitTests()
EnvPrepResult prepareEnvironment()
bool initialize(const QStringList &arguments, const EnvPrepResult &envResult)
bool gpuZeroCopyAllowedForCurrentGraphicsApi(bool forceCpuVideoPath, bool forceSoftwareDecoder)
Applies backend-wide sink policy before constructing the GStreamer sink.
void applyDecoderPriorities(int rawOption)
void releaseSink(void *sink)
void attachSink(QObject *receiver, void *sink, QQuickItem *widget)
void onMainWindowReady(QQuickWindow *window)
bool disabledForUnitTests()
True when the backend should be skipped under unit tests (opt back in with QGC_TEST_ENABLE_GSTREAMER)...
void * createSink(QQuickItem *widget, QObject *parent)
VideoReceiver * createReceiver(QObject *parent)
void bindDebugLevelFact(Fact *fact, QObject *context)