From d6e2b8a332862d06f548abc649fb037c628a2604 Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Mon, 28 Oct 2019 11:10:44 -0400
Subject: [PATCH] video device: use device id instead of friendly name

- Video settings, and APIs will now use a device id, which will be
  a path on platforms where everything is a file, and a DevicePath
  with a bonus ffmpeg-dshow compliant prefix on Windows.

- The device's friendly name is uniquified, and stored in the
  settings still, but only retrieved/translated for UI.

- MRLs are now constructed with the device id.

Change-Id: I092f08cc2cd31bd78aeec5c774c2cc33d75c1d4e
---
 bin/dbus/cx.ring.Ring.VideoManager.xml        |  24 +--
 bin/dbus/dbusvideomanager.cpp                 |  20 +-
 bin/dbus/dbusvideomanager.h                   |  10 +-
 src/client/videomanager.cpp                   |  30 +--
 src/client/videomanager.h                     |   2 +-
 src/dring/videomanager_interface.h            |  14 +-
 .../video/androidvideo/video_device_impl.cpp  |   1 +
 .../video/iosvideo/video_device_impl.cpp      |   2 +-
 src/media/video/osxvideo/video_device_impl.mm |   8 +-
 src/media/video/v4l2/video_device_impl.cpp    |  10 +-
 src/media/video/video_base.cpp                |   4 +
 src/media/video/video_base.h                  |   1 +
 src/media/video/video_device.h                |   8 +-
 src/media/video/video_device_monitor.cpp      | 176 +++++++-----------
 src/media/video/video_device_monitor.h        |  10 +-
 .../video/winvideo/video_device_impl.cpp      |  16 +-
 .../winvideo/video_device_monitor_impl.cpp    |   6 +-
 17 files changed, 155 insertions(+), 187 deletions(-)

diff --git a/bin/dbus/cx.ring.Ring.VideoManager.xml b/bin/dbus/cx.ring.Ring.VideoManager.xml
index 4b637dc602..6d0d51202b 100644
--- a/bin/dbus/cx.ring.Ring.VideoManager.xml
+++ b/bin/dbus/cx.ring.Ring.VideoManager.xml
@@ -4,33 +4,33 @@
         <!-- Video device methods -->
 
         <method name="getDeviceList" tp:name-for-bindings="getDeviceList">
-            <tp:docstring>Returns a list of the detected v4l2 devices</tp:docstring>
+            <tp:docstring>Returns a list of ids for detected devices</tp:docstring>
             <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/>
             <arg type="as" name="list" direction="out">
             </arg>
         </method>
 
         <method name="getCapabilities" tp:name-for-bindings="getCapabilities">
-           <tp:docstring>Returns a map of map of array of strings, containing the capabilities (channel, size, rate) of a device</tp:docstring>
+            <tp:docstring>Returns a map of map of array of strings, containing the capabilities (channel, size, rate) for a given device id</tp:docstring>
             <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringMapStringVectorString"/>
-            <arg type="s" name="name" direction="in">
+            <arg type="s" name="deviceId" direction="in">
             </arg>
             <arg type="a{sa{sas}}" name="cap" direction="out">
             </arg>
         </method>
 
         <method name="getSettings" tp:name-for-bindings="getSettings">
-           <tp:docstring>Returns a map of settings for the given device name</tp:docstring>
+            <tp:docstring>Returns a map of settings for the given device id</tp:docstring>
             <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringString"/>
-            <arg type="s" name="device" direction="in">
+            <arg type="s" name="deviceId" direction="in">
             </arg>
             <arg type="a{ss}" name="map" direction="out">
             </arg>
         </method>
 
         <method name="applySettings" tp:name-for-bindings="applySettings">
-            <tp:docstring>Set the preferred settings for a given device name</tp:docstring>
-            <arg type="s" name="name" direction="in">
+            <tp:docstring>Set the preferred settings for a given device id</tp:docstring>
+            <arg type="s" name="deviceId" direction="in">
             </arg>
             <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="MapStringString"/>
             <arg type="a{ss}" name="settings" direction="in">
@@ -38,12 +38,14 @@
         </method>
 
         <method name="getDefaultDevice" tp:name-for-bindings="getDefaultDevice">
-            <arg type="s" name="name" direction="out">
+            <tp:docstring>Returns the default device id</tp:docstring>
+            <arg type="s" name="deviceId" direction="out">
             </arg>
         </method>
 
         <method name="setDefaultDevice" tp:name-for-bindings="setDefaultDevice">
-            <arg type="s" name="name" direction="in">
+            <tp:docstring>Sets the default device id</tp:docstring>
+            <arg type="s" name="deviceId" direction="in">
             </arg>
         </method>
 
@@ -132,8 +134,8 @@
         </method>
 
         <method name="setDeviceOrientation" tp:name-for-bindings="setDeviceOrientation">
-            <arg type="s" name="name" direction="in">
-                <tp:docstring>Device name</tp:docstring>
+            <arg type="s" name="deviceId" direction="in">
+                <tp:docstring>Device id</tp:docstring>
             </arg>
             <arg type="i" name="angle" direction="in">
                 <tp:docstring>Angle of device in degrees (counterclockwise)</tp:docstring>
diff --git a/bin/dbus/dbusvideomanager.cpp b/bin/dbus/dbusvideomanager.cpp
index febe4a0083..cb3cbbe5ef 100644
--- a/bin/dbus/dbusvideomanager.cpp
+++ b/bin/dbus/dbusvideomanager.cpp
@@ -32,27 +32,27 @@ DBusVideoManager::getDeviceList() -> decltype(DRing::getDeviceList())
 }
 
 auto
-DBusVideoManager::getCapabilities(const std::string& name) -> decltype(DRing::getCapabilities(name))
+DBusVideoManager::getCapabilities(const std::string& deviceId) -> decltype(DRing::getCapabilities(deviceId))
 {
-    return DRing::getCapabilities(name);
+    return DRing::getCapabilities(deviceId);
 }
 
 auto
-DBusVideoManager::getSettings(const std::string& name) -> decltype(DRing::getSettings(name))
+DBusVideoManager::getSettings(const std::string& deviceId) -> decltype(DRing::getSettings(deviceId))
 {
-    return DRing::getSettings(name);
+    return DRing::getSettings(deviceId);
 }
 
 void
-DBusVideoManager::applySettings(const std::string& name, const std::map<std::string, std::string>& settings)
+DBusVideoManager::applySettings(const std::string& deviceId, const std::map<std::string, std::string>& settings)
 {
-    DRing::applySettings(name, settings);
+    DRing::applySettings(deviceId, settings);
 }
 
 void
-DBusVideoManager::setDefaultDevice(const std::string& dev)
+DBusVideoManager::setDefaultDevice(const std::string& deviceId)
 {
-    DRing::setDefaultDevice(dev);
+    DRing::setDefaultDevice(deviceId);
 }
 
 auto
@@ -122,9 +122,9 @@ DBusVideoManager::setEncodingAccelerated(const bool& state)
 }
 
 void
-DBusVideoManager::setDeviceOrientation(const std::string& name, const int& angle)
+DBusVideoManager::setDeviceOrientation(const std::string& deviceId, const int& angle)
 {
-    DRing::setDeviceOrientation(name, angle);
+    DRing::setDeviceOrientation(deviceId, angle);
 }
 
 std::map<std::string, std::string>
diff --git a/bin/dbus/dbusvideomanager.h b/bin/dbus/dbusvideomanager.h
index 1cd3b7088f..4ed8d8d1ca 100644
--- a/bin/dbus/dbusvideomanager.h
+++ b/bin/dbus/dbusvideomanager.h
@@ -52,10 +52,10 @@ class DRING_PUBLIC DBusVideoManager :
 
         // Methods
         std::vector<std::string> getDeviceList();
-        std::map<std::string, std::map<std::string, std::vector<std::string>>> getCapabilities(const std::string& name);
-        std::map<std::string, std::string> getSettings(const std::string& name);
-        void applySettings(const std::string& name, const std::map<std::string, std::string>& settings);
-        void setDefaultDevice(const std::string& dev);
+        std::map<std::string, std::map<std::string, std::vector<std::string>>> getCapabilities(const std::string& deviceId);
+        std::map<std::string, std::string> getSettings(const std::string& deviceId);
+        void applySettings(const std::string& deviceId, const std::map<std::string, std::string>& settings);
+        void setDefaultDevice(const std::string& deviceId);
         std::string getDefaultDevice();
         void startCamera();
         void stopCamera();
@@ -67,7 +67,7 @@ class DRING_PUBLIC DBusVideoManager :
         void setDecodingAccelerated(const bool& state);
         bool getEncodingAccelerated();
         void setEncodingAccelerated(const bool& state);
-        void setDeviceOrientation(const std::string& name, const int& angle);
+        void setDeviceOrientation(const std::string& deviceId, const int& angle);
         std::map<std::string, std::string> getRenderer(const std::string& callId);
         std::string startLocalRecorder(const bool& audioOnly, const std::string& filepath);
         void stopLocalRecorder(const std::string& filepath);
diff --git a/src/client/videomanager.cpp b/src/client/videomanager.cpp
index c2c993e501..696c4048ce 100644
--- a/src/client/videomanager.cpp
+++ b/src/client/videomanager.cpp
@@ -329,9 +329,9 @@ getDeviceList()
 }
 
 VideoCapabilities
-getCapabilities(const std::string& name)
+getCapabilities(const std::string& deviceId)
 {
-    return jami::Manager::instance().getVideoManager().videoDeviceMonitor.getCapabilities(name);
+    return jami::Manager::instance().getVideoManager().videoDeviceMonitor.getCapabilities(deviceId);
 }
 
 std::string
@@ -341,23 +341,23 @@ getDefaultDevice()
 }
 
 void
-setDefaultDevice(const std::string& name)
+setDefaultDevice(const std::string& deviceId)
 {
-    JAMI_DBG("Setting default device to %s", name.c_str());
-    jami::Manager::instance().getVideoManager().videoDeviceMonitor.setDefaultDevice(name);
+    JAMI_DBG("Setting default device to %s", deviceId.c_str());
+    jami::Manager::instance().getVideoManager().videoDeviceMonitor.setDefaultDevice(deviceId);
     jami::Manager::instance().saveConfig();
 }
 
 void
-setDeviceOrientation(const std::string& name, int angle)
+setDeviceOrientation(const std::string& deviceId, int angle)
 {
-    jami::Manager::instance().getVideoManager().setDeviceOrientation(name, angle);
+    jami::Manager::instance().getVideoManager().setDeviceOrientation(deviceId, angle);
 }
 
 std::map<std::string, std::string>
-getDeviceParams(const std::string& name)
+getDeviceParams(const std::string& deviceId)
 {
-    auto params = jami::Manager::instance().getVideoManager().videoDeviceMonitor.getDeviceParams(name);
+    auto params = jami::Manager::instance().getVideoManager().videoDeviceMonitor.getDeviceParams(deviceId);
     std::stringstream width, height, rate;
     width << params.width;
     height << params.height;
@@ -371,16 +371,16 @@ getDeviceParams(const std::string& name)
 }
 
 std::map<std::string, std::string>
-getSettings(const std::string& name)
+getSettings(const std::string& deviceId)
 {
-    return jami::Manager::instance().getVideoManager().videoDeviceMonitor.getSettings(name).to_map();
+    return jami::Manager::instance().getVideoManager().videoDeviceMonitor.getSettings(deviceId).to_map();
 }
 
 void
-applySettings(const std::string& name,
+applySettings(const std::string& deviceId,
               const std::map<std::string, std::string>& settings)
 {
-    jami::Manager::instance().getVideoManager().videoDeviceMonitor.applySettings(name, settings);
+    jami::Manager::instance().getVideoManager().videoDeviceMonitor.applySettings(deviceId, settings);
     jami::Manager::instance().saveConfig();
 }
 
@@ -650,9 +650,9 @@ getAudioInput(const std::string& id)
 }
 
 void
-VideoManager::setDeviceOrientation(const std::string& name, int angle)
+VideoManager::setDeviceOrientation(const std::string& deviceId, int angle)
 {
-    videoDeviceMonitor.setDeviceOrientation(name, angle);
+    videoDeviceMonitor.setDeviceOrientation(deviceId, angle);
 }
 
 } // namespace jami
