From a1b8b13a6f6ad4c7fb6df8d1c7219509c7dc1036 Mon Sep 17 00:00:00 2001
From: atraczyk <andreastraczyk@gmail.com>
Date: Wed, 28 Dec 2016 11:51:56 -0500
Subject: [PATCH] video: add video device implementation for UWP

- adds a video device implementation and a barebones video device
  montior implementation for UWP.

Change-Id: I69108c688f0e55fea1776708919b881afae42552
Tuleap: #790
---
 src/client/ring_signal.cpp                    |   4 +-
 src/client/videomanager.cpp                   |  22 +-
 src/dring/videomanager_interface.h            |  29 ++-
 .../video/androidvideo/video_device_impl.cpp  |   2 +-
 src/media/video/osxvideo/video_device_impl.mm |   2 +-
 .../video/uwpvideo/video_device_impl.cpp      | 219 ++++++++++++++++++
 .../uwpvideo/video_device_monitor_impl.cpp    |  95 ++++++++
 src/media/video/v4l2/video_device_impl.cpp    |   2 +-
 src/media/video/video_device.h                |   3 +-
 src/media/video/video_device_monitor.cpp      |   6 +-
 src/media/video/video_device_monitor.h        |   2 +-
 src/media/video/video_input.cpp               |  53 ++---
 src/media/video/video_input.h                 |  10 +-
 .../video/winvideo/video_device_impl.cpp      |   2 +-
 14 files changed, 398 insertions(+), 53 deletions(-)
 create mode 100644 src/media/video/uwpvideo/video_device_impl.cpp
 create mode 100644 src/media/video/uwpvideo/video_device_monitor_impl.cpp

diff --git a/src/client/ring_signal.cpp b/src/client/ring_signal.cpp
index 45d495645b..0ff28dbd85 100644
--- a/src/client/ring_signal.cpp
+++ b/src/client/ring_signal.cpp
@@ -93,9 +93,11 @@ getSignalHandlers()
 #ifdef __ANDROID__
         exported_callback<DRing::VideoSignal::GetCameraInfo>(),
         exported_callback<DRing::VideoSignal::SetParameters>(),
+#endif
         exported_callback<DRing::VideoSignal::StartCapture>(),
         exported_callback<DRing::VideoSignal::StopCapture>(),
-#endif
+        exported_callback<DRing::VideoSignal::DeviceAdded>(),
+        exported_callback<DRing::VideoSignal::ParametersChanged>(),
 #endif
     };
 
diff --git a/src/client/videomanager.cpp b/src/client/videomanager.cpp
index 649f9c5d24..05072f651b 100644
--- a/src/client/videomanager.cpp
+++ b/src/client/videomanager.cpp
@@ -82,6 +82,22 @@ setDefaultDevice(const std::string& name)
     ring::Manager::instance().saveConfig();
 }
 
+std::map<std::string, std::string>
+getDeviceParams(const std::string& name)
+{
+    auto params = ring::Manager::instance().getVideoManager().videoDeviceMonitor.getDeviceParams(name);
+    std::stringstream width, height, rate;
+    width << params.width;
+    height << params.height;
+    rate << params.framerate;
+    return {
+        {"format", params.format},
+        {"width", width.str()},
+        {"height", height.str()},
+        {"rate", rate.str()}
+    };
+}
+
 std::map<std::string, std::string>
 getSettings(const std::string& name)
 {
@@ -146,11 +162,11 @@ registerSinkTarget(const std::string& sinkId, const SinkTarget& target)
        RING_WARN("No sink found for id '%s'", sinkId.c_str());
 }
 
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(RING_UWP)
 void
-addVideoDevice(const std::string &node)
+addVideoDevice(const std::string &node, std::vector<std::map<std::string, std::string>> const * devInfo)
 {
-    ring::Manager::instance().getVideoManager().videoDeviceMonitor.addDevice(node);
+    ring::Manager::instance().getVideoManager().videoDeviceMonitor.addDevice(node, devInfo);
 }
 
 void
