Skip to content

Commit a31a92f

Browse files
committed
Video: switch every platform to videoconvert→appsink rendering
Drop the vendored qml6glsink and qml6d3d11sink modules (and the gst-plugins-good / gst-plugins-bad source downloads they required) and funnel all GStreamer rendering through a single videoconvert→appsink → GstAppSinkAdapter → QVideoSink → QML VideoOutput chain. Qt picks the native RHI backend (Metal / Vulkan / D3D11 / OpenGL), so QGCApplication no longer probes for an OpenGL context or forces a graphics API. qgcvideosinkbin loses the d3d11sink and glsinkbin fallbacks plus the widget / aspect-ratio properties they exposed. GStreamer.cc drops the qml6 / qt6d3d11 / opengl static plugin registrations and verifies only appsink / qgc / coreelements; the iOS xcframework no longer needs the opengl plugin filter. VideoManager removes gstreamerD3D11Sink and gstreamerAppleSink (the QML side now picks one VideoOutput component unconditionally), and FlightDisplayViewMetal.qml is renamed to FlightDisplayViewVideoOutput.qml to reflect the universal path.
1 parent c70bab0 commit a31a92f

87 files changed

Lines changed: 6028 additions & 3575 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cmake/find-modules/FindGStreamer.cmake

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,20 @@ Configuration Variables
3333
3434
#]=======================================================================]
3535

36+
# Short-circuit only when every currently-requested component already has a target;
37+
# otherwise re-run so a later find_package(... COMPONENTS NewOne) can populate the
38+
# new GStreamer::NewOne target instead of silently inheriting the cached _FOUND.
3639
if (GStreamer_FOUND)
37-
return()
40+
set(_gst_all_present TRUE)
41+
foreach(_gst_c IN LISTS GStreamer_FIND_COMPONENTS)
42+
if (NOT TARGET GStreamer::${_gst_c})
43+
set(_gst_all_present FALSE)
44+
break()
45+
endif()
46+
endforeach()
47+
if (_gst_all_present)
48+
return()
49+
endif()
3850
endif()
3951

4052
if (NOT GStreamer_ROOT_DIR OR NOT EXISTS "${GStreamer_ROOT_DIR}")
@@ -137,8 +149,8 @@ endif()
137149
# _gst_IGNORED_SYSTEM_LIBRARIES and _gst_SRT_REGEX_PATCH are defined in GStreamerHelpers.cmake
138150

139151
if(PC_GStreamer_FOUND AND (NOT TARGET GStreamer::GStreamer))
140-
add_library(GStreamer::GStreamer INTERFACE IMPORTED)
141-
add_library(GStreamer::deps INTERFACE IMPORTED)
152+
add_library(GStreamer::GStreamer INTERFACE IMPORTED GLOBAL)
153+
add_library(GStreamer::deps INTERFACE IMPORTED GLOBAL)
142154

143155
if (GStreamer_USE_STATIC_LIBS)
144156
_gst_filter_missing_directories(PC_GStreamer_STATIC_INCLUDE_DIRS)

cmake/find-modules/FindQGCGStreamer.cmake

Lines changed: 119 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,6 @@ macro(_qgc_discover_ios_sdk)
623623
set(GSTREAMER_PLUGIN_PATH "${_xcfw_slice_dir}")
624624

625625
_gst_normalize_and_validate_root()
626-
return()
627626
endif()
628627

629628
# ── Classic .framework path ───────────────────────────────────────────────
@@ -652,11 +651,33 @@ macro(_qgc_discover_ios_sdk)
652651
endif()
653652
endforeach()
654653
endif()
654+
# 1.28+ embeds everything in the framework binary — no lib/ subdir exists.
655+
if(NOT EXISTS "${GSTREAMER_LIB_PATH}")
656+
set(GSTREAMER_LIB_PATH "${GStreamer_ROOT_DIR}")
657+
set(GSTREAMER_PLUGIN_PATH "${GStreamer_ROOT_DIR}")
658+
endif()
655659

