Commit 1d666576 authored by dogmaphobic's avatar dogmaphobic

Handling build and runtime when NO video support is available.

parent 2e25ca9c
...@@ -652,7 +652,23 @@ SOURCES += \ ...@@ -652,7 +652,23 @@ SOURCES += \
src/FactSystem/ParameterLoader.cc \ src/FactSystem/ParameterLoader.cc \
src/FactSystem/FactControls/FactPanelController.cc \ src/FactSystem/FactControls/FactPanelController.cc \
#-------------------------------------------------------------------------------------
# Video Streaming # 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) { contains (DEFINES, DISABLE_VIDEOSTREAMING) {
message("Skipping support for video streaming (manual override from command line)") message("Skipping support for video streaming (manual override from command line)")
DEFINES -= DISABLE_VIDEOSTREAMING DEFINES -= DISABLE_VIDEOSTREAMING
...@@ -663,6 +679,7 @@ contains (DEFINES, DISABLE_VIDEOSTREAMING) { ...@@ -663,6 +679,7 @@ contains (DEFINES, DISABLE_VIDEOSTREAMING) {
include(src/VideoStreaming/VideoStreaming.pri) include(src/VideoStreaming/VideoStreaming.pri)
} }
#-------------------------------------------------------------------------------------
# Android # Android
AndroidBuild { AndroidBuild {
......
...@@ -40,9 +40,9 @@ ...@@ -40,9 +40,9 @@
#include <QDebug> #include <QDebug>
#if defined(QGC_GST_STREAMING)
#include <VideoItem.h> #include <VideoItem.h>
#include <VideoSurface.h> #include <VideoSurface.h>
#if defined(QGC_GST_STREAMING)
G_BEGIN_DECLS G_BEGIN_DECLS
GST_PLUGIN_STATIC_DECLARE(QTVIDEOSINK_NAME); GST_PLUGIN_STATIC_DECLARE(QTVIDEOSINK_NAME);
G_END_DECLS G_END_DECLS
...@@ -264,11 +264,11 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) ...@@ -264,11 +264,11 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION); settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION);
} }
#if defined(QGC_GST_STREAMING)
//---------------------------------------------------------------- //----------------------------------------------------------------
//-- Video Streaming //-- Video Streaming
qmlRegisterType<VideoItem>("QGroundControl.QgcQtGStreamer", 1, 0, "VideoItem"); qmlRegisterType<VideoItem>("QGroundControl.QgcQtGStreamer", 1, 0, "VideoItem");
qmlRegisterUncreatableType<VideoSurface>("QGroundControl.QgcQtGStreamer", 1, 0, "VideoSurface", QLatin1String("VideoSurface from QML is not supported")); qmlRegisterUncreatableType<VideoSurface>("QGroundControl.QgcQtGStreamer", 1, 0, "VideoSurface", QLatin1String("VideoSurface from QML is not supported"));
#if defined(QGC_GST_STREAMING)
GError* error = NULL; GError* error = NULL;
if (!gst_init_check(&argc, &argv, &error)) { if (!gst_init_check(&argc, &argv, &error)) {
qCritical() << "gst_init_check() failed: " << error->message; qCritical() << "gst_init_check() failed: " << error->message;
......
...@@ -50,7 +50,6 @@ public: ...@@ -50,7 +50,6 @@ public:
Q_PROPERTY(bool isAndroid READ isAndroid CONSTANT) Q_PROPERTY(bool isAndroid READ isAndroid CONSTANT)
Q_PROPERTY(bool isiOS READ isiOS CONSTANT) Q_PROPERTY(bool isiOS READ isiOS CONSTANT)
Q_PROPERTY(bool isMobile READ isMobile CONSTANT) Q_PROPERTY(bool isMobile READ isMobile CONSTANT)
Q_PROPERTY(bool hasVideo READ hasVideo CONSTANT)
//! Used to trigger a \c Canvas element repaint. //! Used to trigger a \c Canvas element repaint.
/*! /*!
...@@ -111,12 +110,6 @@ public: ...@@ -111,12 +110,6 @@ public:
bool isMobile () { return false; } bool isMobile () { return false; }
#endif #endif
#if defined(QGC_GST_STREAMING)
bool hasVideo () { return true; }
#else
bool hasVideo () { return false; }
#endif
signals: signals:
void repaintRequested(void); void repaintRequested(void);
......
...@@ -32,35 +32,51 @@ This file is part of the QGROUNDCONTROL project ...@@ -32,35 +32,51 @@ This file is part of the QGROUNDCONTROL project
#include <QtQuick/QSGFlatColorMaterial> #include <QtQuick/QSGFlatColorMaterial>
#include "VideoItem.h" #include "VideoItem.h"
#if defined(QGC_GST_STREAMING)
#include "VideoSurface_p.h" #include "VideoSurface_p.h"
#endif
#if defined(QGC_GST_STREAMING)
struct VideoItem::Private struct VideoItem::Private
{ {
QPointer<VideoSurface> surface; QPointer<VideoSurface> surface;
bool surfaceDirty; bool surfaceDirty;
QRectF targetArea; QRectF targetArea;
}; };
#endif
VideoItem::VideoItem(QQuickItem *parent) 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; _data->surfaceDirty = true;
setFlag(QQuickItem::ItemHasContents, true); setFlag(QQuickItem::ItemHasContents, true);
#endif
} }
VideoItem::~VideoItem() VideoItem::~VideoItem()
{ {
#if defined(QGC_GST_STREAMING)
setSurface(0); setSurface(0);
delete _data; delete _data;
#endif
} }
VideoSurface *VideoItem::surface() const VideoSurface *VideoItem::surface() const
{ {
#if defined(QGC_GST_STREAMING)
return _data->surface.data(); return _data->surface.data();
#else
return NULL;
#endif
} }
void VideoItem::setSurface(VideoSurface *surface) void VideoItem::setSurface(VideoSurface *surface)
{ {
#if defined(QGC_GST_STREAMING)
if (_data->surface) { if (_data->surface) {
_data->surface.data()->_data->items.remove(this); _data->surface.data()->_data->items.remove(this);
} }
...@@ -69,8 +85,10 @@ void VideoItem::setSurface(VideoSurface *surface) ...@@ -69,8 +85,10 @@ void VideoItem::setSurface(VideoSurface *surface)
if (_data->surface) { if (_data->surface) {
_data->surface.data()->_data->items.insert(this); _data->surface.data()->_data->items.insert(this);
} }
#endif
} }
#if defined(QGC_GST_STREAMING)
QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*)
{ {
QRectF r = boundingRect(); QRectF r = boundingRect();
...@@ -111,3 +129,4 @@ QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) ...@@ -111,3 +129,4 @@ QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*)
return newNode; return newNode;
} }
#endif
...@@ -47,12 +47,16 @@ public: ...@@ -47,12 +47,16 @@ public:
void setSurface(VideoSurface *surface); void setSurface(VideoSurface *surface);
protected: protected:
#if defined(QGC_GST_STREAMING)
/*! Reimplemented from QQuickItem. */ /*! Reimplemented from QQuickItem. */
virtual QSGNode* updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); virtual QSGNode* updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
#endif
private: private:
#if defined(QGC_GST_STREAMING)
struct Private; struct Private;
Private* const _data; Private* const _data;
#endif
}; };
#endif // VIDEO_ITEM_H #endif // VIDEO_ITEM_H
...@@ -32,18 +32,23 @@ This file is part of the QGROUNDCONTROL project ...@@ -32,18 +32,23 @@ This file is part of the QGROUNDCONTROL project
VideoReceiver::VideoReceiver(QObject* parent) VideoReceiver::VideoReceiver(QObject* parent)
: QObject(parent) : QObject(parent)
#if defined(QGC_GST_STREAMING)
, _pipeline(NULL) , _pipeline(NULL)
, _videoSink(NULL) , _videoSink(NULL)
#endif
{ {
} }
VideoReceiver::~VideoReceiver() VideoReceiver::~VideoReceiver()
{ {
#if defined(QGC_GST_STREAMING)
stop(); stop();
setVideoSink(NULL); setVideoSink(NULL);
#endif
} }
#if defined(QGC_GST_STREAMING)
void VideoReceiver::setVideoSink(GstElement* sink) void VideoReceiver::setVideoSink(GstElement* sink)
{ {
if (_videoSink) { if (_videoSink) {
...@@ -55,9 +60,11 @@ void VideoReceiver::setVideoSink(GstElement* sink) ...@@ -55,9 +60,11 @@ void VideoReceiver::setVideoSink(GstElement* sink)
gst_object_ref_sink(_videoSink); gst_object_ref_sink(_videoSink);
} }
} }
#endif
void VideoReceiver::start() void VideoReceiver::start()
{ {
#if defined(QGC_GST_STREAMING)
if (_uri.isEmpty()) { if (_uri.isEmpty()) {
qCritical() << "VideoReceiver::start() failed because URI is not specified"; qCritical() << "VideoReceiver::start() failed because URI is not specified";
return; return;
...@@ -158,15 +165,18 @@ void VideoReceiver::start() ...@@ -158,15 +165,18 @@ void VideoReceiver::start()
_pipeline = NULL; _pipeline = NULL;
} }
} }
#endif
} }
void VideoReceiver::stop() void VideoReceiver::stop()
{ {
#if defined(QGC_GST_STREAMING)
if (_pipeline != NULL) { if (_pipeline != NULL) {
gst_element_set_state(_pipeline, GST_STATE_NULL); gst_element_set_state(_pipeline, GST_STATE_NULL);
gst_object_unref(_pipeline); gst_object_unref(_pipeline);
_pipeline = NULL; _pipeline = NULL;
} }
#endif
} }
void VideoReceiver::setUri(const QString & uri) void VideoReceiver::setUri(const QString & uri)
...@@ -175,6 +185,7 @@ void VideoReceiver::setUri(const QString & uri) ...@@ -175,6 +185,7 @@ void VideoReceiver::setUri(const QString & uri)
_uri = uri; _uri = uri;
} }
#if defined(QGC_GST_STREAMING)
void VideoReceiver::_onBusMessage(GstMessage* msg) void VideoReceiver::_onBusMessage(GstMessage* msg)
{ {
switch (GST_MESSAGE_TYPE(msg)) { switch (GST_MESSAGE_TYPE(msg)) {
...@@ -196,7 +207,9 @@ void VideoReceiver::_onBusMessage(GstMessage* msg) ...@@ -196,7 +207,9 @@ void VideoReceiver::_onBusMessage(GstMessage* msg)
break; break;
} }
} }
#endif
#if defined(QGC_GST_STREAMING)
gboolean VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer data) gboolean VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer data)
{ {
Q_UNUSED(bus) Q_UNUSED(bus)
...@@ -205,3 +218,4 @@ gboolean VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer dat ...@@ -205,3 +218,4 @@ gboolean VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer dat
pThis->_onBusMessage(msg); pThis->_onBusMessage(msg);
return TRUE; return TRUE;
} }
#endif
...@@ -31,7 +31,9 @@ This file is part of the QGROUNDCONTROL project ...@@ -31,7 +31,9 @@ This file is part of the QGROUNDCONTROL project
#define VIDEORECEIVER_H #define VIDEORECEIVER_H
#include <QObject> #include <QObject>
#if defined(QGC_GST_STREAMING)
#include <gst/gst.h> #include <gst/gst.h>
#endif
class VideoReceiver : public QObject class VideoReceiver : public QObject
{ {
...@@ -40,7 +42,9 @@ public: ...@@ -40,7 +42,9 @@ public:
explicit VideoReceiver(QObject* parent = 0); explicit VideoReceiver(QObject* parent = 0);
~VideoReceiver(); ~VideoReceiver();
#if defined(QGC_GST_STREAMING)
void setVideoSink(GstElement* sink); void setVideoSink(GstElement* sink);
#endif
public Q_SLOTS: public Q_SLOTS:
void start (); void start ();
...@@ -48,12 +52,19 @@ public Q_SLOTS: ...@@ -48,12 +52,19 @@ public Q_SLOTS:
void setUri (const QString& uri); void setUri (const QString& uri);
private: private:
#if defined(QGC_GST_STREAMING)
void _onBusMessage(GstMessage* message); void _onBusMessage(GstMessage* message);
static gboolean _onBusMessage(GstBus* bus, GstMessage* msg, gpointer data); static gboolean _onBusMessage(GstBus* bus, GstMessage* msg, gpointer data);
#endif
QString _uri; QString _uri;
#if defined(QGC_GST_STREAMING)
GstElement* _pipeline; GstElement* _pipeline;
GstElement* _videoSink; GstElement* _videoSink;
#endif
}; };
#endif // VIDEORECEIVER_H #endif // VIDEORECEIVER_H
...@@ -50,26 +50,13 @@ VideoEnabled { ...@@ -50,26 +50,13 @@ VideoEnabled {
GST_PLUGIN_BUILD_STATIC \ GST_PLUGIN_BUILD_STATIC \
QTGLVIDEOSINK_NAME=qt5glvideosink \ QTGLVIDEOSINK_NAME=qt5glvideosink \
QTVIDEOSINK_NAME=qt5videosink QTVIDEOSINK_NAME=qt5videosink
#QT_NO_KEYWORDS \
INCLUDEPATH += \ INCLUDEPATH += \
$$PWD \
$$PWD/gstqtvideosink \ $$PWD/gstqtvideosink \
$$PWD/gstqtvideosink/delegates \ $$PWD/gstqtvideosink/delegates \
$$PWD/gstqtvideosink/painters \ $$PWD/gstqtvideosink/painters \
$$PWD/gstqtvideosink/utils \ $$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) #-- QtGstreamer (gutted to our needs)
HEADERS += \ HEADERS += \
......
...@@ -27,25 +27,33 @@ This file is part of the QGROUNDCONTROL project ...@@ -27,25 +27,33 @@ This file is part of the QGROUNDCONTROL project
* @author Gus Grubba <mavlink@grubba.com> * @author Gus Grubba <mavlink@grubba.com>
*/ */
#if defined(QGC_GST_STREAMING)
#include "VideoSurface_p.h" #include "VideoSurface_p.h"
#endif
#include "VideoSurface.h"
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtQuick/QQuickItem> #include <QtQuick/QQuickItem>
VideoSurface::VideoSurface(QObject *parent) VideoSurface::VideoSurface(QObject *parent)
: QObject(parent) : QObject(parent)
#if defined(QGC_GST_STREAMING)
, _data(new VideoSurfacePrivate) , _data(new VideoSurfacePrivate)
#endif
{ {
} }
VideoSurface::~VideoSurface() VideoSurface::~VideoSurface()
{ {
#if defined(QGC_GST_STREAMING)
if (_data->videoSink != NULL) { if (_data->videoSink != NULL) {
gst_element_set_state(_data->videoSink, GST_STATE_NULL); gst_element_set_state(_data->videoSink, GST_STATE_NULL);
} }
delete _data; delete _data;
#endif
} }
#if defined(QGC_GST_STREAMING)
GstElement* VideoSurface::videoSink() const GstElement* VideoSurface::videoSink() const
{ {
if (_data->videoSink == NULL) { if (_data->videoSink == NULL) {
...@@ -71,4 +79,5 @@ void VideoSurface::onUpdateThunk(GstElement* sink, gpointer data) ...@@ -71,4 +79,5 @@ void VideoSurface::onUpdateThunk(GstElement* sink, gpointer data)
VideoSurface* pThis = (VideoSurface* )data; VideoSurface* pThis = (VideoSurface* )data;
pThis->onUpdate(); pThis->onUpdate();
} }
#endif
...@@ -32,9 +32,13 @@ This file is part of the QGROUNDCONTROL project ...@@ -32,9 +32,13 @@ This file is part of the QGROUNDCONTROL project
#include <QtCore/QObject> #include <QtCore/QObject>
#if defined(QGC_GST_STREAMING)
#include <gst/gst.h> #include <gst/gst.h>
#endif
#if defined(QGC_GST_STREAMING)
class VideoSurfacePrivate; class VideoSurfacePrivate;
#endif
class VideoSurface : public QObject class VideoSurface : public QObject
{ {
...@@ -48,15 +52,21 @@ public: ...@@ -48,15 +52,21 @@ public:
* The element will be constructed the first time that this function * The element will be constructed the first time that this function
* is called. The surface will always keep a reference to this element. * is called. The surface will always keep a reference to this element.
*/ */
#if defined(QGC_GST_STREAMING)
GstElement* videoSink() const; GstElement* videoSink() const;
#endif
protected: protected:
#if defined(QGC_GST_STREAMING)
void onUpdate(); void onUpdate();
static void onUpdateThunk(GstElement* sink, gpointer data); static void onUpdateThunk(GstElement* sink, gpointer data);
#endif
private: private:
friend class VideoItem; friend class VideoItem;
#if defined(QGC_GST_STREAMING)
VideoSurfacePrivate * const _data; VideoSurfacePrivate * const _data;
#endif
}; };
Q_DECLARE_METATYPE(VideoSurface*) Q_DECLARE_METATYPE(VideoSurface*)
......
...@@ -31,11 +31,9 @@ This file is part of the QGROUNDCONTROL project ...@@ -31,11 +31,9 @@ This file is part of the QGROUNDCONTROL project
#include <QQmlEngine> #include <QQmlEngine>
#include <QSettings> #include <QSettings>
#if defined(QGC_GST_STREAMING)
#include <VideoItem.h> #include <VideoItem.h>
#include <VideoSurface.h> #include <VideoSurface.h>
#include "VideoReceiver.h" #include "VideoReceiver.h"
#endif
#include "ScreenToolsController.h" #include "ScreenToolsController.h"
#include "FlightDisplay.h" #include "FlightDisplay.h"
...@@ -59,7 +57,6 @@ FlightDisplay::FlightDisplay(QWidget *parent) ...@@ -59,7 +57,6 @@ FlightDisplay::FlightDisplay(QWidget *parent)
#endif #endif
setContextPropertyObject("flightDisplay", this); 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: * 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) ...@@ -89,9 +86,10 @@ FlightDisplay::FlightDisplay(QWidget *parent)
setContextPropertyObject("videoDisplay", pSurface); setContextPropertyObject("videoDisplay", pSurface);
VideoReceiver* pReceiver = new VideoReceiver(this); VideoReceiver* pReceiver = new VideoReceiver(this);
pReceiver->setUri(QLatin1Literal("udp://0.0.0.0:5000")); pReceiver->setUri(QLatin1Literal("udp://0.0.0.0:5000"));
#if defined(QGC_GST_STREAMING)
pReceiver->setVideoSink(pSurface->videoSink()); pReceiver->setVideoSink(pSurface->videoSink());
setContextPropertyObject("videoReceiver", pReceiver);
#endif #endif
setContextPropertyObject("videoReceiver", pReceiver);
setSource(QUrl::fromUserInput("qrc:/qml/FlightDisplay.qml")); setSource(QUrl::fromUserInput("qrc:/qml/FlightDisplay.qml"));
setVisible(true); setVisible(true);
......
...@@ -44,9 +44,17 @@ public: ...@@ -44,9 +44,17 @@ public:
/// @brief Invokes the Flight Display Options menu /// @brief Invokes the Flight Display Options menu
void showOptionsMenu() { emit showOptionsMenuChanged(); } void showOptionsMenu() { emit showOptionsMenuChanged(); }
Q_PROPERTY(bool hasVideo READ hasVideo CONSTANT)
Q_INVOKABLE void saveSetting (const QString &key, const QString& value); Q_INVOKABLE void saveSetting (const QString &key, const QString& value);
Q_INVOKABLE QString loadSetting (const QString &key, const QString& defaultValue); 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: signals:
void showOptionsMenuChanged (); void showOptionsMenuChanged ();
......
...@@ -91,6 +91,13 @@ Item { ...@@ -91,6 +91,13 @@ Item {
videoBackground.visible = false; videoBackground.visible = false;
flightDisplay.saveSetting("showVideoBackground", setBool(videoBackground.visible)); 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 { Menu {
...@@ -141,6 +148,7 @@ Item { ...@@ -141,6 +148,7 @@ Item {
MenuSeparator {} MenuSeparator {}
MenuItem { MenuItem {
id: videoMenu
text: "Video Background" text: "Video Background"
checkable: true checkable: true
checked: videoBackground.visible checked: videoBackground.visible
......
...@@ -35,17 +35,19 @@ VideoItem { ...@@ -35,17 +35,19 @@ VideoItem {
id: videoBackground id: videoBackground
property var display property var display
property var receiver property var receiver
surface: display surface: display
onVisibleChanged: { onVisibleChanged: {
if(videoBackground.visible) { if(videoBackground.receiver && videoBackground.display) {
receiver.start(); if(videoBackground.visible) {
} else { videoBackground.receiver.start();
receiver.stop(); } else {
videoBackground.receiver.stop();
}
} }
} }
Component.onCompleted: { Component.onCompleted: {
if(videoBackground.visible) { if(videoBackground.visible && videoBackground.receiver) {
receiver.start(); videoBackground.receiver.start();
} }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment