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 += \
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 {
......
......@@ -40,9 +40,9 @@
#include <QDebug>
#if defined(QGC_GST_STREAMING)
#include <VideoItem.h>
#include <VideoSurface.h>
#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<VideoItem>("QGroundControl.QgcQtGStreamer", 1, 0, "VideoItem");
qmlRegisterUncreatableType<VideoSurface>("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;
......
......@@ -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);
......
......@@ -32,35 +32,51 @@ This file is part of the QGROUNDCONTROL project
#include <QtQuick/QSGFlatColorMaterial>
#include "VideoItem.h"
#if defined(QGC_GST_STREAMING)
#include "VideoSurface_p.h"
#endif
#if defined(QGC_GST_STREAMING)
struct VideoItem::Private
{
QPointer<VideoSurface> 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
......@@ -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
......@@ -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
......@@ -31,7 +31,9 @@ This file is part of the QGROUNDCONTROL project
#define VIDEORECEIVER_H
#include <QObject>
#if defined(QGC_GST_STREAMING)
#include <gst/gst.h>
#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
......@@ -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 += \
......
......@@ -27,25 +27,33 @@ This file is part of the QGROUNDCONTROL project
* @author Gus Grubba <mavlink@grubba.com>
*/
#if defined(QGC_GST_STREAMING)
#include "VideoSurface_p.h"
#endif
#include "VideoSurface.h"
#include <QtCore/QDebug>
#include <QtQuick/QQuickItem>
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
......@@ -32,9 +32,13 @@ This file is part of the QGROUNDCONTROL project
#include <QtCore/QObject>
#if defined(QGC_GST_STREAMING)
#include <gst/gst.h>
#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*)
......
......@@ -31,11 +31,9 @@ This file is part of the QGROUNDCONTROL project
#include <QQmlEngine>
#include <QSettings>
#if defined(QGC_GST_STREAMING)
#include <VideoItem.h>
#include <VideoSurface.h>
#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);
......
......@@ -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 ();
......
......@@ -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
......
......@@ -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();
}
}
}
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