From 3ade8ee12fdca4c3168b21f882929e4a48ffdf0b Mon Sep 17 00:00:00 2001
From: Ming Rui Zhang <mingrui.zhang@savoirfairelinux.com>
Date: Mon, 23 Nov 2020 15:29:23 -0500
Subject: [PATCH] video: add black background in previewrenderer and flow
 optimization

Change-Id: I979dcc7d7a65029a1ee361579e51575ea813f0e7
---
 src/avadapter.cpp                             | 19 +++++++++++----
 src/avadapter.h                               |  2 +-
 src/mainview/components/VideoCallPage.qml     |  8 +++++++
 src/previewrenderer.cpp                       | 21 ++++++++++++++--
 src/previewrenderer.h                         |  6 +++--
 src/settingsview/components/VideoSettings.qml | 24 ++++++++++++++-----
 6 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/src/avadapter.cpp b/src/avadapter.cpp
index d22aa1c87..e1e750df3 100644
--- a/src/avadapter.cpp
+++ b/src/avadapter.cpp
@@ -66,13 +66,19 @@ AvAdapter::populateVideoDeviceContextMenuItem()
 void
 AvAdapter::onVideoContextMenuDeviceItemClicked(const QString& deviceName)
 {
+    auto* convModel = LRCInstance::getCurrentConversationModel();
+    const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
+    auto call = LRCInstance::getCallInfoForConversation(conversation);
+    if (!call)
+        return;
+
     auto deviceId = LRCInstance::avModel().getDeviceIdFromName(deviceName);
     if (deviceId.isEmpty()) {
         qWarning() << "Couldn't find device: " << deviceName;
         return;
     }
-    LRCInstance::avModel().switchInputTo(deviceId);
     LRCInstance::avModel().setCurrentVideoCaptureDevice(deviceId);
+    LRCInstance::avModel().switchInputTo(deviceId, call->id);
 }
 
 void
@@ -179,8 +185,9 @@ AvAdapter::slotDeviceEvent()
             avModel.switchInputTo({}, callId);
             avModel.stopPreview();
         } else if (deviceEvent == DeviceEvent::RemovedCurrent && currentDeviceListSize > 0) {
-            avModel.switchInputTo(defaultDevice, callId);
+            avModel.setDefaultDevice(defaultDevice);
             avModel.setCurrentVideoCaptureDevice(defaultDevice);
+            avModel.switchInputTo(defaultDevice, callId);
         }
     };
 
@@ -190,14 +197,18 @@ AvAdapter::slotDeviceEvent()
                               [cb] { QtConcurrent::run([cb]() { cb(); }); });
     } else {
         if (deviceEvent == DeviceEvent::Added && currentDeviceListSize == 1) {
-            avModel.switchInputTo(defaultDevice, callId);
+            avModel.setDefaultDevice(defaultDevice);
             avModel.setCurrentVideoCaptureDevice(defaultDevice);
+            if (callId.isEmpty())
+                LRCInstance::renderer()->startPreviewing();
+            else
+                avModel.switchInputTo(defaultDevice, callId);
         } else {
             cb();
         }
     }
 
-    emit videoDeviceListChanged();
+    emit videoDeviceListChanged(currentDeviceListSize == 0);
 
     deviceListSize_ = currentDeviceListSize;
 }
\ No newline at end of file
diff --git a/src/avadapter.h b/src/avadapter.h
index 8c2c98a31..3c7d619bb 100644
--- a/src/avadapter.h
+++ b/src/avadapter.h
@@ -37,7 +37,7 @@ signals:
     /*
      * Emitted when the size of the video capture device list changes.
      */
-    void videoDeviceListChanged();
+    void videoDeviceListChanged(bool listIsEmpty);
 
 protected:
     void safeInit() override {};
diff --git a/src/mainview/components/VideoCallPage.qml b/src/mainview/components/VideoCallPage.qml
index 45ad4d5bc..a7897d3f0 100644
--- a/src/mainview/components/VideoCallPage.qml
+++ b/src/mainview/components/VideoCallPage.qml
@@ -244,6 +244,14 @@ Rectangle {
                         }
                     }
 
+                    Connections {
+                        target: AvAdapter
+
+                        function onVideoDeviceListChanged(listIsEmpty) {
+                            previewRenderer.visible = !listIsEmpty
+                        }
+                    }
+
                     width: Math.max(videoCallPageMainRect.width / 5, JamiTheme.minimumPreviewWidth)
                     x: videoCallPageMainRect.width - previewRenderer.width - previewMargin
                     y: videoCallPageMainRect.height - previewRenderer.height - previewMargin - 56 // Avoid overlay
diff --git a/src/previewrenderer.cpp b/src/previewrenderer.cpp
index d935dcfc7..22e179653 100644
--- a/src/previewrenderer.cpp
+++ b/src/previewrenderer.cpp
@@ -32,11 +32,16 @@ PreviewRenderer::PreviewRenderer(QQuickItem* parent)
     previewFrameUpdatedConnection_ = connect(LRCInstance::renderer(),
                                              &RenderManager::previewFrameUpdated,
                                              [this]() { update(QRect(0, 0, width(), height())); });
