diff --git a/user/openterface-qt/348_address-use-of-deleted-function.patch b/user/openterface-qt/348_address-use-of-deleted-function.patch new file mode 100644 index 0000000..2783740 --- /dev/null +++ b/user/openterface-qt/348_address-use-of-deleted-function.patch @@ -0,0 +1,23 @@ +diff --git a/serial/SerialPortManager.cpp.orig b/serial/SerialPortManager.cpp +index 22565b5..d444eee 100644 +--- a/serial/SerialPortManager.cpp.orig ++++ b/serial/SerialPortManager.cpp +@@ -1945,8 +1945,9 @@ void SerialPortManager::attemptRecovery() + } + } else { + qCWarning(log_core_serial) << "Serial port recovery attempt failed"; +- if (eventCallback) { +- eventCallback->onStatusUpdate(QString("Recovery attempt %1 failed").arg(m_connectionRetryCount)); ++ if (eventCallback) { ++ int crc = m_connectionRetryCount; ++ eventCallback->onStatusUpdate(QString("Recovery attempt %1 failed").arg(crc)); + } + + // Try again if we haven't exceeded max attempts +@@ -2034,4 +2035,4 @@ void SerialPortManager::applyCommandBasedBaudrateChange(int baudRate, const QStr + } else { + qCWarning(log_core_serial) << logPrefix << "Failed to apply user selected baudrate:" << baudRate; + } +-} +\ No newline at end of file ++} diff --git a/user/openterface-qt/423_deduplicate-logging-categories-and-remove-backslashes.patch b/user/openterface-qt/423_deduplicate-logging-categories-and-remove-backslashes.patch new file mode 100644 index 0000000..5e762ff --- /dev/null +++ b/user/openterface-qt/423_deduplicate-logging-categories-and-remove-backslashes.patch @@ -0,0 +1,586 @@ +From 4478cfb004d3db7797e99fd3bdb23bf880a9c85b Mon Sep 17 00:00:00 2001 +From: John Lane <1786613+johnlane@users.noreply.github.com> +Date: Wed, 3 Dec 2025 21:19:33 +0000 +Subject: [PATCH 1/2] Remove additional backslashes and add missing cpp and h + files + +--- + openterfaceQT.pro | 28 +++++++++++++++++++--------- + 1 file changed, 19 insertions(+), 9 deletions(-) + +diff --git a/openterfaceQT.pro b/openterfaceQT.pro +index 3460dbac..f0d878e8 100644 +--- a/openterfaceQT.pro ++++ b/openterfaceQT.pro +@@ -84,16 +84,26 @@ SOURCES += main.cpp \ + !win32 { + SOURCES += host/backend/ffmpegbackendhandler.cpp \ + host/backend/gstreamerbackendhandler.cpp \ +- host/backend/gstreamer/sinkselector.cpp \\ +- host/backend/gstreamer/queueconfigurator.cpp \\ +- host/backend/gstreamer/videooverlaymanager.cpp \\ +- host/backend/gstreamer/pipelinebuilder.cpp ++ host/backend/gstreamer/pipelinefactory.cpp \ ++ host/backend/gstreamer/externalgstrunner.cpp \ ++ host/backend/gstreamer/inprocessgstrunner.cpp \ ++ host/backend/gstreamer/sinkselector.cpp \ ++ host/backend/gstreamer/queueconfigurator.cpp \ ++ host/backend/gstreamer/videooverlaymanager.cpp \ ++ host/backend/gstreamer/pipelinebuilder.cpp \ ++ host/backend/gstreamer/recordingmanager.cpp \ ++ host/backend/gstreamer/gstreamerhelpers.cpp + HEADERS += host/backend/ffmpegbackendhandler.h \ + host/backend/gstreamerbackendhandler.h \ +- host/backend/gstreamer/sinkselector.h \\ +- host/backend/gstreamer/queueconfigurator.h \\ +- host/backend/gstreamer/videooverlaymanager.h \\ +- host/backend/gstreamer/pipelinebuilder.h ++ host/backend/gstreamer/pipelinefactory.h \ ++ host/backend/gstreamer/externalgstrunner.h \ ++ host/backend/gstreamer/inprocessgstrunner.h \ ++ host/backend/gstreamer/sinkselector.h \ ++ host/backend/gstreamer/queueconfigurator.h \ ++ host/backend/gstreamer/videooverlaymanager.h \ ++ host/backend/gstreamer/pipelinebuilder.h \ ++ host/backend/gstreamer/recordingmanager.h \ ++ host/backend/gstreamer/gstreamerhelpers.h + } + + +@@ -263,4 +273,4 @@ TRANSLATIONS += config/languages/openterface_en.ts \ + config/languages/openterface_se.ts \ + config/languages/openterface_de.ts \ + config/languages/openterface_zh.ts +- # Add more languages here +\ No newline at end of file ++ # Add more languages here + +From ccd8f51fe510684439edf0d5f8083e4dd1423836 Mon Sep 17 00:00:00 2001 +From: John Lane <1786613+johnlane@users.noreply.github.com> +Date: Wed, 3 Dec 2025 21:26:20 +0000 +Subject: [PATCH 2/2] De-duplicate logging categories + +--- + host/backend/gstreamer/gstreamerhelpers.cpp | 22 ++-- + host/backend/gstreamer/queueconfigurator.cpp | 8 +- + .../backend/gstreamer/videooverlaymanager.cpp | 118 +++++++++--------- + 3 files changed, 74 insertions(+), 74 deletions(-) + +diff --git a/host/backend/gstreamer/gstreamerhelpers.cpp b/host/backend/gstreamer/gstreamerhelpers.cpp +index 6fc1dd6e..4739da17 100644 +--- a/host/backend/gstreamer/gstreamerhelpers.cpp ++++ b/host/backend/gstreamer/gstreamerhelpers.cpp +@@ -4,7 +4,7 @@ + #include + #include + +-Q_LOGGING_CATEGORY(log_gstreamer_backend, "opf.backend.gstreamer") ++Q_LOGGING_CATEGORY(log_gstreamer_gstreamerhelpers, "opf.backend.gstreamerhelpers") + + using namespace Openterface::GStreamer::GstHelpers; + +@@ -16,7 +16,7 @@ bool Openterface::GStreamer::GstHelpers::setPipelineStateWithTimeout(void* eleme + { + if (!elementPtr) { + if (outError) *outError = QStringLiteral("Element pointer is null"); +- qCWarning(log_gstreamer_backend) << "setPipelineStateWithTimeout: element pointer is null"; ++ qCWarning(log_gstreamer_gstreamerhelpers) << "setPipelineStateWithTimeout: element pointer is null"; + return false; + } + +@@ -24,7 +24,7 @@ bool Openterface::GStreamer::GstHelpers::setPipelineStateWithTimeout(void* eleme + + GstStateChangeReturn ret = gst_element_set_state(element, static_cast(targetState)); + if (ret == GST_STATE_CHANGE_FAILURE) { +- qCCritical(log_gstreamer_backend) << "Failed to set element state to" << targetState; ++ qCCritical(log_gstreamer_gstreamerhelpers) << "Failed to set element state to" << targetState; + // Try to pull any error from the bus for diagnostics + // Caller may pass a bus to parseAndLogGstErrorMessage, but we don't have it here. + if (outError) *outError = QStringLiteral("Failed to set state (GST_STATE_CHANGE_FAILURE)"); +@@ -35,13 +35,13 @@ bool Openterface::GStreamer::GstHelpers::setPipelineStateWithTimeout(void* eleme + ret = gst_element_get_state(element, &state, &pending, static_cast(timeoutMs) * GST_MSECOND); + if (ret == GST_STATE_CHANGE_FAILURE) { + if (outError) *outError = QStringLiteral("State change failure"); +- qCCritical(log_gstreamer_backend) << "State change failure waiting for target state"; ++ qCCritical(log_gstreamer_gstreamerhelpers) << "State change failure waiting for target state"; + return false; + } + + if (state != static_cast(targetState)) { + if (outError) *outError = QStringLiteral("Element did not reach target state in timeout"); +- qCCritical(log_gstreamer_backend) << "Element failed to reach state" << targetState << "(current:" << state << ", pending:" << pending << ")"; ++ qCCritical(log_gstreamer_gstreamerhelpers) << "Element failed to reach state" << targetState << "(current:" << state << ", pending:" << pending << ")"; + return false; + } + +@@ -51,14 +51,14 @@ bool Openterface::GStreamer::GstHelpers::setPipelineStateWithTimeout(void* eleme + void Openterface::GStreamer::GstHelpers::parseAndLogGstErrorMessage(void* busPtr, const char* context) + { + if (!busPtr) { +- qCWarning(log_gstreamer_backend) << "Bus not available for error details" << (context ? context : ""); ++ qCWarning(log_gstreamer_gstreamerhelpers) << "Bus not available for error details" << (context ? context : ""); + return; + } + + GstBus* bus = static_cast(busPtr); + GstMessage* msg = gst_bus_pop_filtered(bus, GST_MESSAGE_ERROR); + if (!msg) { +- qCDebug(log_gstreamer_backend) << "No error message available on bus" << (context ? context : ""); ++ qCDebug(log_gstreamer_gstreamerhelpers) << "No error message available on bus" << (context ? context : ""); + return; + } + +@@ -66,8 +66,8 @@ void Openterface::GStreamer::GstHelpers::parseAndLogGstErrorMessage(void* busPtr + gchar* debug_info = nullptr; + gst_message_parse_error(msg, &error, &debug_info); + +- qCCritical(log_gstreamer_backend) << "GStreamer Error:" << (error ? error->message : "Unknown") << (context ? context : ""); +- qCCritical(log_gstreamer_backend) << "Debug info:" << (debug_info ? debug_info : "None"); ++ qCCritical(log_gstreamer_gstreamerhelpers) << "GStreamer Error:" << (error ? error->message : "Unknown") << (context ? context : ""); ++ qCCritical(log_gstreamer_gstreamerhelpers) << "Debug info:" << (debug_info ? debug_info : "None"); + + if (error) g_error_free(error); + if (debug_info) g_free(debug_info); +@@ -79,13 +79,13 @@ void Openterface::GStreamer::GstHelpers::parseAndLogGstErrorMessage(void* busPtr + bool Openterface::GStreamer::GstHelpers::setPipelineStateWithTimeout(void* /*elementPtr*/, int /*targetState*/, int /*timeoutMs*/, QString* outError) + { + if (outError) *outError = QStringLiteral("GStreamer not available in this build"); +- qCWarning(log_gstreamer_backend) << "setPipelineStateWithTimeout called but GStreamer is not compiled in"; ++ qCWarning(log_gstreamer_gstreamerhelpers) << "setPipelineStateWithTimeout called but GStreamer is not compiled in"; + return false; + } + + void Openterface::GStreamer::GstHelpers::parseAndLogGstErrorMessage(void* /*busPtr*/, const char* context) + { +- qCDebug(log_gstreamer_backend) << "GStreamer not compiled in - no bus to parse" << (context ? context : ""); ++ qCDebug(log_gstreamer_gstreamerhelpers) << "GStreamer not compiled in - no bus to parse" << (context ? context : ""); + } + + #endif // HAVE_GSTREAMER +diff --git a/host/backend/gstreamer/queueconfigurator.cpp b/host/backend/gstreamer/queueconfigurator.cpp +index b7bea42e..12290193 100644 +--- a/host/backend/gstreamer/queueconfigurator.cpp ++++ b/host/backend/gstreamer/queueconfigurator.cpp +@@ -8,7 +8,7 @@ + #include + #endif + +-Q_LOGGING_CATEGORY(log_gstreamer_backend, "opf.backend.gstreamer") ++Q_LOGGING_CATEGORY(log_gstreamer_queueconfigurator, "opf.backend.queueconfigurator") + + using namespace Openterface::GStreamer; + +@@ -26,10 +26,10 @@ void QueueConfigurator::configureDisplayQueue(void* pipeline) + "max-size-time", G_GUINT64_CONSTANT(100000000), // 100ms + "leaky", 2, // GST_QUEUE_LEAK_DOWNSTREAM + NULL); +- qCDebug(log_gstreamer_backend) << "✓ Configured display queue with higher priority for qtsink"; ++ qCDebug(log_gstreamer_queueconfigurator) << "✓ Configured display queue with higher priority for qtsink"; + gst_object_unref(displayQueue); + } else { +- qCDebug(log_gstreamer_backend) << "Display queue element not found (no named display-queue)"; ++ qCDebug(log_gstreamer_queueconfigurator) << "Display queue element not found (no named display-queue)"; + } + #else + Q_UNUSED(pipeline); +@@ -50,7 +50,7 @@ void QueueConfigurator::configureRecordingQueue(void* pipeline) + "max-size-time", G_GUINT64_CONSTANT(500000000), // 500ms + "leaky", 1, // GST_QUEUE_LEAK_UPSTREAM + NULL); +- qCDebug(log_gstreamer_backend) << "✓ Configured recording queue with lower priority relative to display"; ++ qCDebug(log_gstreamer_queueconfigurator) << "✓ Configured recording queue with lower priority relative to display"; + gst_object_unref(recordingQueue); + } + #else +diff --git a/host/backend/gstreamer/videooverlaymanager.cpp b/host/backend/gstreamer/videooverlaymanager.cpp +index d8bf42f3..2dbe3bbf 100644 +--- a/host/backend/gstreamer/videooverlaymanager.cpp ++++ b/host/backend/gstreamer/videooverlaymanager.cpp +@@ -22,7 +22,7 @@ static int x11_overlay_error_handler_local(Display* display, XErrorEvent* error) + } + #endif + +-Q_LOGGING_CATEGORY(log_gstreamer_backend, "opf.backend.gstreamer") ++Q_LOGGING_CATEGORY(log_gstreamer_videooverlaymanager, "opf.backend.videooverlaymanager") + + using namespace Openterface::GStreamer; + +@@ -30,36 +30,36 @@ bool VideoOverlayManager::embedVideoInWidget(void* pipeline, QWidget* widget) + { + #ifdef HAVE_GSTREAMER + if (!widget || !pipeline) { +- qCWarning(log_gstreamer_backend) << "Cannot embed video: widget or pipeline is null"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Cannot embed video: widget or pipeline is null"; + return false; + } + + GstElement* videoSink = gst_bin_get_by_name(GST_BIN(pipeline), "videosink"); + if (!videoSink) { +- qCWarning(log_gstreamer_backend) << "No video sink element named 'videosink' found in pipeline"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "No video sink element named 'videosink' found in pipeline"; + videoSink = gst_bin_get_by_interface(GST_BIN(pipeline), GST_TYPE_VIDEO_OVERLAY); + if (!videoSink) { +- qCWarning(log_gstreamer_backend) << "No video overlay interface found in pipeline either"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "No video overlay interface found in pipeline either"; + return false; + } + } + + WId winId = widget->winId(); + if (winId) { +- qCDebug(log_gstreamer_backend) << "Embedding video in widget with window ID:" << winId; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Embedding video in widget with window ID:" << winId; + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(videoSink), winId); + gst_object_unref(videoSink); +- qCDebug(log_gstreamer_backend) << "Video embedded in widget successfully"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Video embedded in widget successfully"; + return true; + } else { +- qCWarning(log_gstreamer_backend) << "Widget window ID is null, cannot embed video"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Widget window ID is null, cannot embed video"; + gst_object_unref(videoSink); + return false; + } + #else + Q_UNUSED(pipeline) + Q_UNUSED(widget) +- qCDebug(log_gstreamer_backend) << "Using autovideosink for video output (no in-process GStreamer)"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Using autovideosink for video output (no in-process GStreamer)"; + return true; + #endif + } +@@ -68,36 +68,36 @@ bool VideoOverlayManager::embedVideoInGraphicsView(void* pipeline, QGraphicsView + { + #ifdef HAVE_GSTREAMER + if (!view || !pipeline) { +- qCWarning(log_gstreamer_backend) << "Cannot embed video: graphics view or pipeline is null"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Cannot embed video: graphics view or pipeline is null"; + return false; + } + + GstElement* videoSink = gst_bin_get_by_name(GST_BIN(pipeline), "videosink"); + if (!videoSink) { +- qCWarning(log_gstreamer_backend) << "No video sink element named 'videosink' found in pipeline"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "No video sink element named 'videosink' found in pipeline"; + videoSink = gst_bin_get_by_interface(GST_BIN(pipeline), GST_TYPE_VIDEO_OVERLAY); + if (!videoSink) { +- qCWarning(log_gstreamer_backend) << "No video overlay interface found in pipeline either"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "No video overlay interface found in pipeline either"; + return false; + } + } + + WId winId = view->winId(); + if (winId) { +- qCDebug(log_gstreamer_backend) << "Embedding video in graphics view with window ID:" << winId; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Embedding video in graphics view with window ID:" << winId; + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(videoSink), winId); + gst_object_unref(videoSink); +- qCDebug(log_gstreamer_backend) << "Video embedded in graphics view successfully"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Video embedded in graphics view successfully"; + return true; + } else { +- qCWarning(log_gstreamer_backend) << "Graphics view window ID is null, cannot embed video"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Graphics view window ID is null, cannot embed video"; + gst_object_unref(videoSink); + return false; + } + #else + Q_UNUSED(pipeline) + Q_UNUSED(view) +- qCDebug(log_gstreamer_backend) << "Using autovideosink for video output (no in-process GStreamer)"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Using autovideosink for video output (no in-process GStreamer)"; + return true; + #endif + } +@@ -106,36 +106,36 @@ bool VideoOverlayManager::embedVideoInVideoPane(void* pipeline, ::VideoPane* vid + { + #ifdef HAVE_GSTREAMER + if (!videoPane || !pipeline) { +- qCWarning(log_gstreamer_backend) << "Cannot embed video: VideoPane or pipeline is null"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Cannot embed video: VideoPane or pipeline is null"; + return false; + } + + GstElement* videoSink = gst_bin_get_by_name(GST_BIN(pipeline), "videosink"); + if (!videoSink) { +- qCWarning(log_gstreamer_backend) << "No video sink element named 'videosink' found in pipeline"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "No video sink element named 'videosink' found in pipeline"; + videoSink = gst_bin_get_by_interface(GST_BIN(pipeline), GST_TYPE_VIDEO_OVERLAY); + if (!videoSink) { +- qCWarning(log_gstreamer_backend) << "No video overlay interface found in pipeline either"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "No video overlay interface found in pipeline either"; + return false; + } + } + + WId winId = videoPane->getVideoOverlayWindowId(); + if (winId) { +- qCDebug(log_gstreamer_backend) << "Embedding video in VideoPane overlay with window ID:" << winId; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Embedding video in VideoPane overlay with window ID:" << winId; + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(videoSink), winId); + gst_object_unref(videoSink); +- qCDebug(log_gstreamer_backend) << "Video embedded in VideoPane overlay successfully"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Video embedded in VideoPane overlay successfully"; + return true; + } else { +- qCWarning(log_gstreamer_backend) << "VideoPane overlay window ID is null, cannot embed video"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "VideoPane overlay window ID is null, cannot embed video"; + gst_object_unref(videoSink); + return false; + } + #else + Q_UNUSED(pipeline) + Q_UNUSED(videoPane) +- qCDebug(log_gstreamer_backend) << "Using autovideosink for video output (no in-process GStreamer)"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Using autovideosink for video output (no in-process GStreamer)"; + return true; + #endif + } +@@ -144,7 +144,7 @@ bool VideoOverlayManager::setupVideoOverlay(void* videoSinkPtr, WId windowId, QW + { + #ifdef HAVE_GSTREAMER + if (!videoSinkPtr || windowId == 0) { +- qCWarning(log_gstreamer_backend) << "Invalid parameters for overlay setup: sink=" << videoSinkPtr << "windowId=" << windowId; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Invalid parameters for overlay setup: sink=" << videoSinkPtr << "windowId=" << windowId; + return false; + } + +@@ -152,7 +152,7 @@ bool VideoOverlayManager::setupVideoOverlay(void* videoSinkPtr, WId windowId, QW + + // Check if the sink supports video overlay interface + if (GST_IS_VIDEO_OVERLAY(videoSink)) { +- qCDebug(log_gstreamer_backend) << "Sink supports video overlay - setting up overlay with window ID:" << windowId; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Sink supports video overlay - setting up overlay with window ID:" << windowId; + + #ifdef Q_OS_LINUX + // Add X11 error handling to prevent segmentation fault +@@ -175,12 +175,12 @@ bool VideoOverlayManager::setupVideoOverlay(void* videoSinkPtr, WId windowId, QW + if (g_object_class_find_property(G_OBJECT_GET_CLASS(videoSink), "force-aspect-ratio")) { + // Allow the sink to stretch to the configured render rectangle so overlay scales to widget size + g_object_set(videoSink, "force-aspect-ratio", FALSE, NULL); +- qCDebug(log_gstreamer_backend) << "Disabled force-aspect-ratio on video sink to allow fill scaling"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Disabled force-aspect-ratio on video sink to allow fill scaling"; + } + + if (g_object_class_find_property(G_OBJECT_GET_CLASS(videoSink), "pixel-aspect-ratio")) { + g_object_set(videoSink, "pixel-aspect-ratio", "1/1", NULL); +- qCDebug(log_gstreamer_backend) << "Set pixel-aspect-ratio to 1:1 on video sink"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Set pixel-aspect-ratio to 1:1 on video sink"; + } + + // Configure render rectangle based on provided targets +@@ -188,13 +188,13 @@ bool VideoOverlayManager::setupVideoOverlay(void* videoSinkPtr, WId windowId, QW + QSize widgetSize = videoWidget->size(); + if (widgetSize.width() > 0 && widgetSize.height() > 0) { + gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(videoSink), 0, 0, widgetSize.width(), widgetSize.height()); +- qCDebug(log_gstreamer_backend) << "Set render rectangle to widget size:" << widgetSize; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Set render rectangle to widget size:" << widgetSize; + } + } else if (graphicsVideoItem) { + QRectF itemRect = graphicsVideoItem->boundingRect(); + if (itemRect.width() > 0 && itemRect.height() > 0) { + gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(videoSink), 0, 0, (gint)itemRect.width(), (gint)itemRect.height()); +- qCDebug(log_gstreamer_backend) << "Set render rectangle to video item size:" << itemRect.size(); ++ qCDebug(log_gstreamer_videooverlaymanager) << "Set render rectangle to video item size:" << itemRect.size(); + } + } + +@@ -205,18 +205,18 @@ bool VideoOverlayManager::setupVideoOverlay(void* videoSinkPtr, WId windowId, QW + XCloseDisplay(display); + + if (x11_overlay_error_occurred_local) { +- qCWarning(log_gstreamer_backend) << "X11 error occurred during overlay setup - continuing without embedding"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "X11 error occurred during overlay setup - continuing without embedding"; + } else { +- qCDebug(log_gstreamer_backend) << "Video overlay setup completed successfully"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Video overlay setup completed successfully"; + } + } else if (!old_handler) { +- qCDebug(log_gstreamer_backend) << "Video overlay setup completed (no X11 error handling)"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Video overlay setup completed (no X11 error handling)"; + } + #endif + +- qCDebug(log_gstreamer_backend) << "Overlay setup completed"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Overlay setup completed"; + } catch (...) { +- qCCritical(log_gstreamer_backend) << "Exception during video overlay setup - continuing without embedding"; ++ qCCritical(log_gstreamer_videooverlaymanager) << "Exception during video overlay setup - continuing without embedding"; + #ifdef Q_OS_LINUX + if (display && old_handler) { + XSetErrorHandler(old_handler); +@@ -242,17 +242,17 @@ bool VideoOverlayManager::setupVideoOverlay(void* videoSinkPtr, WId windowId, QW + if (gst_iterator_next(iter, &item) == GST_ITERATOR_OK) { + actualSink = GST_ELEMENT(g_value_get_object(&item)); + if (actualSink && GST_IS_VIDEO_OVERLAY(actualSink)) { +- qCDebug(log_gstreamer_backend) << "Found overlay-capable sink inside autovideosink"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Found overlay-capable sink inside autovideosink"; + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(actualSink), windowId); + // Use target widget size if available to set explicit render rectangle so scaling works + if (videoWidget) { + QSize widgetSize = videoWidget->size(); + if (widgetSize.width() > 0 && widgetSize.height() > 0) { + gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(actualSink), 0, 0, widgetSize.width(), widgetSize.height()); +- qCDebug(log_gstreamer_backend) << "Set render rectangle to widget size for autovideosink child sink:" << widgetSize; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Set render rectangle to widget size for autovideosink child sink:" << widgetSize; + if (g_object_class_find_property(G_OBJECT_GET_CLASS(actualSink), "force-aspect-ratio")) { + g_object_set(actualSink, "force-aspect-ratio", FALSE, NULL); +- qCDebug(log_gstreamer_backend) << "Disabled force-aspect-ratio on autovideosink child sink"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Disabled force-aspect-ratio on autovideosink child sink"; + } + } else { + gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(actualSink), 0, 0, -1, -1); +@@ -269,18 +269,18 @@ bool VideoOverlayManager::setupVideoOverlay(void* videoSinkPtr, WId windowId, QW + } + gst_iterator_free(iter); + } +- qCDebug(log_gstreamer_backend) << "autovideosink selected sink doesn't support overlay - video will display in separate window"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "autovideosink selected sink doesn't support overlay - video will display in separate window"; + return false; + } + +- qCWarning(log_gstreamer_backend) << "Sink does not support video overlay:" << sinkName; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Sink does not support video overlay:" << sinkName; + return false; + #else + Q_UNUSED(videoSinkPtr) + Q_UNUSED(windowId) + Q_UNUSED(videoWidget) + Q_UNUSED(graphicsVideoItem) +- qCDebug(log_gstreamer_backend) << "No in-process GStreamer - overlay unavailable"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "No in-process GStreamer - overlay unavailable"; + return false; + #endif + } +@@ -300,7 +300,7 @@ bool VideoOverlayManager::setupVideoOverlayForPipeline(void* pipeline, WId windo + gst_object_unref(videoSink); + return ok; + } +- qCWarning(log_gstreamer_backend) << "No video sink found in pipeline"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "No video sink found in pipeline"; + return false; + #else + Q_UNUSED(pipeline) +@@ -315,10 +315,10 @@ bool VideoOverlayManager::completePendingOverlaySetup(void* pipeline, + ::VideoPane* videoPane, + bool &pendingFlag) + { +- qCDebug(log_gstreamer_backend) << "VideoOverlayManager: Completing pending overlay setup..."; ++ qCDebug(log_gstreamer_videooverlaymanager) << "VideoOverlayManager: Completing pending overlay setup..."; + + if (!pendingFlag || !pipeline) { +- qCDebug(log_gstreamer_backend) << "No pending setup or no pipeline"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "No pending setup or no pipeline"; + return false; + } + +@@ -326,7 +326,7 @@ bool VideoOverlayManager::completePendingOverlaySetup(void* pipeline, + const bool isXcb = platform.contains("xcb", Qt::CaseInsensitive); + const bool hasXDisplay = !qgetenv("DISPLAY").isEmpty(); + if (!isXcb || !hasXDisplay) { +- qCWarning(log_gstreamer_backend) << "Skipping deferred overlay setup: platform is" << platform << "(DISPLAY set:" << hasXDisplay << ")"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Skipping deferred overlay setup: platform is" << platform << "(DISPLAY set:" << hasXDisplay << ")"; + pendingFlag = false; + return false; + } +@@ -335,7 +335,7 @@ bool VideoOverlayManager::completePendingOverlaySetup(void* pipeline, + + if (videoPane) { + windowId = videoPane->getVideoOverlayWindowId(); +- qCDebug(log_gstreamer_backend) << "Completing overlay setup with VideoPane window ID:" << windowId; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Completing overlay setup with VideoPane window ID:" << windowId; + } else if (graphicsVideoItem) { + if (graphicsVideoItem->scene()) { + QList views = graphicsVideoItem->scene()->views(); +@@ -344,21 +344,21 @@ bool VideoOverlayManager::completePendingOverlaySetup(void* pipeline, + if (auto pane = qobject_cast(view)) { + if (pane->isDirectGStreamerModeEnabled() && pane->getOverlayWidget()) { + windowId = pane->getVideoOverlayWindowId(); +- qCDebug(log_gstreamer_backend) << "Completing overlay setup with VideoPane overlay widget window ID:" << windowId; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Completing overlay setup with VideoPane overlay widget window ID:" << windowId; + } else { +- qCDebug(log_gstreamer_backend) << "VideoPane overlay widget still not ready"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "VideoPane overlay widget still not ready"; + return false; + } + } else { + windowId = view->winId(); +- qCDebug(log_gstreamer_backend) << "Completing overlay setup with graphics view window ID:" << windowId; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Completing overlay setup with graphics view window ID:" << windowId; + } + } else { +- qCWarning(log_gstreamer_backend) << "Graphics video item has no associated view"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Graphics video item has no associated view"; + return false; + } + } else { +- qCWarning(log_gstreamer_backend) << "Graphics video item has no scene"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Graphics video item has no scene"; + return false; + } + } +@@ -367,7 +367,7 @@ bool VideoOverlayManager::completePendingOverlaySetup(void* pipeline, + GstElement* videoSink = gst_bin_get_by_name(GST_BIN(pipeline), "videosink"); + if (!videoSink) { + videoSink = gst_bin_get_by_interface(GST_BIN(pipeline), GST_TYPE_VIDEO_OVERLAY); +- if (videoSink) qCDebug(log_gstreamer_backend) << "Deferred path: found sink by overlay interface"; ++ if (videoSink) qCDebug(log_gstreamer_videooverlaymanager) << "Deferred path: found sink by overlay interface"; + } + + if (videoSink) { +@@ -384,14 +384,14 @@ bool VideoOverlayManager::completePendingOverlaySetup(void* pipeline, + targetWidget = videoWidget; + } + if (targetWidget) { +- qCDebug(log_gstreamer_backend) << "Deferred: binding qt6videosink to QWidget" << targetWidget; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Deferred: binding qt6videosink to QWidget" << targetWidget; + g_object_set(G_OBJECT(videoSink), "widget", (gpointer)targetWidget, nullptr); + gst_object_unref(videoSink); + pendingFlag = false; +- qCDebug(log_gstreamer_backend) << "Deferred qt6videosink binding completed"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Deferred qt6videosink binding completed"; + return true; + } else { +- qCWarning(log_gstreamer_backend) << "Deferred: no target QWidget available to bind qt6videosink"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Deferred: no target QWidget available to bind qt6videosink"; + } + } + +@@ -399,30 +399,30 @@ bool VideoOverlayManager::completePendingOverlaySetup(void* pipeline, + const bool looksLikeXSink = sinkNameBA.contains("xvimage") || sinkNameBA.contains("ximage"); + + if (!supportsOverlay) { +- qCWarning(log_gstreamer_backend) << "Deferred overlay skipped: sink does not support overlay interface (" << sinkName << ")"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Deferred overlay skipped: sink does not support overlay interface (" << sinkName << ")"; + gst_object_unref(videoSink); + pendingFlag = false; + return false; + } + + if (!looksLikeXSink) { +- qCWarning(log_gstreamer_backend) << "Deferred overlay skipped: sink is not an X sink (" << sinkName << ") on platform" << QGuiApplication::platformName(); ++ qCWarning(log_gstreamer_videooverlaymanager) << "Deferred overlay skipped: sink is not an X sink (" << sinkName << ") on platform" << QGuiApplication::platformName(); + gst_object_unref(videoSink); + pendingFlag = false; + return false; + } + +- qCDebug(log_gstreamer_backend) << "Setting up deferred video overlay with window ID:" << windowId << "using sink" << sinkName; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Setting up deferred video overlay with window ID:" << windowId << "using sink" << sinkName; + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(videoSink), windowId); + gst_object_unref(videoSink); + pendingFlag = false; +- qCDebug(log_gstreamer_backend) << "Deferred overlay setup completed successfully"; ++ qCDebug(log_gstreamer_videooverlaymanager) << "Deferred overlay setup completed successfully"; + return true; + } else { +- qCWarning(log_gstreamer_backend) << "Could not find video sink for deferred overlay setup"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Could not find video sink for deferred overlay setup"; + } + } else { +- qCWarning(log_gstreamer_backend) << "Still no valid window ID available for deferred overlay setup"; ++ qCWarning(log_gstreamer_videooverlaymanager) << "Still no valid window ID available for deferred overlay setup"; + } + + return false; diff --git a/user/openterface-qt/APKBUILD b/user/openterface-qt/APKBUILD index cf753a7..a96e328 100644 --- a/user/openterface-qt/APKBUILD +++ b/user/openterface-qt/APKBUILD @@ -1,29 +1,54 @@ # Maintainer: Antoine Martin (ayakael) pkgname=openterface-qt -pkgver=0.3.13 +pkgver=0.5.7 pkgrel=0 pkgdesc="Openterface Mini-KVM Host Application" -arch="all !armhf" # missing qt6-qtmultimedia +# armhf: missing qt6-qtmultimedia +# riscv64: missing libgtk-3 +arch="all !armhf !riscv64" url="https://openterface.com/" license="AGPL-3.0-only" -depends="qt6-qtmultimedia-ffmpeg hicolor-icon-theme" -makedepends="qt6-qtbase-dev qt6-qtmultimedia-dev qt6-qtserialport-dev qt6-qtsvg-dev qt6-qtmultimedia-dev libusb-dev" +depends=" + gst-plugins-good-qt + hicolor-icon-theme + qt6-qtmultimedia-ffmpeg + " +makedepends=" + cmake + ffmpeg-dev + libgudev-dev + libjpeg-turbo-dev + libusb-dev + libx11-dev + libxv-dev + patchelf + qt6-qtbase-dev + qt6-qtmultimedia-dev + qt6-qtserialport-dev + samurai + v4l-utils-dev +" install="$pkgname.post-install" builddir="$srcdir"/Openterface_QT-$pkgver +options="!check" # No testsuite source=" $pkgname-$pkgver.tar.gz::https://github.com/TechxArtisanStudio/Openterface_QT/archive/$pkgver.tar.gz openterfaceQT.desktop 51-openterface-permissions.rules + 348_address-use-of-deleted-function.patch + 423_deduplicate-logging-categories-and-remove-backslashes.patch + use-system-libs.patch " prepare() { default_prepare mkdir build && cd build - qmake6 .. + # OPENTERFACE_BUILD_STATIC: do not build vendored dependencies + cmake -DOPENTERFACE_BUILD_STATIC=OFF .. } build() { - make -C build + ninja -C build } package() { @@ -33,9 +58,16 @@ package() { install -Dm644 "$builddir"/images/icon_32.png "$pkgdir"/usr/share/icons/hicolor/32x32/apps/openterfaceQT.png install -Dm644 "$builddir"/images/icon_64.png "$pkgdir"/usr/share/icons/hicolor/64x64/apps/openterfaceQT.png install -Dm644 "$builddir"/images/icon_128.png "$pkgdir"/usr/share/icons/hicolor/128x128/apps/openterfaceQT.png + + # vanilla build does not set rpath, since it usually wants to use vendored libs + patchelf --set-rpath '/usr/lib' "$pkgdir"/usr/bin/openterfaceQT } + sha512sums=" -7261ce2875b1617d27945de591c72779d2305889b7f53bb6758cb5e1d4dc01c969fef1638726d868f75e995c44a8e2c453cac45c90cfb3d140b8120523c4038d openterface-qt-0.3.13.tar.gz +996415d6f7d3ed950901c380a0520ddab8c31e8d3c2e2bb3a5f631a5600cace6bcf6bf89871e4e4ef818009eeb08c448fd793e1e4758ecccf1e1a21ff04fd560 openterface-qt-0.5.7.tar.gz e39cfa04cbcb59e8ba54110a28eff41854f73fa7c4baeeed5433907c79781946f12bd3a731763caa1d591e664eab0650bdbd2a844954baa12bb96a76a17c6e4f openterfaceQT.desktop f50d721a6a2d1e0183c81e99230e91e127ee6c6f3243af1cff3e3cb78e2913ebab3346ec8b461a4710220d1ce2e12a7cc960ded6e0dc2def539375c6e737b647 51-openterface-permissions.rules +69b5556ec9e56792e848ea1ff9374e12e6901da821ecd9d6f2f521ea30f48e564c2cd0631fc1360acd6c8c6249cfa718d5baf7ed6929e1e92f63eeaea578bcb3 348_address-use-of-deleted-function.patch +47580d07a2d971ad2010e78373d1abbcbc05b3fbd3a7e466faed50dc9a0d632db30c0a7622e7324aeb0eb38d49e3241cb6cebc835f7adeed977b1dd7b48ea5f6 423_deduplicate-logging-categories-and-remove-backslashes.patch +22ecac74fe0923f39f538a5d587f8c100d9709631a1584bd20646e09dcf777cd3042670d08195626220f0494e5efa9549a299c5e1fd8c42f991ec5746b42cc86 use-system-libs.patch " diff --git a/user/openterface-qt/use-system-libs.patch b/user/openterface-qt/use-system-libs.patch new file mode 100644 index 0000000..a220d5f --- /dev/null +++ b/user/openterface-qt/use-system-libs.patch @@ -0,0 +1,72 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e0e8ea1..c861725 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -244,7 +244,7 @@ endif() + # Add XCB cursor library for static linking (Linux only) - Legacy support + if(UNIX AND NOT APPLE AND XCB_CURSOR_FOUND) + # This is redundant now but keeping for compatibility +- message(STATUS "XCB cursor already linked via static approach above") ++ target_link_libraries(openterfaceQT PRIVATE X11) + endif() + + # Add TurboJPEG if available +@@ -307,4 +307,4 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release") + endif() + endif() + +-# Qt components already found above +\ No newline at end of file ++# Qt components already found above +diff --git a/cmake/FFmpeg.cmake b/cmake/FFmpeg.cmake +index ef0699e..660e765 100644 +--- a/cmake/FFmpeg.cmake ++++ b/cmake/FFmpeg.cmake +@@ -19,7 +19,7 @@ if(NOT DEFINED FFMPEG_PREFIX) + if(WIN32) + set(FFMPEG_PREFIX "C:/ffmpeg-static" CACHE PATH "FFmpeg installation directory") + else() +- set(FFMPEG_PREFIX "/opt/ffmpeg" CACHE PATH "FFmpeg installation directory") ++ set(FFMPEG_PREFIX "/usr" CACHE PATH "FFmpeg installation directory") + endif() + message(STATUS "Using default FFMPEG_PREFIX: ${FFMPEG_PREFIX}") + endif() +@@ -116,7 +116,7 @@ if(NOT FFMPEG_FOUND) + message(STATUS "FFmpeg search paths: ${FFMPEG_SEARCH_PATHS}") + foreach(SEARCH_PATH ${FFMPEG_SEARCH_PATHS}) + # For static builds, prefer .a files; check common lib directories +- set(LIB_EXTENSIONS ".a") ++ set(LIB_EXTENSIONS ".so") + + # Platform-specific library paths + if(WIN32) +diff --git a/cmake/GStreamer.cmake b/cmake/GStreamer.cmake +index 220e9f5..576535f 100644 +--- a/cmake/GStreamer.cmake ++++ b/cmake/GStreamer.cmake +@@ -316,10 +316,11 @@ else() + # Check for Qt6 plugin availability in system + message(STATUS "Checking for Qt6 GStreamer plugin in system...") + find_file(GSTREAMER_QT6_PLUGIN +- NAMES libgstqt6.so ++ NAMES libgstqml6.so + PATHS + /usr/lib/x86_64-linux-gnu/gstreamer-1.0 + /usr/lib/aarch64-linux-gnu/gstreamer-1.0 ++ /usr/lib/gstreamer-1.0 + /usr/local/lib/gstreamer-1.0 + NO_DEFAULT_PATH + ) +diff --git a/cmake/Resources.cmake b/cmake/Resources.cmake +index 2d28b89..e2009e3 100644 +--- a/cmake/Resources.cmake ++++ b/cmake/Resources.cmake +@@ -336,7 +336,7 @@ install(FILES ${CMAKE_SOURCE_DIR}/com.openterface.openterfaceQT.metainfo.xml + if(COMMAND qt_generate_deploy_app_script) + qt_generate_deploy_app_script( + TARGET openterfaceQT +- FILENAME_VARIABLE deploy_script ++ OUTPUT_SCRIPT deploy_script + NO_UNSUPPORTED_PLATFORM_ERROR + ) + install(SCRIPT ${deploy_script})