VideoManager.cc 8.86 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/


#include <QQmlContext>
#include <QQmlEngine>
#include <QSettings>
14
#include <QUrl>
15
#include <QDir>
16 17

#ifndef QGC_DISABLE_UVC
18
#include <QCameraInfo>
19
#endif
20 21 22 23 24

#include <VideoItem.h>

#include "ScreenToolsController.h"
#include "VideoManager.h"
25 26 27
#include "QGCToolbox.h"
#include "QGCCorePlugin.h"
#include "QGCOptions.h"
28 29

static const char* kVideoSourceKey  = "VideoSource";
30 31
static const char* kVideoUDPPortKey = "VideoUDPPort";
static const char* kVideoRTSPUrlKey = "VideoRTSPUrl";
32 33
static const char* kNoVideo         = "No Video Available";

34
#if defined(QGC_GST_STREAMING)
35 36 37
#if defined(QGC_ENABLE_VIDEORECORDING)
static const char* kVideoSavePathKey= "VideoSavePath";
#endif
38
static const char* kUDPStream       = "UDP Video Stream";
39
static const char* kRTSPStream      = "RTSP Video Stream";
40
#endif
41 42 43 44 45 46

QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog")

//-----------------------------------------------------------------------------
VideoManager::VideoManager(QGCApplication* app)
    : QGCTool(app)
47 48
    , _videoSurface(NULL)
    , _videoReceiver(NULL)
49
    , _videoRunning(false)
50 51
    , _udpPort(5600) //-- Defalut Port 5600 == Solo UDP Port
    , _init(false)
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
{
}

//-----------------------------------------------------------------------------
VideoManager::~VideoManager()
{

}

//-----------------------------------------------------------------------------
void
VideoManager::setToolbox(QGCToolbox *toolbox)
{
   QGCTool::setToolbox(toolbox);
   QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
   qmlRegisterUncreatableType<VideoManager>("QGroundControl.VideoManager", 1, 0, "VideoManager", "Reference only");
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
   //-- Get saved settings
#if defined(QGC_GST_STREAMING)
   QSettings settings;
#if defined(NO_UDP_VIDEO)
   setVideoSource(settings.value(kVideoSourceKey, kRTSPStream).toString());
#else
   setVideoSource(settings.value(kVideoSourceKey, kUDPStream).toString());
#endif
   //-- Check if core plugin defines its own video requirements
   if(qgcApp()->toolbox()->corePlugin()->options()->definesVideo()) {
       if(qgcApp()->toolbox()->corePlugin()->options()->videoUDPPort()) {
           setUdpPort(qgcApp()->toolbox()->corePlugin()->options()->videoUDPPort());
           setVideoSource(kUDPStream);
       } else {
           setVideoSource(kRTSPStream);
           setRtspURL(qgcApp()->toolbox()->corePlugin()->options()->videoRSTPUrl());
       }
   } else {
       setUdpPort(settings.value(kVideoUDPPortKey, 5600).toUInt());
       setRtspURL(settings.value(kVideoRTSPUrlKey, "rtsp://192.168.42.1:554/live").toString()); //-- Example RTSP URL
   }
89
#if defined(QGC_ENABLE_VIDEORECORDING)
90
   setVideoSavePath(settings.value(kVideoSavePathKey, QDir::homePath()).toString());
91
#endif
92 93 94 95 96 97 98
#endif
   _init = true;
#if defined(QGC_GST_STREAMING)
   _updateVideo();
   connect(&_frameTimer, &QTimer::timeout, this, &VideoManager::_updateTimer);
   _frameTimer.start(1000);
#endif
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
}

//-----------------------------------------------------------------------------
bool
VideoManager::hasVideo()
{
#if defined(QGC_GST_STREAMING)
    return true;
#endif
    return !_videoSource.isEmpty();
}

//-----------------------------------------------------------------------------
bool
VideoManager::isGStreamer()
{
#if defined(QGC_GST_STREAMING)
116
    return _videoSource == kUDPStream || _videoSource == kRTSPStream;
117 118 119 120 121
#else
    return false;
#endif
}

122 123 124 125 126 127 128 129 130
//-----------------------------------------------------------------------------
#ifndef QGC_DISABLE_UVC
bool
VideoManager::uvcEnabled()
{
    return QCameraInfo::availableCameras().count() > 0;
}
#endif

131 132 133 134
//-----------------------------------------------------------------------------
void
VideoManager::setVideoSource(QString vSource)
{
135 136
    if(vSource == kNoVideo)
        return;
137 138 139 140
    _videoSource = vSource;
    QSettings settings;
    settings.setValue(kVideoSourceKey, vSource);
    emit videoSourceChanged();
141
#ifndef QGC_DISABLE_UVC
142 143 144 145 146
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    foreach (const QCameraInfo &cameraInfo, cameras) {
        if(cameraInfo.description() == vSource) {
            _videoSourceID = cameraInfo.deviceName();
            emit videoSourceIDChanged();
147
            qCDebug(VideoManagerLog) << "Found USB source:" << _videoSourceID << " Name:" << _videoSource;
148 149 150
            break;
        }
    }
151
#endif
152 153
    emit isGStreamerChanged();
    qCDebug(VideoManagerLog) << "New Video Source:" << vSource;
154
    /*
155
     * Not working. Requires restart for now. (Undef KRTSP/kUDP above when enabling this)
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
    if(isGStreamer())
        _updateVideo();
    */
    if(_videoReceiver) {
        if(isGStreamer()) {
            _videoReceiver->start();
        } else {
            _videoReceiver->stop();
        }
    }
}