+
+    previewRenderingStopped_ = connect(LRCInstance::renderer(),
+                                       &RenderManager::previewRenderingStopped,
+                                       [this]() { update(QRect(0, 0, width(), height())); });
 }
 
 PreviewRenderer::~PreviewRenderer()
 {
     disconnect(previewFrameUpdatedConnection_);
+    disconnect(previewRenderingStopped_);
 }
 
 void
@@ -63,11 +68,23 @@ PreviewRenderer::paint(QPainter* painter)
         scaledPreview = previewImage->scaled(size().toSize(), Qt::KeepAspectRatio);
         painter->drawImage(QRect(0, 0, scaledPreview.width(), scaledPreview.height()),
                            scaledPreview);
+    } else {
+        paintBackground(painter);
     }
 }
 
+void
+PreviewRenderer::paintBackground(QPainter* painter)
+{
+    QBrush brush(Qt::black);
+    QPainterPath path;
+    path.addRect(QRect(0, 0, width(), height()));
+    painter->fillPath(path, brush);
+}
+
 VideoCallPreviewRenderer::VideoCallPreviewRenderer(QQuickItem* parent)
-    : PreviewRenderer(parent) {
+    : PreviewRenderer(parent)
+{
     setProperty("previewImageScalingFactor", 1.0);
 }
 
@@ -79,7 +96,7 @@ VideoCallPreviewRenderer::paint(QPainter* painter)
     auto previewImage = LRCInstance::renderer()->getPreviewFrame();
     if (previewImage) {
         auto scalingFactor = static_cast<qreal>(previewImage->height())
-                / static_cast<qreal>(previewImage->width());
+                             / static_cast<qreal>(previewImage->width());
         setProperty("previewImageScalingFactor", scalingFactor);
         QImage scaledPreview;
         scaledPreview = previewImage->scaled(size().toSize(), Qt::KeepAspectRatio);
diff --git a/src/previewrenderer.h b/src/previewrenderer.h
index 1da8a38fd..b607f2901 100644
--- a/src/previewrenderer.h
+++ b/src/previewrenderer.h
@@ -34,16 +34,18 @@ public:
 
 protected:
     void paint(QPainter* painter) override;
+    void paintBackground(QPainter* painter);
 
 private:
     QMetaObject::Connection previewFrameUpdatedConnection_;
+    QMetaObject::Connection previewRenderingStopped_;
 };
 
 class VideoCallPreviewRenderer : public PreviewRenderer
 {
     Q_OBJECT
-    Q_PROPERTY(qreal previewImageScalingFactor MEMBER previewImageScalingFactor_
-               NOTIFY previewImageScalingFactorChanged)
+    Q_PROPERTY(qreal previewImageScalingFactor MEMBER previewImageScalingFactor_ NOTIFY
+                   previewImageScalingFactorChanged)
 public:
     explicit VideoCallPreviewRenderer(QQuickItem* parent = 0);
     virtual ~VideoCallPreviewRenderer();
diff --git a/src/settingsview/components/VideoSettings.qml b/src/settingsview/components/VideoSettings.qml
index 16f43360a..721c75a3d 100644
--- a/src/settingsview/components/VideoSettings.qml
+++ b/src/settingsview/components/VideoSettings.qml
@@ -49,10 +49,18 @@ ColumnLayout {
     function populateVideoSettings() {
         deviceComboBoxSetting.comboModel.reset()
 
-        var count = deviceComboBoxSetting.comboModel.deviceCount() > 0
-        deviceComboBoxSetting.setEnabled(count)
-        resolutionComboBoxSetting.setEnabled(count)
-        fpsComboBoxSetting.setEnabled(count)
+        var count = deviceComboBoxSetting.comboModel.deviceCount()
+        var deviceListIsEmpty = count === 0
+
+        previewWidget.visible = count > 0
+        deviceComboBoxSetting.setEnabled(count > 0)
+        resolutionComboBoxSetting.setEnabled(count > 0)
+        fpsComboBoxSetting.setEnabled(count > 0)
+
+        if (deviceListIsEmpty) {
+            resolutionComboBoxSetting.comboModel.reset()
+            fpsComboBoxSetting.comboModel.reset()
+        }
 
         deviceComboBoxSetting.setCurrentIndex(
                     deviceComboBoxSetting.comboModel.getCurrentSettingIndex(), true)
@@ -71,8 +79,11 @@ ColumnLayout {
                 return
             }
 
-            AVModel.setCurrentVideoCaptureDevice(deviceId)
-            AVModel.setDefaultDevice(deviceId)
+            if (AVModel.getCurrentVideoCaptureDevice() !== deviceId) {
+                AVModel.setCurrentVideoCaptureDevice(deviceId)
+                AVModel.setDefaultDevice(deviceId)
+            }
+
             setFormatListForCurrentDevice()
             startPreviewing()
         } catch(err){ console.warn(err.message) }
@@ -99,6 +110,7 @@ ColumnLayout {
         var resolution
         var rate
         if(isResolutionIndex) {
+            fpsComboBoxSetting.comboModel.reset()
             resolution = resolutionComboBoxSetting.comboModel.data(
                         resolutionComboBoxSetting.comboModel.index(index, 0),
                         VideoFormatResolutionModel.Resolution)
-- 
GitLab