diff --git a/src/dring/videomanager_interface.h b/src/dring/videomanager_interface.h
index 44c495e2fe..e9b85583b9 100644
--- a/src/dring/videomanager_interface.h
+++ b/src/dring/videomanager_interface.h
@@ -58,6 +58,9 @@ VideoCapabilities 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& name);
+
+std::map<std::string, std::string> getDeviceParams(const std::string& name);
+
 std::string getDefaultDevice();
 std::string getCurrentCodecName(const std::string& callID);
 void startCamera();
@@ -67,8 +70,8 @@ bool switchInput(const std::string& resource);
 bool switchToCamera();
 void registerSinkTarget(const std::string& sinkId, const SinkTarget& target);
 
-#ifdef __ANDROID__
-void addVideoDevice(const std::string &node);
+#if defined(__ANDROID__) || defined(RING_UWP)
+void addVideoDevice(const std::string &node, const std::vector<std::map<std::string, std::string>>* devInfo=nullptr);
 void removeVideoDevice(const std::string &node);
 void* obtainFrame(int length);
 void releaseFrame(void* frame);
@@ -88,24 +91,32 @@ struct VideoSignal {
                 constexpr static const char* name = "DecodingStopped";
                 using cb_type = void(const std::string& /*id*/, const std::string& /*shm_path*/, bool /*is_mixer*/);
         };
-#ifdef __ANDROID__
-        struct GetCameraInfo {
-            constexpr static const char* name = "GetCameraInfo";
-            using cb_type = void(const std::string& device, std::vector<int> *formats, std::vector<unsigned> *sizes, std::vector<unsigned> *rates);
-        };
+#if __ANDROID__
         struct SetParameters {
             constexpr static const char* name = "SetParameters";
             using cb_type = void(const std::string& device, const int format, const int width, const int height, const int rate);
         };
+        struct GetCameraInfo {
+            constexpr static const char* name = "GetCameraInfo";
+            using cb_type = void(const std::string& device, std::vector<int> *formats, std::vector<unsigned> *sizes, std::vector<unsigned> *rates);
+        };
+#endif
         struct StartCapture {
             constexpr static const char* name = "StartCapture";
-            using cb_type = void(const std::string& device);
+            using cb_type = void(const std::string& /*device*/);
         };
         struct StopCapture {
             constexpr static const char* name = "StopCapture";
             using cb_type = void(void);
         };
-#endif
+        struct DeviceAdded {
+            constexpr static const char* name = "DeviceAdded";
+            using cb_type = void(const std::string& /*device*/);
+        };
+        struct ParametersChanged {
+            constexpr static const char* name = "ParametersChanged";
+            using cb_type = void(const std::string& /*device*/);
+        };
 };
 
 } // namespace DRing
diff --git a/src/media/video/androidvideo/video_device_impl.cpp b/src/media/video/androidvideo/video_device_impl.cpp
index 50bb83ebda..a758a3aa8a 100644
--- a/src/media/video/androidvideo/video_device_impl.cpp
+++ b/src/media/video/androidvideo/video_device_impl.cpp
@@ -187,7 +187,7 @@ VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
     emitSignal<DRing::VideoSignal::SetParameters>(name, fmt_->code, size_.first, size_.second, rate_.real());
 }
 
