From 1d6665765f199c493b635a47ba885f2150165cf7 Mon Sep 17 00:00:00 2001 From: dogmaphobic Date: Mon, 6 Jul 2015 13:51:52 -0400 Subject: [PATCH] Handling build and runtime when NO video support is available. --- QGCApplication.pro | 17 +++++++++++++++++ src/QGCApplication.cc | 4 ++-- src/QmlControls/ScreenToolsController.h | 7 ------- src/VideoStreaming/VideoItem.cc | 21 ++++++++++++++++++++- src/VideoStreaming/VideoItem.h | 4 ++++ src/VideoStreaming/VideoReceiver.cc | 14 ++++++++++++++ src/VideoStreaming/VideoReceiver.h | 11 +++++++++++ src/VideoStreaming/VideoStreaming.pri | 13 ------------- src/VideoStreaming/VideoSurface.cc | 9 +++++++++ src/VideoStreaming/VideoSurface.h | 10 ++++++++++ src/ui/flightdisplay/FlightDisplay.cc | 6 ++---- src/ui/flightdisplay/FlightDisplay.h | 8 ++++++++ src/ui/flightdisplay/FlightDisplay.qml | 8 ++++++++ src/ui/qmlcommon/QGCVideoBackground.qml | 16 +++++++++------- 14 files changed, 114 insertions(+), 34 deletions(-) diff --git a/QGCApplication.pro b/QGCApplication.pro index 6f9795607..61d8f15d3 100644 --- a/QGCApplication.pro +++ b/QGCApplication.pro @@ -652,7 +652,23 @@ SOURCES += \ src/FactSystem/ParameterLoader.cc \ src/FactSystem/FactControls/FactPanelController.cc \ +#------------------------------------------------------------------------------------- # Video Streaming + +INCLUDEPATH += \ + src/VideoStreaming + +HEADERS += \ + src/VideoStreaming/VideoItem.h \ + src/VideoStreaming/VideoReceiver.h \ + src/VideoStreaming/VideoSurface.h \ + src/VideoStreaming/VideoSurface_p.h \ + +SOURCES += \ + src/VideoStreaming/VideoItem.cc \ + src/VideoStreaming/VideoReceiver.cc \ + src/VideoStreaming/VideoSurface.cc \ + contains (DEFINES, DISABLE_VIDEOSTREAMING) { message("Skipping support for video streaming (manual override from command line)") DEFINES -= DISABLE_VIDEOSTREAMING @@ -663,6 +679,7 @@ contains (DEFINES, DISABLE_VIDEOSTREAMING) { include(src/VideoStreaming/VideoStreaming.pri) } +#------------------------------------------------------------------------------------- # Android AndroidBuild { diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 00cbf094a..f6da705d3 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -40,9 +40,9 @@ #include -#if defined(QGC_GST_STREAMING) #include #include +#if defined(QGC_GST_STREAMING) G_BEGIN_DECLS GST_PLUGIN_STATIC_DECLARE(QTVIDEOSINK_NAME); G_END_DECLS @@ -264,11 +264,11 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION); } -#if defined(QGC_GST_STREAMING) //---------------------------------------------------------------- //-- Video Streaming qmlRegisterType("QGroundControl.QgcQtGStreamer", 1, 0, "VideoItem"); qmlRegisterUncreatableType("QGroundControl.QgcQtGStreamer", 1, 0, "VideoSurface", QLatin1String("VideoSurface from QML is not supported")); +#if defined(QGC_GST_STREAMING) GError* error = NULL; if (!gst_init_check(&argc, &argv, &error)) { qCritical() << "gst_init_check() failed: " << error->message; diff --git a/src/QmlControls/ScreenToolsController.h b/src/QmlControls/ScreenToolsController.h index d118c8a76..46e43fa04 100644 --- a/src/QmlControls/ScreenToolsController.h +++ b/src/QmlControls/ScreenToolsController.h @@ -50,7 +50,6 @@ public: Q_PROPERTY(bool isAndroid READ isAndroid CONSTANT) Q_PROPERTY(bool isiOS READ isiOS CONSTANT) Q_PROPERTY(bool isMobile READ isMobile CONSTANT) - Q_PROPERTY(bool hasVideo READ hasVideo CONSTANT) //! Used to trigger a \c Canvas element repaint. /*! @@ -111,12 +110,6 @@ public: bool isMobile () { return false; } #endif -#if defined(QGC_GST_STREAMING) - bool hasVideo () { return true; } -#else - bool hasVideo () { return false; } -#endif - signals: void repaintRequested(void); diff --git a/src/VideoStreaming/VideoItem.cc b/src/VideoStreaming/VideoItem.cc index b02ff504f..3943a326b 100644 --- a/src/VideoStreaming/VideoItem.cc +++ b/src/VideoStreaming/VideoItem.cc @@ -32,35 +32,51 @@ This file is part of the QGROUNDCONTROL project #include #include "VideoItem.h" +#if defined(QGC_GST_STREAMING) #include "VideoSurface_p.h" +#endif +#if defined(QGC_GST_STREAMING) struct VideoItem::Private { QPointer surface; bool surfaceDirty; QRectF targetArea; }; +#endif VideoItem::VideoItem(QQuickItem *parent) - : QQuickItem(parent), _data(new Private) + : QQuickItem(parent) +#if defined(QGC_GST_STREAMING) + , _data(new Private) +#endif { +#if defined(QGC_GST_STREAMING) _data->surfaceDirty = true; setFlag(QQuickItem::ItemHasContents, true); +#endif } VideoItem::~VideoItem() { +#if defined(QGC_GST_STREAMING) setSurface(0); delete _data; +#endif } VideoSurface *VideoItem::surface() const { +#if defined(QGC_GST_STREAMING) return _data->surface.data(); +#else + return NULL; +#endif } void VideoItem::setSurface(VideoSurface *surface) { +#if defined(QGC_GST_STREAMING) if (_data->surface) { _data->surface.data()->_data->items.remove(this); } @@ -69,8 +85,10 @@ void VideoItem::setSurface(VideoSurface *surface) if (_data->surface) { _data->surface.data()->_data->items.insert(this); } +#endif } +#if defined(QGC_GST_STREAMING) QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) { QRectF r = boundingRect(); @@ -111,3 +129,4 @@ QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) return newNode; } +#endif diff --git a/src/VideoStreaming/VideoItem.h b/src/VideoStreaming/VideoItem.h index 65c38c83a..ef7399a92 100644 --- a/src/VideoStreaming/VideoItem.h +++ b/src/VideoStreaming/VideoItem.h @@ -47,12 +47,16 @@ public: void setSurface(VideoSurface *surface); protected: +#if defined(QGC_GST_STREAMING) /*! Reimplemented from QQuickItem. */ virtual QSGNode* updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); +#endif private: +#if defined(QGC_GST_STREAMING) struct Private; Private* const _data; +#endif }; #endif // VIDEO_ITEM_H diff --git a/src/VideoStreaming/VideoReceiver.cc b/src/VideoStreaming/VideoReceiver.cc index 7c60446a4..10aa0f5bb 100644 --- a/src/VideoStreaming/VideoReceiver.cc +++ b/src/VideoStreaming/VideoReceiver.cc @@ -32,18 +32,23 @@ This file is part of the QGROUNDCONTROL project VideoReceiver::VideoReceiver(QObject* parent) : QObject(parent) +#if defined(QGC_GST_STREAMING) , _pipeline(NULL) , _videoSink(NULL) +#endif { } VideoReceiver::~VideoReceiver() { +#if defined(QGC_GST_STREAMING) stop(); setVideoSink(NULL); +#endif } +#if defined(QGC_GST_STREAMING) void VideoReceiver::setVideoSink(GstElement* sink) { if (_videoSink) { @@ -55,9 +60,11 @@ void VideoReceiver::setVideoSink(GstElement* sink) gst_object_ref_sink(_videoSink); } } +#endif void VideoReceiver::start() { +#if defined(QGC_GST_STREAMING) if (_uri.isEmpty()) { qCritical() << "VideoReceiver::start() failed because URI is not specified"; return; @@ -158,15 +165,18 @@ void VideoReceiver::start() _pipeline = NULL; } } +#endif } void VideoReceiver::stop() { +#if defined(QGC_GST_STREAMING) if (_pipeline != NULL) { gst_element_set_state(_pipeline, GST_STATE_NULL); gst_object_unref(_pipeline); _pipeline = NULL; } +#endif } void VideoReceiver::setUri(const QString & uri) @@ -175,6 +185,7 @@ void VideoReceiver::setUri(const QString & uri) _uri = uri; } +#if defined(QGC_GST_STREAMING) void VideoReceiver::_onBusMessage(GstMessage* msg) { switch (GST_MESSAGE_TYPE(msg)) { @@ -196,7 +207,9 @@ void VideoReceiver::_onBusMessage(GstMessage* msg) break; } } +#endif +#if defined(QGC_GST_STREAMING) gboolean VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer data) { Q_UNUSED(bus) @@ -205,3 +218,4 @@ gboolean VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer dat pThis->_onBusMessage(msg); return TRUE; } +#endif diff --git a/src/VideoStreaming/VideoReceiver.h b/src/VideoStreaming/VideoReceiver.h index 1a7917f12..c2fd35fc3 100644 --- a/src/VideoStreaming/VideoReceiver.h +++ b/src/VideoStreaming/VideoReceiver.h @@ -31,7 +31,9 @@ This file is part of the QGROUNDCONTROL project #define VIDEORECEIVER_H #include +#if defined(QGC_GST_STREAMING) #include +#endif class VideoReceiver : public QObject { @@ -40,7 +42,9 @@ public: explicit VideoReceiver(QObject* parent = 0); ~VideoReceiver(); +#if defined(QGC_GST_STREAMING) void setVideoSink(GstElement* sink); +#endif public Q_SLOTS: void start (); @@ -48,12 +52,19 @@ public Q_SLOTS: void setUri (const QString& uri); private: + +#if defined(QGC_GST_STREAMING) void _onBusMessage(GstMessage* message); static gboolean _onBusMessage(GstBus* bus, GstMessage* msg, gpointer data); +#endif QString _uri; + +#if defined(QGC_GST_STREAMING) GstElement* _pipeline; GstElement* _videoSink; +#endif + }; #endif // VIDEORECEIVER_H diff --git a/src/VideoStreaming/VideoStreaming.pri b/src/VideoStreaming/VideoStreaming.pri index 4d4f2a541..323fe1d6b 100644 --- a/src/VideoStreaming/VideoStreaming.pri +++ b/src/VideoStreaming/VideoStreaming.pri @@ -50,26 +50,13 @@ VideoEnabled { GST_PLUGIN_BUILD_STATIC \ QTGLVIDEOSINK_NAME=qt5glvideosink \ QTVIDEOSINK_NAME=qt5videosink - #QT_NO_KEYWORDS \ INCLUDEPATH += \ - $$PWD \ $$PWD/gstqtvideosink \ $$PWD/gstqtvideosink/delegates \ $$PWD/gstqtvideosink/painters \ $$PWD/gstqtvideosink/utils \ - HEADERS += \ - $$PWD/VideoItem.h \ - $$PWD/VideoReceiver.h \ - $$PWD/VideoSurface.h \ - $$PWD/VideoSurface_p.h \ - - SOURCES += \ - $$PWD/VideoItem.cc \ - $$PWD/VideoReceiver.cc \ - $$PWD/VideoSurface.cc \ - #-- QtGstreamer (gutted to our needs) HEADERS += \ diff --git a/src/VideoStreaming/VideoSurface.cc b/src/VideoStreaming/VideoSurface.cc index cb067527a..9202f1984 100644 --- a/src/VideoStreaming/VideoSurface.cc +++ b/src/VideoStreaming/VideoSurface.cc @@ -27,25 +27,33 @@ This file is part of the QGROUNDCONTROL project * @author Gus Grubba */ +#if defined(QGC_GST_STREAMING) #include "VideoSurface_p.h" +#endif +#include "VideoSurface.h" #include #include VideoSurface::VideoSurface(QObject *parent) : QObject(parent) +#if defined(QGC_GST_STREAMING) , _data(new VideoSurfacePrivate) +#endif { } VideoSurface::~VideoSurface() { +#if defined(QGC_GST_STREAMING) if (_data->videoSink != NULL) { gst_element_set_state(_data->videoSink, GST_STATE_NULL); } delete _data; +#endif } +#if defined(QGC_GST_STREAMING) GstElement* VideoSurface::videoSink() const { if (_data->videoSink == NULL) { @@ -71,4 +79,5 @@ void VideoSurface::onUpdateThunk(GstElement* sink, gpointer data) VideoSurface* pThis = (VideoSurface* )data; pThis->onUpdate(); } +#endif diff --git a/src/VideoStreaming/VideoSurface.h b/src/VideoStreaming/VideoSurface.h index 428a59af2..deb140ad7 100644 --- a/src/VideoStreaming/VideoSurface.h +++ b/src/VideoStreaming/VideoSurface.h @@ -32,9 +32,13 @@ This file is part of the QGROUNDCONTROL project #include +#if defined(QGC_GST_STREAMING) #include +#endif +#if defined(QGC_GST_STREAMING) class VideoSurfacePrivate; +#endif class VideoSurface : public QObject { @@ -48,15 +52,21 @@ public: * The element will be constructed the first time that this function * is called. The surface will always keep a reference to this element. */ +#if defined(QGC_GST_STREAMING) GstElement* videoSink() const; +#endif protected: +#if defined(QGC_GST_STREAMING) void onUpdate(); static void onUpdateThunk(GstElement* sink, gpointer data); +#endif private: friend class VideoItem; +#if defined(QGC_GST_STREAMING) VideoSurfacePrivate * const _data; +#endif }; Q_DECLARE_METATYPE(VideoSurface*) diff --git a/src/ui/flightdisplay/FlightDisplay.cc b/src/ui/flightdisplay/FlightDisplay.cc index f3b8938d6..a154823b7 100644 --- a/src/ui/flightdisplay/FlightDisplay.cc +++ b/src/ui/flightdisplay/FlightDisplay.cc @@ -31,11 +31,9 @@ This file is part of the QGROUNDCONTROL project #include #include -#if defined(QGC_GST_STREAMING) #include #include #include "VideoReceiver.h" -#endif #include "ScreenToolsController.h" #include "FlightDisplay.h" @@ -59,7 +57,6 @@ FlightDisplay::FlightDisplay(QWidget *parent) #endif setContextPropertyObject("flightDisplay", this); -#if defined(QGC_GST_STREAMING) /* * This is the receiving end of an UDP RTP stream. The sender can be setup with this command: * @@ -89,9 +86,10 @@ FlightDisplay::FlightDisplay(QWidget *parent) setContextPropertyObject("videoDisplay", pSurface); VideoReceiver* pReceiver = new VideoReceiver(this); pReceiver->setUri(QLatin1Literal("udp://0.0.0.0:5000")); +#if defined(QGC_GST_STREAMING) pReceiver->setVideoSink(pSurface->videoSink()); - setContextPropertyObject("videoReceiver", pReceiver); #endif + setContextPropertyObject("videoReceiver", pReceiver); setSource(QUrl::fromUserInput("qrc:/qml/FlightDisplay.qml")); setVisible(true); diff --git a/src/ui/flightdisplay/FlightDisplay.h b/src/ui/flightdisplay/FlightDisplay.h index ba374c26a..cd3e63e72 100644 --- a/src/ui/flightdisplay/FlightDisplay.h +++ b/src/ui/flightdisplay/FlightDisplay.h @@ -44,9 +44,17 @@ public: /// @brief Invokes the Flight Display Options menu void showOptionsMenu() { emit showOptionsMenuChanged(); } + Q_PROPERTY(bool hasVideo READ hasVideo CONSTANT) + Q_INVOKABLE void saveSetting (const QString &key, const QString& value); Q_INVOKABLE QString loadSetting (const QString &key, const QString& defaultValue); +#if defined(QGC_GST_STREAMING) + bool hasVideo () { return true; } +#else + bool hasVideo () { return false; } +#endif + signals: void showOptionsMenuChanged (); diff --git a/src/ui/flightdisplay/FlightDisplay.qml b/src/ui/flightdisplay/FlightDisplay.qml index 043d4164a..e075a5248 100644 --- a/src/ui/flightdisplay/FlightDisplay.qml +++ b/src/ui/flightdisplay/FlightDisplay.qml @@ -91,6 +91,13 @@ Item { videoBackground.visible = false; flightDisplay.saveSetting("showVideoBackground", setBool(videoBackground.visible)); } + // Disable video if we don't have support for it + if(!flightDisplay.hasVideo) { + videoBackground.visible = false; + flightDisplay.saveSetting("showVideoBackground", setBool(videoBackground.visible)); + } + // Enable/Disable menu accordingly + videoMenu.enabled = flightDisplay.hasVideo; } Menu { @@ -141,6 +148,7 @@ Item { MenuSeparator {} MenuItem { + id: videoMenu text: "Video Background" checkable: true checked: videoBackground.visible diff --git a/src/ui/qmlcommon/QGCVideoBackground.qml b/src/ui/qmlcommon/QGCVideoBackground.qml index 833222574..639bba83f 100644 --- a/src/ui/qmlcommon/QGCVideoBackground.qml +++ b/src/ui/qmlcommon/QGCVideoBackground.qml @@ -35,17 +35,19 @@ VideoItem { id: videoBackground property var display property var receiver - surface: display + surface: display onVisibleChanged: { - if(videoBackground.visible) { - receiver.start(); - } else { - receiver.stop(); + if(videoBackground.receiver && videoBackground.display) { + if(videoBackground.visible) { + videoBackground.receiver.start(); + } else { + videoBackground.receiver.stop(); + } } } Component.onCompleted: { - if(videoBackground.visible) { - receiver.start(); + if(videoBackground.visible && videoBackground.receiver) { + videoBackground.receiver.start(); } } } -- 2.22.0