Skip to content

Commit 21de26f

Browse files
committed
GStreamer: Add qml6d3d11 Video Sink
1 parent 4ae36ba commit 21de26f

File tree

13 files changed

+443
-40
lines changed

13 files changed

+443
-40
lines changed

.github/workflows/custom.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
env:
3737
ARTIFACT: QGroundControl-installer.exe
3838
QT_VERSION: 6.8.3
39-
GST_VERSION: 1.22.12
39+
GST_VERSION: 1.26.3
4040

4141
steps:
4242
- name: Checkout repo

.github/workflows/windows.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
ARTIFACT: QGroundControl-installer.exe
4040
PACKAGE: QGroundControl-installer
4141
QT_VERSION: 6.8.3
42-
GST_VERSION: 1.22.12
42+
GST_VERSION: 1.26.3
4343

4444
steps:
4545
- name: Checkout repo

cmake/find-modules/FindGStreamer.cmake

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
if(NOT DEFINED GStreamer_FIND_VERSION)
22
if(LINUX)
33
set(GStreamer_FIND_VERSION 1.20)
4+
elseif(WIN32)
5+
set(GStreamer_FIND_VERSION 1.26.3)
46
else()
57
set(GStreamer_FIND_VERSION 1.22.12)
68
endif()
@@ -225,18 +227,21 @@ endif()
225227

226228
################################################################################
227229

228-
if(GStreamer_USE_STATIC_LIBS)
229-
set(GSTREAMER_EXTRA_DEPS
230-
gstreamer-base-1.0
231-
gstreamer-video-1.0
232-
gstreamer-gl-1.0
233-
gstreamer-gl-prototypes-1.0
234-
gstreamer-rtsp-1.0
235-
# gstreamer-gl-egl-1.0
236-
# gstreamer-gl-wayland-1.0
237-
# gstreamer-gl-x11-1.0
238-
)
230+
set(GSTREAMER_EXTRA_DEPS
231+
gstreamer-base-1.0
232+
gstreamer-video-1.0
233+
gstreamer-rtsp-1.0
234+
gstreamer-gl-1.0
235+
gstreamer-gl-prototypes-1.0
236+
# gstreamer-gl-egl-1.0
237+
# gstreamer-gl-wayland-1.0
238+
# gstreamer-gl-x11-1.0
239+
)
240+
if(WIN32)
241+
list(APPEND GSTREAMER_EXTRA_DEPS gstreamer-d3d11-1.0)
242+
endif()
239243

244+
if(GStreamer_USE_STATIC_LIBS)
240245
set(GSTREAMER_PLUGINS
241246
coreelements
242247
dav1d
@@ -338,9 +343,9 @@ endfunction()
338343
find_gstreamer_component(Core gstreamer-1.0)
339344
find_gstreamer_component(Base gstreamer-base-1.0)
340345
find_gstreamer_component(Video gstreamer-video-1.0)
346+
find_gstreamer_component(Rtsp gstreamer-rtsp-1.0)
341347
find_gstreamer_component(Gl gstreamer-gl-1.0)
342348
find_gstreamer_component(GlPrototypes gstreamer-gl-prototypes-1.0)
343-
find_gstreamer_component(Rtsp gstreamer-rtsp-1.0)
344349

345350
################################################################################
346351

@@ -356,6 +361,10 @@ if(GlX11 IN_LIST GStreamer_FIND_COMPONENTS)
356361
find_gstreamer_component(GlX11 gstreamer-gl-x11-1.0)
357362
endif()
358363

364+
if(D3d11 IN_LIST GStreamer_FIND_COMPONENTS)
365+
find_gstreamer_component(D3d11 gstreamer-d3d11-1.0)
366+
endif()
367+
359368
################################################################################
360369

361370
include(FindPackageHandleStandardArgs)
@@ -405,11 +414,16 @@ if(GStreamer_FOUND AND NOT TARGET GStreamer::GStreamer)
405414
GStreamer::Core
406415
GStreamer::Base
407416
GStreamer::Video
417+
GStreamer::Rtsp
408418
GStreamer::Gl
409419
GStreamer::GlPrototypes
410-
GStreamer::Rtsp
411420
)
412421