-VideoDevice::VideoDevice(const std::string& path) :
+VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&) :
     deviceImpl_(new VideoDeviceImpl(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 0bc1996772..ab29efd79c 100644
--- a/src/media/video/osxvideo/video_device_impl.mm
+++ b/src/media/video/osxvideo/video_device_impl.mm
@@ -146,7 +146,7 @@ VideoDeviceImpl::getChannelList() const
     return {"default"};
 }
 
-VideoDevice::VideoDevice(const std::string& path) :
+VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&) :
     deviceImpl_(new VideoDeviceImpl(path))
 {
     node_ = path;
diff --git a/src/media/video/uwpvideo/video_device_impl.cpp b/src/media/video/uwpvideo/video_device_impl.cpp
new file mode 100644
index 0000000000..78f524e912
--- /dev/null
+++ b/src/media/video/uwpvideo/video_device_impl.cpp
@@ -0,0 +1,219 @@
+/*
+ *  Copyright (C) 2015-2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include <array>
+
+#include "logger.h"
+#include "../video_device.h"
+
+#include "ring_signal.h"
+
+//#include <ciso646>
+
+namespace ring { namespace video {
+
+typedef struct
+{
+    std::string             name;
+    enum VideoPixelFormat   ring_format;
+} uwp_fmt;
+
+// have all formats map to bgra
+static const std::array<uwp_fmt, 4> uwp_formats
+{
+    uwp_fmt { "MJPG",   VIDEO_PIXFMT_BGRA   },
+    uwp_fmt { "RGB24",  VIDEO_PIXFMT_BGRA   },
+    uwp_fmt { "NV12",   VIDEO_PIXFMT_BGRA   },
+    uwp_fmt { "YUY2",   VIDEO_PIXFMT_BGRA   }
+};
+
+class VideoDeviceImpl
+{
+    public:
+        VideoDeviceImpl(const std::string& path, const std::vector<std::map<std::string, std::string>>& devInfo);
+
+        std::string name;
+
+        DeviceParams getDeviceParams() const;
+
+        void setDeviceParams(const DeviceParams&);
+        void selectFormat();
+
+        std::vector<VideoSize> getSizeList() const;
+        std::vector<FrameRate> getRateList() const;
+
+    private:
+
+        VideoSize getSize(VideoSize size) const;
+        FrameRate getRate(FrameRate rate) const;
+
+        std::vector<std::string> formats_ {};
+        std::vector<VideoSize> sizes_ {};
+        std::vector<FrameRate> rates_ {};
+
+        const uwp_fmt* fmt_ {nullptr};
+        VideoSize size_ {};
+        FrameRate rate_ {};
+
+};
+
+void
+VideoDeviceImpl::selectFormat()
+{
+    unsigned best = UINT_MAX;
+    for(auto fmt : formats_) {
+        auto f = uwp_formats.begin();
+        for (; f != uwp_formats.end(); ++f) {
+            if (f->name == fmt) {
+                auto pos = std::distance(uwp_formats.begin(), f);
+                if (pos < best)
+                    best = pos;
+                break;
+            }
+        }
+        if (f == uwp_formats.end())
+            RING_WARN("Video: No format matching %s", fmt.c_str());
+    }
+
+    if (best != UINT_MAX) {
+        fmt_ = &uwp_formats[best];
+        RING_DBG("Video: picked format %s", fmt_->name.c_str());
+    }
+    else {
+        fmt_ = &uwp_formats[0];
+        RING_ERR("Video: Could not find a known format to use");
+    }
+}
+
+VideoDeviceImpl::VideoDeviceImpl(const std::string& path, const std::vector<std::map<std::string, std::string>>& devInfo)
+    : name(path)
+{
+    for (auto& setting : devInfo) {
+        formats_.emplace_back(setting.at("format"));
+        sizes_.emplace_back(std::stoi(setting.at("width")), std::stoi(setting.at("height")));
+        rates_.emplace_back(std::stoi(setting.at("rate")), 1);
+    }
+    selectFormat();
+}
+
+VideoSize
+VideoDeviceImpl::getSize(VideoSize size) const
+{
+    for (const auto &iter : sizes_) {
+        if (iter == size)
+            return iter;
+    }
+
+    return sizes_.empty() ? VideoSize{0, 0} : sizes_.back();
+}
+
+FrameRate
+VideoDeviceImpl::getRate(FrameRate rate) const
+{
+    for (const auto &iter : rates_) {
+        if (iter == rate)
+            return iter;
+    }
+
+    return rates_.empty() ? FrameRate{0, 0} : rates_.back();
+}
+
+std::vector<VideoSize>
+VideoDeviceImpl::getSizeList() const
+{
+    return sizes_;
+}
+
+std::vector<FrameRate>
+VideoDeviceImpl::getRateList() const
+{
+    return rates_;
+}
+
+DeviceParams
+VideoDeviceImpl::getDeviceParams() const
+{
+    DeviceParams params;
+    std::stringstream ss1, ss2;
+
+    ss1 << fmt_->ring_format;
+    ss1 >> params.format;
+
+    params.format = fmt_->name;
+    params.name = name;
+    params.input = name;
+    params.channel =  0;
+    params.width = size_.first;
+    params.height = size_.second;
+    params.framerate = rate_;
+
+    return params;
+}
+
+void
+VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
+{
+    size_ = getSize({params.width, params.height});
+    rate_ = getRate(params.framerate);
+    emitSignal<DRing::VideoSignal::ParametersChanged>(name);
+}
+
+VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>& devInfo)
+    : deviceImpl_(new VideoDeviceImpl(path, devInfo))
+{
+    node_ = path;
+    name = deviceImpl_->name;
+}
+
+DeviceParams
+VideoDevice::getDeviceParams() const
+{
+    return deviceImpl_->getDeviceParams();
+}
+
+void
+VideoDevice::setDeviceParams(const DeviceParams& params)
+{
+    return deviceImpl_->setDeviceParams(params);
+}
+
+std::vector<std::string>
+VideoDevice::getChannelList() const
+{
+    return {"default"};
+}
+
+std::vector<VideoSize>
+VideoDevice::getSizeList(const std::string& channel) const
+{
+    return deviceImpl_->getSizeList();
+}
+
+std::vector<FrameRate>
+VideoDevice::getRateList(const std::string& channel, VideoSize size) const
+{
+    return deviceImpl_->getRateList();
+}
+
+VideoDevice::~VideoDevice()
+{}
+
+}} // namespace ring::video
diff --git a/src/media/video/uwpvideo/video_device_monitor_impl.cpp b/src/media/video/uwpvideo/video_device_monitor_impl.cpp
new file mode 100644
index 0000000000..e2974ba31c
--- /dev/null
+++ b/src/media/video/uwpvideo/video_device_monitor_impl.cpp
@@ -0,0 +1,95 @@
+/*
+ *  Copyright (C) 2015-2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
+ *  Author: Edric Milaret <edric.ladent-milaret@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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include <mutex>
+#include <thread>
+
+#include "../video_device_monitor.h"
+#include "logger.h"
+#include "noncopyable.h"
+
+namespace ring { namespace video {
+
+class VideoDeviceMonitorImpl
+{
+    public:
+        /*
+        * This is the only restriction to the pImpl design:
+        * as the Linux implementation has a thread, it needs a way to notify
+        * devices addition and deletion.
+        *
+        * This class should maybe inherit from VideoDeviceMonitor instead of
+        * being its pImpl.
+        */
+        VideoDeviceMonitorImpl(VideoDeviceMonitor* monitor);
+        ~VideoDeviceMonitorImpl();
+
+        void start();
+
+    private:
+        NON_COPYABLE(VideoDeviceMonitorImpl);
+
+        VideoDeviceMonitor* monitor_;
+
+        void run();
+
+        mutable std::mutex mutex_;
+        bool probing_;
+        std::thread thread_;
+};
+
+VideoDeviceMonitorImpl::VideoDeviceMonitorImpl(VideoDeviceMonitor* monitor)
+    : monitor_(monitor)
+    , mutex_()
+    , thread_()
+{}
+
+void
+VideoDeviceMonitorImpl::start()
+{
+    probing_ = true;
+    thread_ = std::thread(&VideoDeviceMonitorImpl::run, this);
+}
+
+VideoDeviceMonitorImpl::~VideoDeviceMonitorImpl()
+{
+    probing_ = false;
+    if (thread_.joinable())
+        thread_.join();
+}
+
+void
+VideoDeviceMonitorImpl::run()
+{
+}
+
+VideoDeviceMonitor::VideoDeviceMonitor()
+    : preferences_()
+    , devices_()
+    , monitorImpl_(new VideoDeviceMonitorImpl(this))
+{
+    monitorImpl_->start();
+}
+
+VideoDeviceMonitor::~VideoDeviceMonitor()
+{}
+
+}} // namespace ring::video
diff --git a/src/media/video/v4l2/video_device_impl.cpp b/src/media/video/v4l2/video_device_impl.cpp
index 66ffbc743b..65df9f2ced 100644
--- a/src/media/video/v4l2/video_device_impl.cpp
+++ b/src/media/video/v4l2/video_device_impl.cpp
@@ -569,7 +569,7 @@ VideoDeviceImpl::setDeviceParams(const DeviceParams& params)
     }
 }
 