656-
_qgc_find_apple_pkg_config(PKG_CONFIG_EXECUTABLE)
657-
_gst_configure_pkg_config(
658-
LIBDIR "${GSTREAMER_LIB_PATH}/pkgconfig" "${GSTREAMER_PLUGIN_PATH}/pkgconfig"
659-
)
660+
# When no pkgconfig dir is present the framework is a single fat binary (1.28+
661+
# Cerbero layout); reuse the xcframework target-creation path which already handles
662+
# this: no pkg-config queries, direct link of the binary, system framework deps.
663+
if(NOT EXISTS "${GSTREAMER_LIB_PATH}/pkgconfig")
664+
# The framework binary lives at Versions/1.0/<FrameworkName> (= GStreamer_ROOT_DIR/GStreamer).
665+
set(GSTREAMER_XCFRAMEWORK_PATH "${GSTREAMER_FRAMEWORK_PATH}")
666+
set(GSTREAMER_XCFRAMEWORK_LIB "${GStreamer_ROOT_DIR}/GStreamer")
667+
set(GSTREAMER_INCLUDE_PATH "${GSTREAMER_FRAMEWORK_PATH}/Headers")
668+
# Point synthetic lib/plugin paths at the root so downstream existence checks pass.
669+
set(GSTREAMER_LIB_PATH "${GStreamer_ROOT_DIR}")
670+
set(GSTREAMER_PLUGIN_PATH "${GStreamer_ROOT_DIR}")
671+
set(GStreamer_USE_XCFRAMEWORK ON)
672+
_gst_normalize_and_validate_root()
673+
endif()
674+
675+
if(NOT GStreamer_USE_XCFRAMEWORK) # xcframework has no .pc files; target already created
676+
_qgc_find_apple_pkg_config(PKG_CONFIG_EXECUTABLE)
677+
_gst_configure_pkg_config(
678+
LIBDIR "${GSTREAMER_LIB_PATH}/pkgconfig" "${GSTREAMER_PLUGIN_PATH}/pkgconfig"
679+
)
680+
endif()
660681
endmacro()
661682

662683
# Dispatch to the appropriate platform discovery macro
@@ -756,8 +777,12 @@ if(NOT DEFINED GSTREAMER_EXTRA_DEPS)
756777
endif()
757778
endif()
758779

780+
# Default plugin set assumes the videoconvert→appsink rendering path used everywhere.
781+
# The base opengl / d3d11 plugins are kept because GStreamer auto-plugs gldownload /
782+
# d3d11download when hardware decoders produce GPU memory.
759783
if(NOT DEFINED GSTREAMER_PLUGINS)
760784
set(GSTREAMER_PLUGINS
785+
app
761786
coreelements
762787
isomp4
763788
libav
@@ -775,15 +800,12 @@ if(NOT DEFINED GSTREAMER_PLUGINS)
775800
udp
776801
videoparsersbad
777802
vpx
803+
# gst >=1.22 split: only the one matching the SDK gets a target; #ifdef in GStreamer.cc picks it.
804+
videoconvertscale
805+
videoconvert
806+
videoscale
778807
)
779-
# Deferred on Linux — actual version may differ from the minimum (see finalization below)
780-
if(NOT LINUX)
781-
if(GStreamer_FIND_VERSION VERSION_GREATER_EQUAL "1.22")
782-
list(APPEND GSTREAMER_PLUGINS videoconvertscale)
783-
else()
784-
list(APPEND GSTREAMER_PLUGINS videoconvert videoscale)
785-
endif()
786-
endif()
808+
# Deferred for all platforms — GStreamer_VERSION is populated after find_package(GStreamer) below.
787809
if(ANDROID)
788810
list(APPEND GSTREAMER_PLUGINS androidmedia dav1d)
789811
elseif(APPLE)
@@ -840,11 +862,14 @@ if(GStreamer_USE_XCFRAMEWORK)
840862
target_link_libraries(GStreamer::GStreamer INTERFACE
841863
GStreamer_static
842864
)
843-
target_include_directories(GStreamer::GStreamer INTERFACE
844-
"${GSTREAMER_INCLUDE_PATH}"
845-
"${GSTREAMER_INCLUDE_PATH}/gstreamer-1.0"
846-
"${GSTREAMER_INCLUDE_PATH}/glib-2.0"
847-
)
865+
# iOS .framework has flat Headers/; macOS-style installs have the gstreamer-1.0 /
866+
# glib-2.0 subdirs. Add only what exists — INTERFACE_INCLUDE_DIRECTORIES is validated.
867+
target_include_directories(GStreamer::GStreamer INTERFACE "${GSTREAMER_INCLUDE_PATH}")
868+
foreach(_inc_sub IN ITEMS gstreamer-1.0 glib-2.0)
869+
if(IS_DIRECTORY "${GSTREAMER_INCLUDE_PATH}/${_inc_sub}")
870+
target_include_directories(GStreamer::GStreamer INTERFACE "${GSTREAMER_INCLUDE_PATH}/${_inc_sub}")
871+
endif()
872+
endforeach()
848873
# System frameworks required by GStreamer on iOS.
849874
find_library(_xcfw_foundation Foundation REQUIRED)
850875
find_library(_xcfw_avfoundation AVFoundation REQUIRED)
@@ -1052,15 +1077,6 @@ foreach(plugin IN LISTS GSTREAMER_PLUGINS)
10521077
endif()
10531078
endforeach()
10541079