422+
if(TARGET GStreamer::D3d11)
423+
target_compile_definitions(GStreamer::D3d11 INTERFACE GST_USE_UNSTABLE_API)
424+
target_link_libraries(GStreamer::GStreamer INTERFACE GStreamer::D3d11)
425+
endif()
426+
413427
foreach(component IN LISTS GStreamer_FIND_COMPONENTS)
414428
if(GStreamer_${component}_FOUND)
415429
target_link_libraries(GStreamer::GStreamer INTERFACE GStreamer::${component})

src/QGCApplication.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,13 @@ void QGCApplication::init()
330330
void QGCApplication::_initVideo()
331331
{
332332
#ifdef QGC_GST_STREAMING
333+
#ifdef Q_OS_WIN
334+
// Gstreamer video playback requires D3D11
335+
QQuickWindow::setGraphicsApi(QSGRendererInterface::Direct3D11);
336+
#else
333337
// Gstreamer video playback requires OpenGL
334338
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
339+
#endif
335340
#endif
336341

337342
QGCCorePlugin::instance(); // CorePlugin must be initialized before VideoManager for Video Cleanup

src/VideoManager/VideoManager.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ void VideoManager::registerQmlTypes()
7575
(void) qmlRegisterUncreatableType<VideoManager>("QGroundControl.VideoManager", 1, 0, "VideoManager", "Reference only");
7676
(void) qmlRegisterUncreatableType<VideoReceiver>("QGroundControl", 1, 0, "VideoReceiver","Reference only");
7777
#ifndef QGC_GST_STREAMING
78-
(void) qmlRegisterType<VideoItemStub>("org.freedesktop.gstreamer.Qt6GLVideoItem", 1, 0, "GstGLQt6VideoItem");
78+
#ifdef Q_OS_WIN
79+
(void) qmlRegisterType<GstVideoItemStub>("org.freedesktop.gstreamer.Qt6D3D11VideoItem", 1, 0, "GstD3D11Qt6VideoItem");
80+
#else
81+
(void) qmlRegisterType<GstVideoItemStub>("org.freedesktop.gstreamer.Qt6GLVideoItem", 1, 0, "GstGLQt6VideoItem");
82+
#endif
7983
#endif
8084
}
8185

src/VideoManager/VideoReceiver/GStreamer/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ if(QGC_ENABLE_GST_VIDEOSTREAMING)
66
# Using FindGStreamer.cmake is currently bypassed on MACOS since it doesn't work
77
# So for now we hack in a simple hardwired setup which does work
88
find_package(GStreamer
9+
COMPONENTS Core Base Video Rtsp Gl GlPrototypes
10+
OPTIONAL_COMPONENTS GlEgl GlWayland GlX11 D3d11
911
REQUIRED
10-
COMPONENTS Core Base Video Gl GlPrototypes Rtsp
11-
OPTIONAL_COMPONENTS GlEgl GlWayland GlX11)
12+
)
1213
endif()
1314

1415
add_subdirectory(gstqml6gl)
15-
# TODO: https://gstreamer.freedesktop.org/documentation/qt6d3d11/index.html#qml6d3d11sink-page
1616
endif()
1717

1818
if(TARGET gstqml6gl)

src/VideoManager/VideoReceiver/GStreamer/GStreamer.cc

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ GST_PLUGIN_STATIC_DECLARE(opengl);
4343
GST_PLUGIN_STATIC_DECLARE(openh264);
4444
GST_PLUGIN_STATIC_DECLARE(playback);
4545
GST_PLUGIN_STATIC_DECLARE(qml6);
46+
GST_PLUGIN_STATIC_DECLARE(qml6d3d11);
4647
GST_PLUGIN_STATIC_DECLARE(qsv);
4748
GST_PLUGIN_STATIC_DECLARE(rtp);
4849
GST_PLUGIN_STATIC_DECLARE(rtpmanager);
@@ -120,10 +121,19 @@ void _registerPlugins()
120121
#endif
121122
#endif
122123

123-
// #if !defined(GST_PLUGIN_qml6_FOUND) && defined(QGC_GST_STATIC_BUILD)
124-
GST_PLUGIN_STATIC_REGISTER(qml6);
124+
// #if !defined(GST_PLUGIN_qml6d3d11_FOUND) || defined(QGC_GST_STATIC_BUILD)
125+
// GST_PLUGIN_STATIC_REGISTER(qml6d3d11);
126+
// #endif
127+
128+
// #if !defined(GST_PLUGIN_qml6_FOUND) || defined(QGC_GST_STATIC_BUILD)
129+
// GST_PLUGIN_STATIC_REGISTER(qml6);
125130
// #endif
126131

132+
GST_PLUGIN_STATIC_REGISTER(qml6);
133+
#ifdef Q_OS_WIN
134+
GST_PLUGIN_STATIC_REGISTER(qml6d3d11)
135+
#endif
136+
127137
GST_PLUGIN_STATIC_REGISTER(qgc);
128138
}
129139

@@ -246,7 +256,13 @@ bool _verifyPlugins()
246256
g_list_foreach(plugins, _checkPlugin, NULL);
247257
g_list_free(plugins);
248258

249-
static constexpr const char *pluginNames[2] = {"qml6", "qgc"};
259+
static constexpr const char *pluginNames[2] = {
260+
"qgc",
261+
"qml6"
262+
#ifdef Q_OS_WIN
263+
, "qml6d3d11"
264+
#endif
265+
};
250266
for (const char *name : pluginNames) {
251267
GstPlugin *plugin = gst_registry_find_plugin(registry, name);
252268
if (!plugin) {
@@ -407,9 +423,15 @@ bool initialize()
407423

408424
_setCodecPriorities(static_cast<GStreamer::VideoDecoderOptions>(SettingsManager::instance()->videoSettings()->forceVideoDecoder()->rawValue().toInt()));
409425

410-
GstElement *sink = gst_element_factory_make("qml6glsink", nullptr);
426+
#ifdef Q_OS_WIN
427+
static constexpr const char *qmlSinkName = "qml6d3d11sink";
428+
#else
429+
static constexpr const char *qmlSinkName = "qml6glsink";
430+
#endif
431+
432+
GstElement *sink = gst_element_factory_make(qmlSinkName, nullptr);
411433
if (!sink) {
412-
qCCritical(GStreamerLog) << "failed to init qml6glsink";
434+
qCCritical(GStreamerLog) << "failed to init" << qmlSinkName;
413435
return false;
414436
}
415437

@@ -419,13 +441,19 @@ bool initialize()
419441

420442
void *createVideoSink(QQuickItem *widget, QObject *parent)
421443
{
422-
GstElement *videoSinkBin = gst_element_factory_make("qgcvideosinkbin", NULL);
444+
#ifdef Q_OS_WIN
445+
static constexpr const char *videoSinkBinName = "qgcvideosinkbin_d3d11";
446+
#else
447+
static constexpr const char *videoSinkBinName = "qgcvideosinkbin";
448+
#endif
449+
450+
GstElement *videoSinkBin = gst_element_factory_make(videoSinkBinName, NULL);
423451
if (videoSinkBin) {
424452
if (widget) {
425453
g_object_set(videoSinkBin, "widget", widget, NULL);
426454
}
427455
} else {
428-
qCCritical(GStreamerLog) << "gst_element_factory_make('qgcvideosinkbin') failed";
456+
qCCritical(GStreamerLog) << QStringLiteral("gst_element_factory_make('%1') failed").arg(videoSinkBinName);
429457
}
430458

431459
return videoSinkBin;

src/VideoManager/VideoReceiver/GStreamer/gstqgc/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@ target_sources(${CMAKE_PROJECT_NAME}
77
gstqgcvideosinkbin.h
88
)
99

10+
if(WIN32)
11+
target_sources(${CMAKE_PROJECT_NAME}
12+
PRIVATE
13+
gstqgcvideosinkbin_d3d11.cc
14+
gstqgcvideosinkbin_d3d11.h
15+
)
16+
endif()
17+
1018
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

src/VideoManager/VideoReceiver/GStreamer/gstqgc/gstqgcvideosinkbin.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,14 @@ gst_qgc_video_sink_bin_init(GstQgcVideoSinkBin *self)
156156
return;
157157
}
158158

159-
self->qmlglsink = gst_element_factory_make("qml6glsink", NULL);
160-
if (!self->qmlglsink) {
159+
self->qml6glsink = gst_element_factory_make("qml6glsink", NULL);
160+
if (!self->qml6glsink) {
161161
GST_ERROR_OBJECT(self, "gst_element_factory_make('qml6glsink') failed");
162162
return;
163163
}
164164

165165
g_object_set(self->glsinkbin,
166-
"sink", self->qmlglsink,
166+
"sink", self->qml6glsink,
167167
PROP_ENABLE_LAST_SAMPLE_NAME, FALSE,
168168
NULL);
169169

@@ -209,7 +209,7 @@ gst_qgc_video_sink_bin_set_property(GObject *object, guint prop_id, const GValue
209209
NULL);
210210
break;
211211
case PROP_WIDGET:
212-
g_object_set(self->qmlglsink,
212+
g_object_set(self->qml6glsink,
213213
PROP_WIDGET_NAME,
214214
g_value_get_pointer(value),
215215
NULL);
@@ -223,7 +223,7 @@ gst_qgc_video_sink_bin_set_property(GObject *object, guint prop_id, const GValue
223223
case PROP_PIXEL_ASPECT_RATIO: {
224224
const gint num = gst_value_get_fraction_numerator(value);
225225
const gint den = gst_value_get_fraction_denominator(value);
226-
g_object_set(self->qmlglsink,
226+
g_object_set(self->qml6glsink,
227227
PROP_PIXEL_ASPECT_RATIO_NAME,
228228
num,
229229
den,
@@ -271,7 +271,7 @@ gst_qgc_video_sink_bin_get_property(GObject *object, guint prop_id, GValue *valu
271271
}
272272
case PROP_WIDGET: {
273273
gpointer widget = NULL;
274-
g_object_get(self->qmlglsink,
274+
g_object_get(self->qml6glsink,
275275
PROP_WIDGET_NAME,
276276
&widget,
277277
NULL);
@@ -289,7 +289,7 @@ gst_qgc_video_sink_bin_get_property(GObject *object, guint prop_id, GValue *valu
289289
}
290290
case PROP_PIXEL_ASPECT_RATIO: {
291291
gint num = 0, den = 1;
292-
g_object_get(self->qmlglsink,
292+
g_object_get(self->qml6glsink,
293293
PROP_PIXEL_ASPECT_RATIO_NAME,
294294
&num, &den,
295295
NULL);
@@ -318,13 +318,13 @@ gst_qgc_video_sink_bin_on_glsinkbin_create_element(GstElement *object, gpointer
318318
GstQgcVideoSinkBin *qgcVideoSinkBin = GST_QGC_VIDEO_SINK_BIN(udata);
319319

320320
qgcVideoSinkBin->glsinkbin = GST_ELEMENT(glsinkbin);
321-
qgcVideoSinkBin->qmlglsink = gst_element_factory_make("qml6glsink", NULL);
322-
if (!qgcVideoSinkBin->qmlglsink) {
321+
qgcVideoSinkBin->qml6glsink = gst_element_factory_make("qml6glsink", NULL);
322+
if (!qgcVideoSinkBin->qml6glsink) {
323323
GST_ERROR_OBJECT(qgcVideoSinkBin, "gst_element_factory_make('qml6glsink') failed");
324-
g_signal_emit(GST_ELEMENT(qgcVideoSinkBin), gst_qgc_video_sink_bin_signals[SIGNAL_CREATE_ELEMENT], 0, &qgcVideoSinkBin->qmlglsink);
324+
g_signal_emit(GST_ELEMENT(qgcVideoSinkBin), gst_qgc_video_sink_bin_signals[SIGNAL_CREATE_ELEMENT], 0, &qgcVideoSinkBin->qml6glsink);
325325
}
326326

327-
return qgcVideoSinkBin->qmlglsink;
327+
return qgcVideoSinkBin->qml6glsink;
328328
}
329329

330330
static void

src/VideoManager/VideoReceiver/GStreamer/gstqgc/gstqgcvideosinkbin.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct _GstQgcVideoSinkBin
2020
{
2121
GstBin parent;
2222
GstElement *glsinkbin;
23-
GstElement *qmlglsink;
23+
GstElement *qml6glsink;
2424
};
2525

2626
G_END_DECLS

0 commit comments

Comments
 (0)