-VideoDevice::VideoDevice(const string& path)
+VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&)
     : deviceImpl_(new VideoDeviceImpl(path))
 {
     node_ = path;
diff --git a/src/media/video/video_device.h b/src/media/video/video_device.h
index 14914111b7..6aa3b8c129 100644
--- a/src/media/video/video_device.h
+++ b/src/media/video/video_device.h
@@ -31,6 +31,7 @@
 #include <string>
 #include <vector>
 #include <algorithm>
+#include <sstream>
 
 #include "videomanager_interface.h"
 #include "string_utils.h"
@@ -46,7 +47,7 @@ class VideoDeviceImpl;
 class VideoDevice {
 public:
 
-    VideoDevice(const std::string& path);
+    VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>& devInfo);
     ~VideoDevice();
 
     /*
diff --git a/src/media/video/video_device_monitor.cpp b/src/media/video/video_device_monitor.cpp
index fc7781c417..3185e63761 100644
--- a/src/media/video/video_device_monitor.cpp
+++ b/src/media/video/video_device_monitor.cpp
@@ -186,14 +186,15 @@ notify()
 }
 
 void
-VideoDeviceMonitor::addDevice(const string& node)
+VideoDeviceMonitor::addDevice(const string& node, const std::vector<std::map<std::string, std::string>>* devInfo)
 {
     if (findDeviceByNode(node) != devices_.end())
         return;
 
     // instantiate a new unique device
     try {
-        VideoDevice dev {node};
+        VideoDevice dev {node, *devInfo};
+
         if (dev.getChannelList().empty())
             return;
 
@@ -214,6 +215,7 @@ VideoDeviceMonitor::addDevice(const string& node)
 
         devices_.emplace_back(std::move(dev));
         notify();
+
     } catch (const std::exception& e) {
         RING_ERR("Failed to add device %s: %s", node.c_str(), e.what());
         return;
diff --git a/src/media/video/video_device_monitor.h b/src/media/video/video_device_monitor.h
index 1f63de9a52..b41ae12a41 100644
--- a/src/media/video/video_device_monitor.h
+++ b/src/media/video/video_device_monitor.h
@@ -57,7 +57,7 @@ class VideoDeviceMonitor : public Serializable
         std::string getMRLForDefaultDevice() const;
         void setDefaultDevice(const std::string& name);
 
-        void addDevice(const std::string &node);
+        void addDevice(const std::string &node, const std::vector<std::map<std::string, std::string>>* devInfo=nullptr);
         void removeDevice(const std::string &node);
 
         /**
diff --git a/src/media/video/video_input.cpp b/src/media/video/video_input.cpp
index ef3f8fc085..0e67ce0c7a 100644
--- a/src/media/video/video_input.cpp
+++ b/src/media/video/video_input.cpp
@@ -39,7 +39,11 @@
 #include <string>
 #include <sstream>
 #include <cassert>
+#ifdef RING_UWP
+#include <io.h> // for access
+#else
 #include <unistd.h>
+#endif
 
 namespace ring { namespace video {
 
@@ -49,21 +53,17 @@ static constexpr unsigned default_grab_height = 480;
 VideoInput::VideoInput()
     : VideoGenerator::VideoGenerator()
     , sink_ {Manager::instance().createSinkClient("local")}
-#ifndef __ANDROID__
     , loop_(std::bind(&VideoInput::setup, this),
             std::bind(&VideoInput::process, this),
             std::bind(&VideoInput::cleanup, this))
-#else
-    , loop_(std::bind(&VideoInput::setup, this),
-            std::bind(&VideoInput::processAndroid, this),
-            std::bind(&VideoInput::cleanupAndroid, this))
+#if defined(__ANDROID__) || defined(RING_UWP)
     , mutex_(), frame_cv_(), buffers_(8)
 #endif
 {}
 
 VideoInput::~VideoInput()
 {
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(RING_UWP)
     /* we need to stop the loop and notify the condition variable
      * to unblock the process loop */
     loop_.stop();
@@ -72,7 +72,7 @@ VideoInput::~VideoInput()
     loop_.join();
 }
 
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(RING_UWP)
 bool VideoInput::waitForBufferFull()
 {
     for(auto& buffer : buffers_) {
@@ -84,7 +84,7 @@ bool VideoInput::waitForBufferFull()
     return !isCapturing();
 }
 
-void VideoInput::processAndroid()
+void VideoInput::process()
 {
     foundDecOpts(decOpts_);
 
@@ -132,7 +132,7 @@ void VideoInput::processAndroid()
     }
 }
 
