diff --git a/src/VideoStreaming/VideoManager.cc b/src/VideoStreaming/VideoManager.cc index 419945f5111e2f516c77fbb1f7e0760c15558736..82948638a8e7969ded6983382d4783295082f6c8 100644 --- a/src/VideoStreaming/VideoManager.cc +++ b/src/VideoStreaming/VideoManager.cc @@ -89,11 +89,9 @@ VideoManager::setToolbox(QGCToolbox *toolbox) for (auto *videoReceiver : { _videoReceiver, _thermalVideoReceiver}) { // First, Setup the current values from the settings. videoReceiver->setRtspTimeout(_videoSettings->rtspTimeout()->rawValue().toInt()); - videoReceiver->setMaxVideoSize(_videoSettings->maxVideoSize()->rawValue().toInt()); videoReceiver->setStreamEnabled(_videoSettings->streamEnabled()->rawValue().toBool()); videoReceiver->setRecordingFormatId(_videoSettings->recordingFormat()->rawValue().toInt()); videoReceiver->setStreamConfigured(_videoSettings->streamConfigured()); - videoReceiver->setStorageLimit(_videoSettings->enableStorageLimit()->rawValue().toBool()); connect(_videoSettings->rtspTimeout(), &Fact::rawValueChanged, videoReceiver, [videoReceiver](const QVariant &value) { @@ -101,12 +99,6 @@ VideoManager::setToolbox(QGCToolbox *toolbox) } ); - connect(_videoSettings->maxVideoSize(), &Fact::rawValueChanged, - videoReceiver, [videoReceiver](const QVariant &value) { - videoReceiver->setMaxVideoSize(value.toInt()); - } - ); - connect(_videoSettings->streamEnabled(), &Fact::rawValueChanged, videoReceiver, [videoReceiver](const QVariant &value) { videoReceiver->setStreamEnabled(value.toBool()); @@ -119,12 +111,6 @@ VideoManager::setToolbox(QGCToolbox *toolbox) } ); - connect(_videoSettings->enableStorageLimit(), &Fact::rawValueChanged, - videoReceiver, [videoReceiver](const QVariant &value) { - videoReceiver->setStorageLimit(value.toInt()); - } - ); - // Why some options are facts while others aren't? connect(_videoSettings, &VideoSettings::streamConfiguredChanged, videoReceiver, &VideoReceiver::setStreamConfigured); @@ -135,6 +121,7 @@ VideoManager::setToolbox(QGCToolbox *toolbox) // Connect the video receiver with the rest of the app. connect(videoReceiver, &VideoReceiver::restartTimeout, this, &VideoManager::restartVideo); connect(videoReceiver, &VideoReceiver::sendMessage, qgcApp(), &QGCApplication::showMessage); + connect(videoReceiver, &VideoReceiver::beforeRecording, this, &VideoManager::cleanupOldVideos); } _updateSettings(); @@ -148,6 +135,55 @@ VideoManager::setToolbox(QGCToolbox *toolbox) #endif } +QStringList VideoManager::videoMuxes() +{ + return {"matroskamux", "qtmux", "mp4mux"}; +} + +QStringList VideoManager::videoExtensions() +{ + return {"mkv", "mov", "mp4"}; +} + +void VideoManager::cleanupOldVideos() +{ +#if defined(QGC_GST_STREAMING) + //-- Only perform cleanup if storage limit is enabled + if(!_videoSettings->enableStorageLimit()->rawValue().toBool()) { + return; + } + QString savePath = qgcApp()->toolbox()->settingsManager()->appSettings()->videoSavePath(); + QDir videoDir = QDir(savePath); + videoDir.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable); + videoDir.setSorting(QDir::Time); + + QStringList nameFilters; + for(const QString& extension : videoExtensions()) { + nameFilters << QString("*.") + extension; + } + videoDir.setNameFilters(nameFilters); + //-- get the list of videos stored + QFileInfoList vidList = videoDir.entryInfoList(); + if(!vidList.isEmpty()) { + uint64_t total = 0; + //-- Settings are stored using MB + uint64_t maxSize = _videoSettings->maxVideoSize()->rawValue().toUInt() * 1024 * 1024; + //-- Compute total used storage + for(int i = 0; i < vidList.size(); i++) { + total += vidList[i].size(); + } + //-- Remove old movies until max size is satisfied. + while(total >= maxSize && !vidList.isEmpty()) { + total -= vidList.last().size(); + qCDebug(VideoReceiverLog) << "Removing old video file:" << vidList.last().filePath(); + QFile file (vidList.last().filePath()); + file.remove(); + vidList.removeLast(); + } + } +#endif +} + //----------------------------------------------------------------------------- void VideoManager::startVideo() diff --git a/src/VideoStreaming/VideoManager.h b/src/VideoStreaming/VideoManager.h index f53f28223992f202e1fdb2d8b8c45bf7f6a1ee31..54e6051d3256e186738dc70ed741e4c4b2dc1e81 100644 --- a/src/VideoStreaming/VideoManager.h +++ b/src/VideoStreaming/VideoManager.h @@ -67,6 +67,9 @@ public: virtual VideoReceiver* videoReceiver () { return _videoReceiver; } virtual VideoReceiver* thermalVideoReceiver () { return _thermalVideoReceiver; } + QStringList videoExtensions(); + QStringList videoMuxes(); + #if defined(QGC_DISABLE_UVC) virtual bool uvcEnabled () { return false; } #else @@ -82,6 +85,8 @@ public: Q_INVOKABLE void startVideo (); Q_INVOKABLE void stopVideo (); + void cleanupOldVideos(); + signals: void hasVideoChanged (); void isGStreamerChanged (); diff --git a/src/VideoStreaming/VideoReceiver.cc b/src/VideoStreaming/VideoReceiver.cc index 19ced14c6c9d3bd9466a09d1214129be35a1070a..8608433c2e65e482503d34cfd1a25fc86b64de0a 100644 --- a/src/VideoStreaming/VideoReceiver.cc +++ b/src/VideoStreaming/VideoReceiver.cc @@ -70,7 +70,6 @@ VideoReceiver::VideoReceiver(QObject* parent) , _showFullScreen(false) , _streamEnabled(false) , _streamConfigured(false) - , _storageLimit(false) , _unittTestMode(false) , _isTaisync(false) { @@ -459,19 +458,6 @@ void VideoReceiver::setStreamConfigured(bool enabled) } } -bool VideoReceiver::storageLimit() const -{ - return _storageLimit; -} - -void VideoReceiver::setStorageLimit(bool enabled) -{ - if (_storageLimit != enabled) { - _storageLimit = enabled; - emit storageLimitChanged(); - } -} - bool VideoReceiver::isTaisync() const { return _isTaisync; @@ -511,19 +497,6 @@ void VideoReceiver::setImagePath(const QString& value) } } -int VideoReceiver::maxVideoSize() const -{ - return _maxVideoSize; -} - -void VideoReceiver::setMaxVideoSize(int value) -{ - if (_maxVideoSize != value) { - _maxVideoSize = value; - emit maxVideoSizeChanged(); - } -} - int VideoReceiver::recordingFormatId() const { return _recordingFormatId; @@ -877,46 +850,6 @@ VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer data) } #endif -//----------------------------------------------------------------------------- -#if defined(QGC_GST_STREAMING) -void -VideoReceiver::_cleanupOldVideos() -{ - //-- Only perform cleanup if storage limit is enabled - if(_storageLimit) { - QString savePath = _videoPath; - QDir videoDir = QDir(savePath); - videoDir.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable); - videoDir.setSorting(QDir::Time); - //-- All the movie extensions we support - QStringList nameFilters; - for(uint32_t i = 0; i < NUM_MUXES; i++) { - nameFilters << QString("*.") + QString(kVideoExtensions[i]); - } - videoDir.setNameFilters(nameFilters); - //-- get the list of videos stored - QFileInfoList vidList = videoDir.entryInfoList(); - if(!vidList.isEmpty()) { - uint64_t total = 0; - //-- Settings are stored using MB - uint64_t maxSize = _maxVideoSize * 1024 * 1024; - //-- Compute total used storage - for(int i = 0; i < vidList.size(); i++) { - total += vidList[i].size(); - } - //-- Remove old movies until max size is satisfied. - while(total >= maxSize && !vidList.isEmpty()) { - total -= vidList.last().size(); - qCDebug(VideoReceiverLog) << "Removing old video file:" << vidList.last().filePath(); - QFile file (vidList.last().filePath()); - file.remove(); - vidList.removeLast(); - } - } - } -} -#endif - //----------------------------------------------------------------------------- #if defined(QGC_GST_STREAMING) void @@ -1049,6 +982,7 @@ void VideoReceiver::startRecording(const QString &videoFile) { #if defined(QGC_GST_STREAMING) + emit beforeRecording(); qCDebug(VideoReceiverLog) << "Starting recording"; // exit immediately if we are already recording @@ -1063,9 +997,6 @@ VideoReceiver::startRecording(const QString &videoFile) return; } - //-- Disk usage maintenance - _cleanupOldVideos(); - QString savePath = _videoPath; if(savePath.isEmpty()) { emit sendMessage(tr("Unabled to record video. Video save path must be specified in Settings.")); diff --git a/src/VideoStreaming/VideoReceiver.h b/src/VideoStreaming/VideoReceiver.h index 165f08c8b1f9870d51deedf00b4cfb52a6af5ede..dac93c3acc5b81f4bbd23c33d77180916558706a 100644 --- a/src/VideoStreaming/VideoReceiver.h +++ b/src/VideoStreaming/VideoReceiver.h @@ -45,10 +45,8 @@ public: Q_PROPERTY(bool showFullScreen READ showFullScreen WRITE setShowFullScreen NOTIFY showFullScreenChanged) Q_PROPERTY(bool streamEnabled READ streamEnabled WRITE setStreamEnabled NOTIFY streamEnabledChanged) Q_PROPERTY(bool streamConfigured READ streamConfigured WRITE setStreamConfigured NOTIFY streamConfiguredChanged) - Q_PROPERTY(bool storageLimit READ storageLimit WRITE setStorageLimit NOTIFY storageLimitChanged) Q_PROPERTY(bool isTaisync READ isTaisync WRITE setIsTaysinc NOTIFY isTaisyncChanged) - Q_PROPERTY(int maxVideoSize READ maxVideoSize WRITE setMaxVideoSize NOTIFY maxVideoSizeChanged) Q_PROPERTY(int recordingFormatId READ recordingFormatId WRITE setRecordingFormatId NOTIFY recordingFormatIdChanged) Q_PROPERTY(int rtspTimeout READ rtspTimeout WRITE setRtspTimeout NOTIFY rtspTimeoutChanged) @@ -63,10 +61,6 @@ public: Q_SLOT void setStreamConfigured(bool enabled); Q_SIGNAL void streamConfiguredChanged(); - bool storageLimit() const; - Q_SLOT void setStorageLimit(bool enabled); - Q_SIGNAL void storageLimitChanged(); - bool isTaisync() const; Q_SLOT void setIsTaysinc(bool value); Q_SIGNAL void isTaisyncChanged(); @@ -79,10 +73,6 @@ public: Q_SLOT void setImagePath(const QString& path); Q_SIGNAL void imagePathChanged(); - int maxVideoSize() const; - Q_SLOT void setMaxVideoSize(int value); - Q_SIGNAL void maxVideoSizeChanged(); - int recordingFormatId() const; Q_SLOT void setRecordingFormatId(int value); Q_SIGNAL void recordingFormatIdChanged(); @@ -94,6 +84,8 @@ public: Q_SIGNAL void restartTimeout(); Q_SIGNAL void sendMessage(const QString& message); + // Emitted before recording starts. + Q_SIGNAL void beforeRecording(); void setUnittestMode(bool runUnitTests); #if defined(QGC_GST_STREAMING) virtual bool recording () { return _recording; } @@ -172,7 +164,6 @@ protected: virtual void _unlinkRecordingBranch (GstPadProbeInfo* info); virtual void _shutdownRecordingBranch(); virtual void _shutdownPipeline (); - virtual void _cleanupOldVideos (); GstElement* _pipeline; GstElement* _videoSink; @@ -201,7 +192,6 @@ protected: bool _storageLimit; bool _unittTestMode; bool _isTaisync; - int _maxVideoSize; // in mbs. int _recordingFormatId; // 0 - 2, defined in VideoReceiver.cc / kVideoExtensions. TODO: use a better representation. int _rtspTimeout;