diff --git a/src/client/videomanager.h b/src/client/videomanager.h
index 520fef040b..c12c686498 100644
--- a/src/client/videomanager.h
+++ b/src/client/videomanager.h
@@ -40,7 +40,7 @@ struct VideoManager
 {
 public:
 
-    void setDeviceOrientation(const std::string& name, int angle);
+    void setDeviceOrientation(const std::string& deviceId, int angle);
 
     /**
      * VideoManager acts as a cache of the active VideoInput.
diff --git a/src/dring/videomanager_interface.h b/src/dring/videomanager_interface.h
index a0b73478b1..c041c7cefb 100644
--- a/src/dring/videomanager_interface.h
+++ b/src/dring/videomanager_interface.h
@@ -163,14 +163,12 @@ struct DRING_PUBLIC AVSinkTarget {
 using VideoCapabilities = std::map<std::string, std::map<std::string, std::vector<std::string>>>;
 
 DRING_PUBLIC std::vector<std::string> getDeviceList();
-DRING_PUBLIC VideoCapabilities getCapabilities(const std::string& name);
-DRING_PUBLIC std::map<std::string, std::string> getSettings(const std::string& name);
-DRING_PUBLIC void applySettings(const std::string& name, const std::map<std::string, std::string>& settings);
-DRING_PUBLIC void setDefaultDevice(const std::string& name);
-DRING_PUBLIC void setDeviceOrientation(const std::string& name, int angle);
-
-DRING_PUBLIC std::map<std::string, std::string> getDeviceParams(const std::string& name);
-
+DRING_PUBLIC VideoCapabilities getCapabilities(const std::string& deviceId);
+DRING_PUBLIC std::map<std::string, std::string> getSettings(const std::string& deviceId);
+DRING_PUBLIC void applySettings(const std::string& deviceId, const std::map<std::string, std::string>& settings);
+DRING_PUBLIC void setDefaultDevice(const std::string& deviceId);
+DRING_PUBLIC void setDeviceOrientation(const std::string& deviceId, int angle);
+DRING_PUBLIC std::map<std::string, std::string> getDeviceParams(const std::string& deviceId);
 DRING_PUBLIC std::string getDefaultDevice();
 DRING_PUBLIC std::string getCurrentCodecName(const std::string& callID);
 DRING_PUBLIC void startCamera();
diff --git a/src/media/video/androidvideo/video_device_impl.cpp b/src/media/video/androidvideo/video_device_impl.cpp
index 89f9515ea6..e47aa005ba 100644
--- a/src/media/video/androidvideo/video_device_impl.cpp
+++ b/src/media/video/androidvideo/video_device_impl.cpp
@@ -189,6 +189,7 @@ VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
 VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&) :
     deviceImpl_(new VideoDeviceImpl(path))
 {
+    id_ = path;
     name = deviceImpl_->name;
 }
 
diff --git a/src/media/video/iosvideo/video_device_impl.cpp b/src/media/video/iosvideo/video_device_impl.cpp
index 2273be507a..be1acbf16a 100644
--- a/src/media/video/iosvideo/video_device_impl.cpp
+++ b/src/media/video/iosvideo/video_device_impl.cpp
@@ -179,7 +179,7 @@ VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
 VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>& devInfo)
 : deviceImpl_(new VideoDeviceImpl(path, devInfo))
 {
-    node_ = path;
+    id_ = path;
     name = deviceImpl_->name;
 }
 
diff --git a/src/media/video/osxvideo/video_device_impl.mm b/src/media/video/osxvideo/video_device_impl.mm
index 940deb05e8..45a3cbff54 100644
--- a/src/media/video/osxvideo/video_device_impl.mm
+++ b/src/media/video/osxvideo/video_device_impl.mm
@@ -42,7 +42,7 @@ class VideoDeviceImpl {
          */
         VideoDeviceImpl(const std::string& path);
 
-        std::string device;
+        std::string id;
         std::string name;
 
         std::vector<std::string> getChannelList() const;
@@ -64,7 +64,7 @@ class VideoDeviceImpl {
 };
 
 VideoDeviceImpl::VideoDeviceImpl(const std::string& uniqueID)
-    : device(uniqueID)
+    : id(uniqueID)
     , current_size_(-1, -1)
     , avDevice_([AVCaptureDevice deviceWithUniqueID:
         [NSString stringWithCString:uniqueID.c_str() encoding:[NSString defaultCStringEncoding]]])
@@ -112,7 +112,7 @@ VideoDeviceImpl::getDeviceParams() const
 {
     DeviceParams params;
     params.name = [[avDevice_ localizedName] UTF8String];
-    params.input = params.name;
+    params.input = [[avDevice_ localizedName] UTF8String];
     params.framerate = rate_;
     params.format = "avfoundation";
     params.pixel_format = "nv12";
@@ -155,7 +155,7 @@ VideoDeviceImpl::getChannelList() const
 VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&) :
     deviceImpl_(new VideoDeviceImpl(path))
 {
-    node_ = path;
+    id_ = path;
     name = deviceImpl_->name;
 }
 
diff --git a/src/media/video/v4l2/video_device_impl.cpp b/src/media/video/v4l2/video_device_impl.cpp
index 0709087a18..8542e45f66 100644
--- a/src/media/video/v4l2/video_device_impl.cpp
+++ b/src/media/video/v4l2/video_device_impl.cpp
@@ -125,7 +125,7 @@ public:
      */
     VideoDeviceImpl(const std::string& path);
 
-    std::string device;
+    std::string id;
     std::string name;
 
     std::vector<std::string> getChannelList() const;
@@ -431,14 +431,14 @@ VideoV4l2Channel::getSize(VideoSize s) const
 }
 
 VideoDeviceImpl::VideoDeviceImpl(const string& path)