-void VideoInput::cleanupAndroid()
+void VideoInput::cleanup()
 {
     emitSignal<DRing::VideoSignal::StopCapture>();
 
@@ -149,21 +149,7 @@ void VideoInput::cleanupAndroid()
         }
     }
 }
-#endif
-
-bool VideoInput::setup()
-{
-    if (not attach(sink_.get())) {
-        RING_ERR("attach sink failed");
-        return false;
-    }
-
-    if (!sink_->start())
-        RING_ERR("start sink failed");
-
-    RING_DBG("VideoInput ready to capture");
-    return true;
-}
+#else
 
 void
 VideoInput::process()
@@ -186,6 +172,21 @@ VideoInput::cleanup()
     RING_DBG("VideoInput closed");
 }
 
+#endif
+bool VideoInput::setup()
+{
+    if (not attach(sink_.get())) {
+        RING_ERR("attach sink failed");
+        return false;
+    }
+
+    if (!sink_->start())
+        RING_ERR("start sink failed");
+
+    RING_DBG("VideoInput ready to capture");
+    return true;
+}
+
 void VideoInput::clearOptions()
 {
     decOpts_ = {};
@@ -230,7 +231,7 @@ bool VideoInput::captureFrame()
     }
 }
 
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(RING_UWP)
 int VideoInput::allocateOneBuffer(struct VideoFrameBuffer& b, int length)
 {
     b.data = std::malloc(length);
@@ -542,7 +543,7 @@ VideoInput::switchInput(const std::string& resource)
     return futureDecOpts_;
 }
 
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(RING_UWP)
 int VideoInput::getWidth() const
 { return decOpts_.width; }
 