1055-
if(LINUX AND NOT "videoconvertscale" IN_LIST GSTREAMER_PLUGINS
1056-
AND NOT "videoconvert" IN_LIST GSTREAMER_PLUGINS)
1057-
if(GStreamer_VERSION VERSION_GREATER_EQUAL "1.22")
1058-
list(APPEND GSTREAMER_PLUGINS videoconvertscale)
1059-
else()
1060-
list(APPEND GSTREAMER_PLUGINS videoconvert videoscale)
1061-
endif()
1062-
endif()
1063-
10641080
if(NOT GStreamer_USE_STATIC_LIBS AND NOT GStreamer_USE_XCFRAMEWORK AND EXISTS "${GSTREAMER_PLUGIN_PATH}")
10651081
set(_gst_missing_plugins)
10661082
if(WIN32)
@@ -1084,7 +1100,18 @@ if(NOT GStreamer_USE_STATIC_LIBS AND NOT GStreamer_USE_XCFRAMEWORK AND EXISTS "$
10841100
endif()
10851101
endforeach()
10861102
list(REMOVE_DUPLICATES _gst_available_basenames)
1103+
# videoconvert(scale)/videoscale alternate — only one ships per gst version; don't warn on the absent ones.
1104+
set(_gst_alternate_satisfied FALSE)
1105+
if("videoconvertscale" IN_LIST _gst_available_basenames
1106+
OR ("videoconvert" IN_LIST _gst_available_basenames
1107+
AND "videoscale" IN_LIST _gst_available_basenames))
1108+
set(_gst_alternate_satisfied TRUE)
1109+
endif()
10871110
foreach(_plugin IN LISTS GSTREAMER_PLUGINS)
1111+
if(_gst_alternate_satisfied
1112+
AND _plugin MATCHES "^(videoconvertscale|videoconvert|videoscale)$")
1113+
continue()
1114+
endif()
10881115
if(NOT _plugin IN_LIST _gst_available_basenames)
10891116
list(APPEND _gst_missing_plugins "${_plugin}")
10901117
endif()
@@ -1096,16 +1123,76 @@ if(NOT GStreamer_USE_STATIC_LIBS AND NOT GStreamer_USE_XCFRAMEWORK AND EXISTS "$
10961123
endif()
10971124
endif()
10981125

1099-
if(GStreamer_VERSION AND TARGET GStreamer::GStreamer)
1126+
if(GStreamer_VERSION)
11001127
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)" _gst_ver_match "${GStreamer_VERSION}")
11011128
if(_gst_ver_match)
1102-
target_compile_definitions(GStreamer::GStreamer INTERFACE
1103-
QGC_GST_BUILD_VERSION_MAJOR=${CMAKE_MATCH_1}
1104-
QGC_GST_BUILD_VERSION_MINOR=${CMAKE_MATCH_2}
1105-
)
1129+
# Mobile (iOS/Android) builds consume GStreamerMobile (alias GStreamer::mobile) instead
1130+
# of GStreamer::GStreamer, so propagate the version defines to whichever exists.
1131+
foreach(_gst_target IN ITEMS GStreamer::GStreamer GStreamerMobile)
1132+
if(TARGET ${_gst_target})
1133+
# target_compile_definitions can't be called on ALIAS targets — resolve first.
1134+
get_target_property(_gst_aliased ${_gst_target} ALIASED_TARGET)
1135+
if(_gst_aliased)
1136+
set(_gst_real ${_gst_aliased})
1137+
else()
1138+
set(_gst_real ${_gst_target})
1139+
endif()
1140+
target_compile_definitions(${_gst_real} INTERFACE
1141+
QGC_GST_BUILD_VERSION_MAJOR=${CMAKE_MATCH_1}
1142+
QGC_GST_BUILD_VERSION_MINOR=${CMAKE_MATCH_2}
1143+
)
1144+
endif()
1145+
endforeach()
11061146
endif()
11071147
endif()
11081148

1149+
# GstVideoOrientationMeta is officially in 1.26+, but bundled iOS/Android SDKs sometimes
1150+
# strip it. Feature-test the actual header instead of trusting the version number.
1151+
include(CheckCXXSourceCompiles)
1152+
foreach(_gst_target IN ITEMS GStreamer::GStreamer GStreamerMobile)
1153+
if(TARGET ${_gst_target})
1154+
set(CMAKE_REQUIRED_LIBRARIES_BACKUP "${CMAKE_REQUIRED_LIBRARIES}")
1155+
set(CMAKE_REQUIRED_LIBRARIES ${_gst_target})
1156+
check_cxx_source_compiles("
1157+
#include <gst/video/gstvideometa.h>
1158+
int main() { GstVideoOrientationMeta *m = nullptr; (void)m; return 0; }
1159+
" QGC_GST_HAS_VIDEO_ORIENTATION_META_${_gst_target})
1160+
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES_BACKUP}")
1161+
if(QGC_GST_HAS_VIDEO_ORIENTATION_META_${_gst_target})
1162+
get_target_property(_gst_aliased ${_gst_target} ALIASED_TARGET)
1163+
if(_gst_aliased)
1164+
set(_gst_real ${_gst_aliased})
1165+
else()
1166+
set(_gst_real ${_gst_target})
1167+
endif()
1168+
target_compile_definitions(${_gst_real} INTERFACE
1169+
QGC_HAS_GST_VIDEO_ORIENTATION_META=1)
1170+
endif()
1171+
endif()
1172+
endforeach()
1173+
1174+
# Zero-copy DMABuf GPU path (Linux only). Requires gst-allocators and Qt's
1175+
# private QHwVideoBuffer header. Both are detected here and the combined
1176+
# QGC_HAS_GST_DMABUF_GPU_PATH define is exposed to consumers via
1177+
# target_compile_definitions on the QGCGStreamerDmaBufFeature interface target
1178+
# below — the feature consumer picks it up by linking that target.
1179+
if(LINUX)
1180+
foreach(_gst_target IN ITEMS GStreamer::GStreamer GStreamerMobile)
1181+
if(TARGET ${_gst_target})
1182+
set(CMAKE_REQUIRED_LIBRARIES_BACKUP "${CMAKE_REQUIRED_LIBRARIES}")
1183+
set(CMAKE_REQUIRED_LIBRARIES ${_gst_target})
1184+
check_cxx_source_compiles("
1185+
#include <gst/allocators/gstdmabuf.h>
1186+
int main() { (void)gst_is_dmabuf_memory; return 0; }
1187+
" QGC_GST_HAS_DMABUF_${_gst_target})
1188+
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES_BACKUP}")
1189+
if(QGC_GST_HAS_DMABUF_${_gst_target})
1190+
set(QGC_GST_HAS_DMABUF TRUE)
1191+
endif()
1192+
endif()
1193+
endforeach()
1194+
endif()
1195+
11091196
include(FindPackageHandleStandardArgs)
11101197
find_package_handle_standard_args(QGCGStreamer
11111198
REQUIRED_VARS GStreamer_ROOT_DIR GSTREAMER_LIB_PATH GSTREAMER_PLUGIN_PATH

cmake/platform/Apple.cmake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ if(NOT APPLE)
66
message(FATAL_ERROR "QGC: Invalid Platform: Apple.cmake included but platform is not Apple")
77
endif()
88

9+
# .mm sources (e.g. GstIOSurfaceVideoBuffer.mm) need OBJCXX rules at root scope so
10+
# CMAKE_OBJCXX_COMPILE_OBJECT is populated for the QGC target. Done here unconditionally
11+
# for macOS + iOS rather than relying on a deferred enable_language inside Find modules.
12+
enable_language(OBJC OBJCXX)
13+
914
if(CMAKE_GENERATOR STREQUAL "Xcode" AND MACOS)
1015
# set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM
1116
# set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE
@@ -58,7 +63,6 @@ if(MACOS)
5863
message(STATUS "QGC: macOS platform configuration applied")
5964
elseif(IOS)
6065
# iOS-specific configuration
61-
enable_language(OBJC)
6266

6367
# set(CMAKE_XCODE_ATTRIBUTE_ARCHS
6468
# set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE

src/FlyView/CMakeLists.txt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ qt_add_qml_module(FlyViewModule
1414
DefaultChecklist.qml
1515
FixedWingChecklist.qml
1616
FlightDisplayViewDummy.qml
17-
FlightDisplayViewGStreamer.qml
18-
FlightDisplayViewGStreamerD3D11.qml
19-
FlightDisplayViewMetal.qml
17+
FlightDisplayViewVideoOutput.qml
2018
FlightDisplayViewQtMultimedia.qml
2119
FlightDisplayViewUVC.qml
2220
FlightDisplayViewVideo.qml
@@ -65,8 +63,6 @@ qt_add_qml_module(FlyViewModule
6563
PreFlightSoundCheck.qml
6664
ProximityRadarValues.qml
6765
ProximityRadarVideoView.qml
68-
QGCVideoBackground.qml
69-
QGCVideoBackgroundD3D11.qml
7066
RoverChecklist.qml
7167
SubChecklist.qml
7268
TelemetryValuesBar.qml

src/FlyView/FlightDisplayViewGStreamer.qml

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/FlyView/FlightDisplayViewGStreamerD3D11.qml

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)