//-----------------------------------------------------------------------------
void
VideoManager::setUdpPort(quint16 port)
{
    _udpPort = port;
    QSettings settings;
    settings.setValue(kVideoUDPPortKey, port);
    emit udpPortChanged();
    /*
177
     * Not working. Requires restart for now. (Undef KRTSP/kUDP above when enabling this)
178 179 180 181 182 183 184 185 186 187 188 189 190 191
    if(_videoSource == kUDPStream)
        _updateVideo();
    */
}

//-----------------------------------------------------------------------------
void
VideoManager::setRtspURL(QString url)
{
    _rtspURL = url;
    QSettings settings;
    settings.setValue(kVideoRTSPUrlKey, url);
    emit rtspURLChanged();
    /*
192
     * Not working. Requires restart for now. (Undef KRTSP/kUDP above when enabling this)
193 194 195
    if(_videoSource == kRTSPStream)
        _updateVideo();
    */
196 197
}

198 199
void
VideoManager::setVideoSavePathByUrl(QUrl url) {
200
#if defined(QGC_ENABLE_VIDEORECORDING)
201
    setVideoSavePath(url.toLocalFile());
202 203 204
#else
    Q_UNUSED(url);
#endif
205 206
}

207 208 209
void
VideoManager::setVideoSavePath(QString path)
{
210
#if defined(QGC_ENABLE_VIDEORECORDING)
211 212 213 214 215 216
    _videoSavePath = path;
    QSettings settings;
    settings.setValue(kVideoSavePathKey, path);
    if(_videoReceiver)
        _videoReceiver->setVideoSavePath(_videoSavePath);
    emit videoSavePathChanged();
217 218 219
#else
    Q_UNUSED(path);
#endif
220 221
}

222 223 224 225 226 227
//-----------------------------------------------------------------------------
QStringList
VideoManager::videoSourceList()
{
    _videoSourceList.clear();
#if defined(QGC_GST_STREAMING)
228 229
    _videoSourceList.append(kUDPStream);
    _videoSourceList.append(kRTSPStream);
230
#endif
231
#ifndef QGC_DISABLE_UVC
232 233 234 235 236
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    foreach (const QCameraInfo &cameraInfo, cameras) {
        qCDebug(VideoManagerLog) << "UVC Video source ID:" << cameraInfo.deviceName() << " Name:" << cameraInfo.description();
        _videoSourceList.append(cameraInfo.description());
    }
237
#endif
238 239
    if(_videoSourceList.count() == 0)
        _videoSourceList.append(kNoVideo);
240 241 242 243
    return _videoSourceList;
}

//-----------------------------------------------------------------------------
244
void VideoManager::_updateTimer()
245
{
246
#if defined(QGC_GST_STREAMING)
247 248 249
    if(_videoReceiver && _videoSurface) {
        if(_videoReceiver->stopping() || _videoReceiver->starting()) {
            return;
250
        }
251 252 253 254

        if(_videoReceiver->streaming()) {
            if(!_videoRunning) {
                _videoSurface->setLastFrame(0);
255 256 257
                _videoRunning = true;
                emit videoRunningChanged();
            }
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
        } else {
            if(_videoRunning) {
                _videoRunning = false;
                emit videoRunningChanged();
            }
        }

        if(_videoRunning) {
            time_t elapsed = 0;
            time_t lastFrame = _videoSurface->lastFrame();
            if(lastFrame != 0) {
                elapsed = time(0) - _videoSurface->lastFrame();
            }
            if(elapsed > 2 && _videoSurface) {
                _videoReceiver->stop();
            }
        } else {
            if(!_videoReceiver->running()) {
                _videoReceiver->start();
            }
278 279 280
        }
    }
#endif
281 282 283 284 285 286 287 288 289 290 291 292
}

//-----------------------------------------------------------------------------
void VideoManager::_updateVideo()
{
    if(_init) {
        if(_videoReceiver)
            delete _videoReceiver;
        if(_videoSurface)
            delete _videoSurface;
        _videoSurface  = new VideoSurface;
        _videoReceiver = new VideoReceiver(this);
293
#if defined(QGC_GST_STREAMING)
294
        _videoReceiver->setVideoSink(_videoSurface->videoSink());
295 296 297 298
        if(_videoSource == kUDPStream)
            _videoReceiver->setUri(QStringLiteral("udp://0.0.0.0:%1").arg(_udpPort));
        else
            _videoReceiver->setUri(_rtspURL);
299
#if defined(QGC_ENABLE_VIDEORECORDING)
300
        _videoReceiver->setVideoSavePath(_videoSavePath);
301 302
#endif
#endif
303 304 305
        _videoReceiver->start();
    }
}