diff --git a/src/media/video/video_input.h b/src/media/video/video_input.h
index 0b88170e12..7ffeefbb0d 100644
--- a/src/media/video/video_input.h
+++ b/src/media/video/video_input.h
@@ -74,10 +74,10 @@ public:
     DeviceParams getParams() const;
 
     std::shared_future<DeviceParams> switchInput(const std::string& resource);
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(RING_UWP)
     /*
-     * these fonctions are used to pass buffer from/to the daemon
-     * to the Java application
+     * these functions are used to pass buffer from/to the daemon
+     * on the Android and UWP builds
      */
     void* obtainFrame(int length);
     void releaseFrame(void *frame);
@@ -120,9 +120,7 @@ private:
     bool captureFrame();
     bool isCapturing() const noexcept;
 
-#ifdef __ANDROID__
-    void processAndroid();
-    void cleanupAndroid();
+#if defined(__ANDROID__) || defined(RING_UWP)
     int allocateOneBuffer(struct VideoFrameBuffer& b, int length);
     void freeOneBuffer(struct VideoFrameBuffer& b);
     bool waitForBufferFull();
diff --git a/src/media/video/winvideo/video_device_impl.cpp b/src/media/video/winvideo/video_device_impl.cpp
index 08b872d89e..ee058dd9c6 100644
--- a/src/media/video/winvideo/video_device_impl.cpp
+++ b/src/media/video/winvideo/video_device_impl.cpp
@@ -283,7 +283,7 @@ VideoDeviceImpl::getChannelList() const
     return {"default"};
 }
 
-VideoDevice::VideoDevice(const std::string& path)
+VideoDevice::VideoDevice(const std::string& path, const std::vector<std::map<std::string, std::string>>&)
     : deviceImpl_(new VideoDeviceImpl(path))
 {
     node_ = path;
-- 
GitLab