From e8b691451771e1cfa5648fc58587a853d742516e Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Mon, 29 May 2023 18:33:20 -0400
Subject: [PATCH] videoprovider: expose the renderer's `active` value QML

Simplifies the property `activeRenderers`.

Gitlab: #1161
Change-Id: I4d39aaf3b96bba774c2492551f0426ea42446690
---
 src/app/commoncomponents/VideoView.qml |  2 +-
 src/app/videoprovider.cpp              | 36 ++++++++++++--------------
 src/app/videoprovider.h                |  8 +++---
 3 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/src/app/commoncomponents/VideoView.qml b/src/app/commoncomponents/VideoView.qml
index 2b2e28632..21ed5d31a 100644
--- a/src/app/commoncomponents/VideoView.qml
+++ b/src/app/commoncomponents/VideoView.qml
@@ -55,7 +55,7 @@ Item {
 
         antialiasing: true
         anchors.fill: parent
-        opacity: videoProvider.renderers[rendererId] !== undefined
+        opacity: videoProvider.activeRenderers[rendererId] === true
         visible: opacity
 
         fillMode: crop ? VideoOutput.PreserveAspectCrop : VideoOutput.PreserveAspectFit
diff --git a/src/app/videoprovider.cpp b/src/app/videoprovider.cpp
index 088605b85..7d18f489b 100644
--- a/src/app/videoprovider.cpp
+++ b/src/app/videoprovider.cpp
@@ -79,14 +79,14 @@ VideoProvider::subscribe(QObject* obj, const QString& id)
             static_cast<Qt::ConnectionType>(Qt::DirectConnection | Qt::UniqueConnection));
 
     QWriteLocker lock(&renderersMutex_);
+    FrameObject* fo = nullptr;
     // Check if we already have a FrameObject for this id.
     auto it = renderers_.find(id);
     if (it == renderers_.end()) {
         qDebug() << "Creating new FrameObject for id:" << id;
-        FrameObject& object = renderers_[id];
-        object.active = false;
-        it = renderers_.find(id);
+        fo = &renderers_[id];
     } else {
+        fo = &it->second;
         // Make sure it's not already subscribed to this QVideoSink.
         if (it->second.subscribers.contains(sink)) {
             qWarning() << Q_FUNC_INFO << "QVideoSink already subscribed to id:" << id;
@@ -94,7 +94,7 @@ VideoProvider::subscribe(QObject* obj, const QString& id)
         }
     }
 
-    it->second.subscribers.insert(sink);
+    fo->subscribers.insert(sink);
     qDebug().noquote() << QString("Added sink: 0x%1 to subscribers for id: %2")
                               .arg((quintptr) obj, QT_POINTER_SIZE, 16, QChar('0'))
                               .arg(id);
@@ -154,6 +154,7 @@ VideoProvider::onRendererStarted(const QString& id, const QSize& size)
     auto frameFormat = QVideoFrameFormat(size, pixelFormat);
 
     renderersMutex_.lockForWrite();
+
     auto it = renderers_.find(id);
     if (it == renderers_.end()) {
         qDebug() << "Create new QVideoFrame" << frameFormat.frameSize();
@@ -165,9 +166,9 @@ VideoProvider::onRendererStarted(const QString& id, const QSize& size)
         it->second.active = true;
         qDebug() << "QVideoFrame reset to" << frameFormat.frameSize();
     }
-    renderersMutex_.unlock();
 
-    Q_EMIT renderersChanged();
+    renderersMutex_.unlock();
+    Q_EMIT activeRenderersChanged();
 }
 
 void
@@ -279,21 +280,21 @@ VideoProvider::onRendererStopped(const QString& id)
         qWarning() << Q_FUNC_INFO << "Can't find renderer for id:" << id;
         return;
     }
+
     if (it->second.subscribers.isEmpty()) {
         renderers_.erase(id);
         renderersMutex_.unlock();
-        Q_EMIT renderersChanged();
+        Q_EMIT activeRenderersChanged();
         return;
     }
 
     it->second.frameMutex.lockForWrite();
     it->second.videoFrame = QVideoFrame();
-    it->second.active = false;
+    it->second.active = true;
     it->second.frameMutex.unlock();
 
     renderersMutex_.unlock();
-
-    Q_EMIT renderersChanged();
+    Q_EMIT activeRenderersChanged();
 }
 
 void
@@ -331,17 +332,12 @@ VideoProvider::copyUnaligned(QVideoFrame& dst, const video::Frame& src)
 }
 
 QVariantMap
-VideoProvider::getRenderers()
+VideoProvider::getActiveRenderers()
 {
-    QVariantMap map;
-    renderersMutex_.lockForRead();
+    QVariantMap activeRenderers;
+    QReadLocker lk(&renderersMutex_);
     for (auto& r : renderers_) {
-        if (r.second.active) {
-            r.second.frameMutex.lockForRead();
-            map[r.first] = r.second.videoFrame.size();
-            r.second.frameMutex.unlock();
-        }
+        activeRenderers[r.first] = r.second.active;
     }
-    renderersMutex_.unlock();
-    return map;
+    return activeRenderers;
 }
diff --git a/src/app/videoprovider.h b/src/app/videoprovider.h
index b44acf329..f579f683a 100644
--- a/src/app/videoprovider.h
+++ b/src/app/videoprovider.h
@@ -40,6 +40,7 @@ class VideoProvider final : public QObject
 {
     Q_OBJECT
     QML_ELEMENT
+    Q_PROPERTY(QVariantMap activeRenderers READ getActiveRenderers NOTIFY activeRenderersChanged)
 public:
     explicit VideoProvider(AVModel& avModel, QObject* parent = nullptr);
     ~VideoProvider() = default;
@@ -49,9 +50,8 @@ public:
     Q_INVOKABLE QString captureVideoFrame(const QString& id);
     Q_INVOKABLE QImage captureRawVideoFrame(const QString& id);
 
-    Q_PROPERTY(QVariantMap renderers READ getRenderers NOTIFY renderersChanged)
-    QVariantMap getRenderers();
-    Q_SIGNAL void renderersChanged();
+    QVariantMap getActiveRenderers();
+    Q_SIGNAL void activeRenderersChanged();
 
 private Q_SLOTS:
     void onRendererStarted(const QString& id, const QSize& size);
@@ -69,7 +69,7 @@ private:
         QReadWriteLock frameMutex;
         QSet<QVideoSink*> subscribers;
         QReadWriteLock subscribersMutex;
-        std::atomic_bool active;
+        bool active;
     };
     std::map<QString, FrameObject> renderers_;
     QReadWriteLock renderersMutex_;
-- 
GitLab