-    : device(path)
+    : id(path)
     , name()
     , channels_()
     , channel_(-1, "")
     , size_(-1, -1)
     , rate_(-1, 1, 0)
 {
-    int fd = open(device.c_str(), O_RDWR);
+    int fd = open(id.c_str(), O_RDWR);
     if (fd == -1)
         throw std::runtime_error("could not open device");
 
@@ -544,7 +544,7 @@ VideoDeviceImpl::getDeviceParams() const
 {
     DeviceParams params;
     params.name = name;
-    params.input = device;
+    params.input = id;
     params.format = "video4linux2";
     params.channel_name = channel_.name;
     params.channel = channel_.idx;
@@ -571,7 +571,7 @@ VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
 VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&)
     : deviceImpl_(new VideoDeviceImpl(path))
 {
-    node_ = path;
+    id_ = path;
     name = deviceImpl_->name;
 }
 
diff --git a/src/media/video/video_base.cpp b/src/media/video/video_base.cpp
index 9404aa7450..8389d0905f 100644
--- a/src/media/video/video_base.cpp
+++ b/src/media/video/video_base.cpp
@@ -83,6 +83,7 @@ extractString(const std::map<std::string, std::string>& settings, const std::str
 VideoSettings::VideoSettings(const std::map<std::string, std::string>& settings)
 {
     name = extractString(settings, "name");
+    id = extractString(settings, "id");
     channel = extractString(settings, "channel");
     video_size = extractString(settings, "size");
     framerate = extractString(settings, "rate");
@@ -93,6 +94,7 @@ VideoSettings::to_map() const
 {
     return {
         {"name", name},
+        {"id", id},
         {"size", video_size},
         {"channel", channel},
         {"rate", framerate}
@@ -107,6 +109,7 @@ Node
 convert<jami::video::VideoSettings>::encode(const jami::video::VideoSettings& rhs) {
     Node node;
     node["name"] = rhs.name;
+    node["id"] = rhs.id;
     node["video_size"] = rhs.video_size;
     node["channel"] = rhs.channel;
     node["framerate"] = rhs.framerate;
@@ -120,6 +123,7 @@ convert<jami::video::VideoSettings>::decode(const Node& node, jami::video::Video
         return false;
     }
     rhs.name = node["name"].as<std::string>();
+    rhs.id = node["id"].as<std::string>();
     rhs.video_size = node["video_size"].as<std::string>();
     rhs.channel = node["channel"].as<std::string>();
     rhs.framerate = node["framerate"].as<std::string>();
diff --git a/src/media/video/video_base.h b/src/media/video/video_base.h
index d4e2e19e71..be09e4d9a4 100644
--- a/src/media/video/video_base.h
+++ b/src/media/video/video_base.h
@@ -96,6 +96,7 @@ struct VideoSettings
 
     std::map<std::string, std::string> to_map() const;
 
+    std::string id {};
     std::string name {};
     std::string channel {};
     std::string video_size {};
diff --git a/src/media/video/video_device.h b/src/media/video/video_device.h
index 16ea85fef8..6a88569231 100644
--- a/src/media/video/video_device.h
+++ b/src/media/video/video_device.h
@@ -56,7 +56,7 @@ public:
      */
     std::string name {};
 
-    const std::string& getNode() const { return node_; }
+    const std::string& getDeviceId() const { return id_; }
 
     /*
      * Get the 3 level deep tree of possible settings for the device.
@@ -138,7 +138,8 @@ public:
     VideoSettings getSettings() const {
         auto params = getDeviceParams();
         VideoSettings settings;
-        settings.name = params.name;
+        settings.name = name.empty() ? params.name : name;
+        settings.id = params.input;
         settings.channel = params.channel_name;
         settings.video_size = sizeToString(params.width, params.height);
         settings.framerate = jami::to_string(params.framerate.real());
@@ -155,6 +156,7 @@ public:
     void applySettings(VideoSettings settings) {
         DeviceParams params {};
         params.name = settings.name;
+        params.input = settings.id;
         params.channel_name = settings.channel;
         auto size = sizeFromString(settings.channel, settings.video_size);
         params.width = size.first;
@@ -222,7 +224,7 @@ private:
     /*
      * The device node, e.g. "/dev/video0".
      */
-    std::string node_ {};
+    std::string id_ {};
 
     int orientation_ {0};
 
diff --git a/src/media/video/video_device_monitor.cpp b/src/media/video/video_device_monitor.cpp
index 6bffe160ba..9500c16d5d 100644
--- a/src/media/video/video_device_monitor.cpp
+++ b/src/media/video/video_device_monitor.cpp
@@ -3,6 +3,7 @@
  *
  *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
  *  Author: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ *  Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -49,18 +50,18 @@ vector<string>
 VideoDeviceMonitor::getDeviceList() const
 {
     std::lock_guard<std::mutex> l(lock_);
-    vector<string> names;
-    names.reserve(devices_.size());
+    vector<string> ids;
+    ids.reserve(devices_.size());
     for (const auto& dev : devices_)
-       names.emplace_back(dev.name);
-    return names;
+        ids.emplace_back(dev.getDeviceId());
+    return ids;
 }
 
 DRing::VideoCapabilities
-VideoDeviceMonitor::getCapabilities(const string& name) const
+VideoDeviceMonitor::getCapabilities(const string& id) const
 {
     std::lock_guard<std::mutex> l(lock_);
-    const auto iter = findDeviceByName(name);
+    const auto iter = findDeviceById(id);
     if (iter == devices_.end())
         return DRing::VideoCapabilities();
 
@@ -68,28 +69,28 @@ VideoDeviceMonitor::getCapabilities(const string& name) const
 }
 
 VideoSettings
-VideoDeviceMonitor::getSettings(const string& name)
+VideoDeviceMonitor::getSettings(const string& id)
 {
     std::lock_guard<std::mutex> l(lock_);
-    const auto itd = findPreferencesByName(name);
 
-    if (itd == preferences_.end())
+    const auto prefIter = findPreferencesById(id);
+    if (prefIter == preferences_.end())
         return VideoSettings();
 
-    return *itd;
+    return *prefIter;
 }
 
 void
-VideoDeviceMonitor::applySettings(const string& name, const VideoSettings& settings)
+VideoDeviceMonitor::applySettings(const string& id, const VideoSettings& settings)
 {
     std::lock_guard<std::mutex> l(lock_);
-    const auto iter = findDeviceByName(name);
+    const auto iter = findDeviceById(id);
 
     if (iter == devices_.end())
         return;
 
     iter->applySettings(settings);
-    auto it = findPreferencesByName(settings.name);
+    auto it = findPreferencesById(settings.id);
     if (it != preferences_.end())
         (*it) = settings;
 }
@@ -98,30 +99,33 @@ string
 VideoDeviceMonitor::getDefaultDevice() const
 {
     std::lock_guard<std::mutex> l(lock_);
-    return defaultDevice_;
+    const auto it = findDeviceById(defaultDevice_);
+    if (it == std::end(devices_))
+        return {};
+    return it->getDeviceId();
 }
 
 std::string
 VideoDeviceMonitor::getMRLForDefaultDevice() const
 {
     std::lock_guard<std::mutex> l(lock_);
-    const auto it = findDeviceByName(defaultDevice_);
+    const auto it = findDeviceById(defaultDevice_);
     if(it == std::end(devices_))
         return {};
     static const std::string sep = DRing::Media::VideoProtocolPrefix::SEPARATOR;
-    return DRing::Media::VideoProtocolPrefix::CAMERA + sep + it->getSettings().name;
+    return DRing::Media::VideoProtocolPrefix::CAMERA + sep + it->getDeviceId();
 }
 
 void
-VideoDeviceMonitor::setDefaultDevice(const std::string& name)
+VideoDeviceMonitor::setDefaultDevice(const std::string& id)
 {
     std::lock_guard<std::mutex> l(lock_);
-    const auto itDev = findDeviceByName(name);
+    const auto itDev = findDeviceById(id);
     if (itDev != devices_.end()) {
-        defaultDevice_ = itDev->name;
+        defaultDevice_ = itDev->getDeviceId();
 
         // place it at the begining of the prefs
-        auto itPref = findPreferencesByName(name);
+        auto itPref = findPreferencesById(itDev->getDeviceId());
         if (itPref != preferences_.end()) {
             auto settings = *itPref;
             preferences_.erase(itPref);
@@ -133,64 +137,38 @@ VideoDeviceMonitor::setDefaultDevice(const std::string& name)
 }
 
 void
-VideoDeviceMonitor::setDeviceOrientation(const std::string& name, int angle)
+VideoDeviceMonitor::setDeviceOrientation(const std::string& id, int angle)
 {
-    const auto itd = findDeviceByName(name);
+    const auto itd = findDeviceById(id);
     if (itd != devices_.cend()) {
         itd->setOrientation(angle);
     } else {
-        JAMI_WARN("Can't find device %s to set orientation %d", name.c_str(), angle);
+        JAMI_WARN("Can't find device %s to set orientation %d", id.c_str(), angle);
     }
 }
 
 DeviceParams
-VideoDeviceMonitor::getDeviceParams(const std::string& name) const
+VideoDeviceMonitor::getDeviceParams(const std::string& id) const
 {
     std::lock_guard<std::mutex> l(lock_);
-    const auto itd = findDeviceByName(name);
+    const auto itd = findDeviceById(id);
     if (itd == devices_.cend())
         return DeviceParams();
     return itd->getDeviceParams();
 }
 
-static int
-getNumber(const string &name, size_t *sharp)
-{
-    size_t len = name.length();
-    // name is too short to be numbered
-    if (len < 3)
-        return -1;
-
-    for (size_t c = len; c; --c) {
-        if (name[c] == '#') {
-            unsigned i;
-            if (sscanf(name.substr(c).c_str(), "#%u", &i) != 1)
-                return -1;
-            *sharp = c;
-            return i;
-        }
-    }
-
-    return -1;
-}
-
 static void
 giveUniqueName(VideoDevice &dev, const vector<VideoDevice> &devices)
 {
-start:
-    for (auto &item : devices) {
-        if (dev.name == item.name) {
-            size_t sharp;
-            int num = getNumber(dev.name, &sharp);
-            if (num < 0) // not numbered
-                dev.name += " #0";
-            else {
-                stringstream ss;
-                ss  << num + 1;
-                dev.name.replace(sharp + 1, ss.str().length(), ss.str());
-            }
-            goto start; // we changed the name, let's look again if it is unique
-        }
+    std::string suffix;
+    uint64_t number = 2;
+    auto unique = true;
+    for (;; unique = static_cast<bool>(++number)) {
+        for (const auto& s : devices)
+            unique &= static_cast<bool>(s.name.compare(dev.name + suffix));
+        if (unique)
+            return (void)(dev.name += suffix);
+        suffix = " (" + std::to_string(number) + ")";
     }
 }
 
@@ -203,15 +181,15 @@ notify()
 }
 
 void
-VideoDeviceMonitor::addDevice(const string& node, const std::vector<std::map<std::string, std::string>>* devInfo)
+VideoDeviceMonitor::addDevice(const string& id, const std::vector<std::map<std::string, std::string>>* devInfo)
 {
     try {
         std::lock_guard<std::mutex> l(lock_);
-        if (findDeviceByNode(node) != devices_.end())
+        if (findDeviceById(id) != devices_.end())
             return;
 
         // instantiate a new unique device
-        VideoDevice dev {node, *devInfo};
+        VideoDevice dev { id, *devInfo};
 
         if (dev.getChannelList().empty())
             return;
@@ -219,43 +197,42 @@ VideoDeviceMonitor::addDevice(const string& node, const std::vector<std::map<std
         giveUniqueName(dev, devices_);
 
         // restore its preferences if any, or store the defaults
-        auto it = findPreferencesByName(dev.name);
-        if (it != preferences_.end())
+        auto it = findPreferencesById(id);
+        if (it != preferences_.end()) {
             dev.applySettings(*it);
-        else {
+        } else {
             dev.applySettings(dev.getDefaultSettings());
             preferences_.emplace_back(dev.getSettings());
         }
 
         // in case there is no default device on a fresh run
         if (defaultDevice_.empty())
-            defaultDevice_ = dev.name;
+            defaultDevice_ = dev.getDeviceId();
 
         devices_.emplace_back(std::move(dev));
     } catch (const std::exception& e) {
-        JAMI_ERR("Failed to add device %s: %s", node.c_str(), e.what());
+        JAMI_ERR("Failed to add device %s: %s", id.c_str(), e.what());
         return;
     }
     notify();
 }
 
 void
-VideoDeviceMonitor::removeDevice(const string& node)
+VideoDeviceMonitor::removeDevice(const string& id)
 {
     {
         std::lock_guard<std::mutex> l(lock_);
-        const auto it = findDeviceByNode(node);
+        const auto it = findDeviceById(id);
         if (it == devices_.end())
             return;
 
-        auto removedDeviceName = it->name;
         devices_.erase(it);
 
-        if (defaultDevice_ == removedDeviceName) {
+        if (defaultDevice_.find(id) != std::string::npos) {
             if (devices_.size() == 0) {
                 defaultDevice_.clear();
             } else {
-                defaultDevice_ = devices_[0].name;
+                defaultDevice_ = devices_[0].getDeviceId();
             }
         }
     }
@@ -263,53 +240,36 @@ VideoDeviceMonitor::removeDevice(const string& node)
 }
 
 vector<VideoDevice>::iterator
-VideoDeviceMonitor::findDeviceByName(const string& name)
+VideoDeviceMonitor::findDeviceById(const string& id)
 {
     for (auto it = devices_.begin(); it != devices_.end(); ++it)
-        if (it->name == name)
+        if (it->getDeviceId().find(id) != std::string::npos)
             return it;
     return devices_.end();
 }
 
 vector<VideoDevice>::const_iterator
-VideoDeviceMonitor::findDeviceByName(const string& name) const
+VideoDeviceMonitor::findDeviceById(const string& id) const
 {
     for (auto it = devices_.cbegin(); it != devices_.cend(); ++it)
-        if (it->name == name)
-            return it;
-    return devices_.cend();
-}
-
-vector<VideoDevice>::iterator
-VideoDeviceMonitor::findDeviceByNode(const string& node)
-{
-    for (auto it = devices_.begin(); it != devices_.end(); ++it)
-        if (it->getNode().find(node) != std::string::npos)
-            return it;
-    return devices_.end();
-}
-
-vector<VideoDevice>::const_iterator
-VideoDeviceMonitor::findDeviceByNode(const string& node) const
-{
-    for (auto it = devices_.cbegin(); it != devices_.cend(); ++it)
-        if (it->getNode().find(node) != std::string::npos)
+        if (it->getDeviceId().find(id) != std::string::npos)
             return it;
     return devices_.end();
 }
 
 vector<VideoSettings>::iterator
-VideoDeviceMonitor::findPreferencesByName(const string& name)
+VideoDeviceMonitor::findPreferencesById(const string& id)
 {
     for (auto it = preferences_.begin(); it != preferences_.end(); ++it)
-        if (it->name == name) return it;
+        if (it->id.find(id) != std::string::npos)
+            return it;
     return preferences_.end();
 }
 
 void
 VideoDeviceMonitor::overwritePreferences(const VideoSettings& settings)
 {
-    auto it = findPreferencesByName(settings.name);
+    auto it = findPreferencesById(settings.id);
     if (it != preferences_.end())
         preferences_.erase(it);
     preferences_.emplace_back(settings);
@@ -332,21 +292,23 @@ VideoDeviceMonitor::unserialize(const YAML::Node &in)
     const auto& devices = node["devices"];
     for (const auto& dev : devices) {
         VideoSettings pref = dev.as<VideoSettings>();
-        if (pref.name.empty())
+        if (pref.id.empty())
             continue; // discard malformed section
         overwritePreferences(pref);
-        auto itd = findDeviceByName(pref.name);
+        auto itd = findDeviceById(pref.id);
         if (itd != devices_.end())
             itd->applySettings(pref);
     }
 
     // Restore the default device if present, or select the first one
-    const string pref = preferences_.empty() ? "" : preferences_[0].name;
-    const string first = devices_.empty() ? "" : devices_[0].name;
-    if (findDeviceByName(pref) != devices_.end())
-        defaultDevice_ = pref;
-    else
-        defaultDevice_ = first;
+    const string prefId = preferences_.empty() ? "" : preferences_[0].id;
+    const string firstId = devices_.empty() ? "" : devices_[0].getDeviceId();
+    const auto devIter = findDeviceById(prefId);
+    if (devIter != devices_.end()) {
+        defaultDevice_ = devIter->getDeviceId();
+    } else {
+        defaultDevice_ = firstId;
+    }
 }
-#pragma optimize("", on)
+
 }} // namespace jami::video
diff --git a/src/media/video/video_device_monitor.h b/src/media/video/video_device_monitor.h
index ff2f1de1e1..40624b2e73 100644
--- a/src/media/video/video_device_monitor.h
+++ b/src/media/video/video_device_monitor.h
@@ -56,7 +56,7 @@ class VideoDeviceMonitor : public Serializable
         std::string getDefaultDevice() const;
         std::string getMRLForDefaultDevice() const;
         void setDefaultDevice(const std::string& name);
-        void setDeviceOrientation(const std::string& name, int angle);
+        void setDeviceOrientation(const std::string& id, int angle);
 
         void addDevice(const std::string &node, const std::vector<std::map<std::string, std::string>>* devInfo=nullptr);
         void removeDevice(const std::string &node);
@@ -83,7 +83,7 @@ class VideoDeviceMonitor : public Serializable
         std::vector<VideoSettings> preferences_;
 
         void overwritePreferences(const VideoSettings& settings);
-        std::vector<VideoSettings>::iterator findPreferencesByName(const std::string& name);
+        std::vector<VideoSettings>::iterator findPreferencesById(const std::string& id);
 
         /*
          * Vector containing the video devices.
@@ -91,10 +91,8 @@ class VideoDeviceMonitor : public Serializable
         std::vector<VideoDevice> devices_;
         std::string defaultDevice_ = "";
 
-        std::vector<VideoDevice>::iterator findDeviceByName(const std::string& name);
-        std::vector<VideoDevice>::const_iterator findDeviceByName(const std::string& name) const;
-        std::vector<VideoDevice>::iterator findDeviceByNode(const std::string& node);
-        std::vector<VideoDevice>::const_iterator findDeviceByNode(const std::string& node) const;
+        std::vector<VideoDevice>::iterator findDeviceById(const std::string& id);
+        std::vector<VideoDevice>::const_iterator findDeviceById(const std::string& id) const;
 
         std::unique_ptr<VideoDeviceMonitorImpl> monitorImpl_;
 
diff --git a/src/media/video/winvideo/video_device_impl.cpp b/src/media/video/winvideo/video_device_impl.cpp
index 44155cb268..72ec9f56a2 100644
--- a/src/media/video/winvideo/video_device_impl.cpp
+++ b/src/media/video/winvideo/video_device_impl.cpp
@@ -43,8 +43,8 @@ class VideoDeviceImpl {
         /**
         * @throw std::runtime_error
         */
-        VideoDeviceImpl(const std::string& path);
-        std::string device;
+        VideoDeviceImpl(const std::string& id);
+        std::string id;
         std::string name;
 
         std::vector<std::string> getChannelList() const;
@@ -66,8 +66,8 @@ class VideoDeviceImpl {
         void fail(const std::string& error);
 };
 
-VideoDeviceImpl::VideoDeviceImpl(const std::string& path)
-    : device(path)
+VideoDeviceImpl::VideoDeviceImpl(const std::string& id)
+    : id(id)
     , name()
     , cInterface(new CaptureGraphInterfaces())
 {
@@ -148,11 +148,11 @@ VideoDeviceImpl::setup()
 
         // We want to get the capabilities of a device with the unique_name
         // that corresponds to what was enumerated by the video device monitor.
-        if (unique_name.find(this->device) == std::string::npos) {
+        if (unique_name.find(this->id) == std::string::npos) {
             continue;
         }
 
-        this->device = unique_name;
+        this->id = unique_name;
 
         // get friendly name
         VARIANT var;
@@ -257,7 +257,7 @@ VideoDeviceImpl::getDeviceParams() const
     DeviceParams params;
 
     params.name = name;
-    params.input = device;
+    params.input = id;
     params.format = "dshow";
 
     AM_MEDIA_TYPE *pmt;
@@ -316,7 +316,7 @@ VideoDeviceImpl::getChannelList() const
 VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&)
     : deviceImpl_(new VideoDeviceImpl(path))
 {
-    node_ = path;
+    id_ = path;
     name = deviceImpl_->name;
 }
 
diff --git a/src/media/video/winvideo/video_device_monitor_impl.cpp b/src/media/video/winvideo/video_device_monitor_impl.cpp
index 2230d942b8..1ae45caa99 100644
--- a/src/media/video/winvideo/video_device_monitor_impl.cpp
+++ b/src/media/video/winvideo/video_device_monitor_impl.cpp
@@ -166,9 +166,9 @@ VideoDeviceMonitorImpl::WinProcCallback(HWND hWnd, UINT message, WPARAM wParam,
                 if (pThis = reinterpret_cast<VideoDeviceMonitorImpl*>(GetWindowLongPtr(hWnd, GWLP_USERDATA))) {
                     if (wParam == DBT_DEVICEARRIVAL) {
                         auto captureDeviceList = pThis->enumerateVideoInputDevices();
-                        for (auto node : captureDeviceList) {
-                            if (node.find(unique_name) != std::string::npos)
-                                pThis->monitor_->addDevice(node);
+                        for (auto id : captureDeviceList) {
+                            if (id.find(unique_name) != std::string::npos)
+                                pThis->monitor_->addDevice(id);
                         }
                     } else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
                         pThis->monitor_->removeDevice(unique_name);
-- 
GitLab