From c186dbb4353c93e5cd02a79f4e4306b5881d1698 Mon Sep 17 00:00:00 2001
From: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>
Date: Tue, 3 Jun 2014 22:38:05 +0200
Subject: [PATCH] [ #49034 ] Refactor the video configuration code to be safer
 (1/3)

This commit implement the new daemon video getcapabilities() to load
the whole device configuration when using the video module for the
first time. This prevent the back and forth between the various
layers of both the client and the daemon. Those, created a feedback
loop that could crash the daemon or corrupt the Qt models.

While it will take a while to get to a stable point again, this
code is much more robust than the previous implementation.

The next few commits will replace the last bits of the old code
path by the new one.
---
 src/dbus/metatypes.h                |  11 +-
 src/dbus/videomanager-introspec.xml |  59 ++++++--
 src/typedefs.h                      |   1 +
 src/videodevice.cpp                 | 213 ++++++++++++++++++----------
 src/videodevice.h                   | 109 +++++++++++---
 src/videodevicemodel.cpp            | 104 +++++---------
 src/videodevicemodel.h              |  25 +++-
 src/videomodel.cpp                  |  38 ++++-
 src/videomodel.h                    |   5 +-
 src/videorenderer.cpp               |  18 +--
 src/videorenderer.h                 |  50 +++----
 11 files changed, 413 insertions(+), 220 deletions(-)

diff --git a/src/dbus/metatypes.h b/src/dbus/metatypes.h
index 01d22f50..ba3c85fb 100644
--- a/src/dbus/metatypes.h
+++ b/src/dbus/metatypes.h
@@ -30,18 +30,27 @@ typedef QMap<QString, QString> MapStringString;
 typedef QMap<QString, int> MapStringInt;
 typedef QVector<int> VectorInt;
 typedef QVector< QMap<QString, QString> > VectorMapStringString;
+typedef QVector< QString > VectorString;
+typedef QMap< QString, QMap< QString, QVector<QString> > > MapStringMapStringVectorString;
+typedef QMap< QString, QVector<QString> > MapStringVectorString;
 
 Q_DECLARE_METATYPE(MapStringString)
 Q_DECLARE_METATYPE(MapStringInt)
 Q_DECLARE_METATYPE(VectorMapStringString)
+Q_DECLARE_METATYPE(MapStringMapStringVectorString)
 Q_DECLARE_METATYPE(VectorInt)
+Q_DECLARE_METATYPE(VectorString)
+Q_DECLARE_METATYPE(MapStringVectorString)
 
 static bool dbus_metaTypeInit = false;
 inline void registerCommTypes() {
 	qDBusRegisterMetaType<MapStringString>();
 	qDBusRegisterMetaType<MapStringInt>();
 	qDBusRegisterMetaType<VectorMapStringString>();
-	qDBusRegisterMetaType<VectorInt>();
+        qDBusRegisterMetaType<MapStringMapStringVectorString>();
+        qDBusRegisterMetaType<VectorInt>();
+	qDBusRegisterMetaType<VectorString>();
+        qDBusRegisterMetaType<MapStringVectorString>();
    dbus_metaTypeInit = true;
 }
 #pragma GCC diagnostic pop
diff --git a/src/dbus/videomanager-introspec.xml b/src/dbus/videomanager-introspec.xml
index 7feb2cfd..4dc4f890 100644
--- a/src/dbus/videomanager-introspec.xml
+++ b/src/dbus/videomanager-introspec.xml
@@ -5,14 +5,14 @@
 
         <method name="getDeviceList" tp:name-for-bindings="getDeviceList">
             <tp:docstring>Returns a list of the detected v4l2 devices</tp:docstring>
-            <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
             <arg type="as" name="list" direction="out">
             </arg>
         </method>
 
         <method name="getDeviceChannelList" tp:name-for-bindings="getDeviceChannelList">
             <tp:docstring>Returns a list of the channels available for a given v4l2 device</tp:docstring>
-            <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
             <arg type="s" name="device" direction="in">
             </arg>
             <arg type="as" name="list" direction="out">
@@ -21,7 +21,7 @@
 
         <method name="getDeviceSizeList" tp:name-for-bindings="getDeviceSizeList">
             <tp:docstring>Returns a list of the resolutions available for a given channel of a given v4l2 device</tp:docstring>
-            <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
             <arg type="s" name="device" direction="in">
             </arg>
             <arg type="s" name="channel" direction="in">
@@ -32,7 +32,7 @@
 
         <method name="getDeviceRateList" tp:name-for-bindings="getDeviceRateList">
            <tp:docstring>Returns a list of the framerates available for a given resolution of a given channel of a given v4l2 device</tp:docstring>
-           <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/>
+           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
            <arg type="s" name="device" direction="in">
            </arg>
            <arg type="s" name="channel" direction="in">
@@ -43,9 +43,18 @@
            </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>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringMapStringVectorString"/>
+            <arg type="s" name="name" direction="in">
+            </arg>
+            <arg type="a{sa{sas}}" name="cap" direction="out">
+            </arg>
+        </method>
+
         <method name="getSettingsFor" tp:name-for-bindings="getSettingsFor">
            <tp:docstring>Returns a map of settings for the given device name</tp:docstring>
-            <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringString"/>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
             <arg type="s" name="device" direction="in">
             </arg>
             <arg type="a{ss}" name="map" direction="out">
@@ -54,7 +63,7 @@
 
         <method name="getPreferences" tp:name-for-bindings="getPreferences">
            <tp:docstring>Returns a map of user preferences for the given device name</tp:docstring>
-            <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringString"/>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
             <arg type="s" name="name" direction="in">
             </arg>
             <arg type="a{ss}" name="map" direction="out">
@@ -65,7 +74,7 @@
             <tp:docstring>Set the preferences of a given device name</tp:docstring>
             <arg type="s" name="name" direction="in">
             </arg>
-            <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="MapStringString"/>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="MapStringString"/>
             <arg type="a{ss}" name="pref" direction="in">
             </arg>
         </method>
@@ -75,18 +84,48 @@
             </arg>
         </method>
 
+        <method name="getActiveDeviceChannel" tp:name-for-bindings="getActiveDeviceChannel">
+            <arg type="s" name="channel" direction="out">
+            </arg>
+        </method>
+
+        <method name="getActiveDeviceSize" tp:name-for-bindings="getActiveDeviceSize">
+            <arg type="s" name="size" direction="out">
+            </arg>
+        </method>
+
+        <method name="getActiveDeviceRate" tp:name-for-bindings="getActiveDeviceRate">
+            <arg type="s" name="rate" direction="out">
+            </arg>
+        </method>
+
         <method name="setActiveDevice" tp:name-for-bindings="setActiveDevice">
             <arg type="s" name="device" direction="in">
             </arg>
         </method>
 
+        <method name="setActiveDeviceChannel" tp:name-for-bindings="setActiveDeviceChannel">
+            <arg type="s" name="channel" direction="in">
+            </arg>
+        </method>
+
+        <method name="setActiveDeviceSize" tp:name-for-bindings="setActiveDeviceSize">
+            <arg type="s" name="size" direction="in">
+            </arg>
+        </method>
+
+        <method name="setActiveDeviceRate" tp:name-for-bindings="setActiveDeviceRate">
+            <arg type="s" name="rate" direction="in">
+            </arg>
+        </method>
+
         <!-- Video Codec related methods -->
 
         <method name="getCodecs" tp:name-for-bindings="getCodecs">
             <tp:docstring>Gets the hashtable describing all the codecs and their parameters for a given account</tp:docstring>
             <arg type="s" name="accountID" direction="in">
             </arg>
-            <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
             <arg type="aa{ss}" name="details" direction="out">
             </arg>
         </method>
@@ -95,7 +134,7 @@
            <tp:docstring>Sets a vector of hashtables describing codecs and their parameters for a given account, one hashtable per codec</tp:docstring>
            <arg type="s" name="accountID" direction="in">
            </arg>
-           <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="VectorMapStringString"/>
+           <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="VectorMapStringString"/>
            <arg type="aa{ss}" name="details" direction="in">
            </arg>
         </method>
@@ -125,7 +164,7 @@
         </method>
 
         <method name="hasCameraStarted" tp:name-for-bindings="hasCameraStarted">
-            <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="Bool"/>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="Bool"/>
             <arg type="b" name="started" direction="out">
             <tp:docstring>Returns true if the camera has already started, false otherwise</tp:docstring>
             </arg>
diff --git a/src/typedefs.h b/src/typedefs.h
index d3fb6b18..ff77e33c 100644
--- a/src/typedefs.h
+++ b/src/typedefs.h
@@ -28,6 +28,7 @@
 
 typedef QMap<QString, QString> MapStringString;
 typedef QVector< QMap<QString, QString> > VectorMapStringString;
+typedef QMap< QString, QMap< QString, QVector<QString> > > MapStringMapStringVectorString;
 typedef QMap<QString, int> MapStringInt;
 
 template<class T, class E>
diff --git a/src/videodevice.cpp b/src/videodevice.cpp
index fcaf69c6..6ef8faf6 100644
--- a/src/videodevice.cpp
+++ b/src/videodevice.cpp
@@ -19,15 +19,17 @@
 #include "dbus/videomanager.h"
 
 
-Resolution::Resolution(uint _width, uint _height):QSize(_width,_height)
+Resolution::Resolution(uint _width, uint _height):QSize(_width,_height),
+m_pCurrentRate(nullptr),m_pChannel(nullptr)
 {
 }
 
-Resolution::Resolution() : QSize()
+Resolution::Resolution() : QSize(),m_pCurrentRate(nullptr),m_pChannel(nullptr)
 {
 }
 
-Resolution::Resolution(const QString& size)
+Resolution::Resolution(const QString& size, VideoChannel* chan)
+: m_pCurrentRate(nullptr),m_pChannel(chan)
 {
    if (size.split('x').size() == 2) {
       setWidth(size.split('x')[0].toInt());
@@ -35,24 +37,50 @@ Resolution::Resolution(const QString& size)
    }
 }
 
-Resolution::Resolution(const Resolution& res):QSize(res.width(),res.height())
+Resolution::Resolution(const Resolution& res):QSize(res.width(),res.height()),
+m_pCurrentRate(nullptr),m_pChannel(nullptr)
 {
 }
 
-Resolution::Resolution(const QSize& size):QSize(size)
+Resolution::Resolution(const QSize& size):QSize(size),
+m_pCurrentRate(nullptr),m_pChannel(nullptr)
 {
 }
 
-const QString Resolution::toString() const
+const QString Resolution::name() const
 {
    return QString::number(width())+'x'+QString::number(height());
 }
 
 
 ///Constructor
-VideoDevice::VideoDevice(const QString &id) : QObject(nullptr), m_DeviceId(id),m_Resolution("0x0")
+VideoDevice::VideoDevice(const QString &id) : QObject(nullptr), m_DeviceId(id),
+m_pCurrentChannel(nullptr)
 {
-   
+   VideoManagerInterface& interface = DBus::VideoManager::instance();
+   MapStringMapStringVectorString cap = interface.getCapabilities(id);
+   QMapIterator<QString, MapStringVectorString> channels(cap);
+   qDebug() << "\n\n\n\nCAP"  << id << cap.size();
+   while (channels.hasNext()) {
+      channels.next();
+
+      VideoChannel* chan = new VideoChannel(this,channels.key());
+      m_lChannels << chan;
+
+      QMapIterator<QString, VectorString> resolutions(channels.value());
+      while (resolutions.hasNext()) {
+         resolutions.next();
+
+         Resolution* res = new Resolution(resolutions.key(),chan);
+         chan->m_lValidResolutions << res;
+
+         foreach(const QString& rate, resolutions.value()) {
+            VideoRate* r = new VideoRate(res,rate);
+            res->m_lValidRates << r;
+         }
+      }
+   }
+   Q_UNUSED(cap)
 }
 
 ///Destructor
@@ -60,104 +88,145 @@ VideoDevice::~VideoDevice()
 {
 }
 
-///Get the valid rates for this device
-const QStringList VideoDevice::rateList(const VideoChannel& channel, const Resolution& resolution)
-{
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
-   return interface.getDeviceRateList(m_DeviceId,channel,resolution.toString());
-}
-
 ///Get the valid channel list
-const QList<VideoChannel> VideoDevice::channelList()
+QList<VideoChannel*> VideoDevice::channelList() const
 {
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
-   return interface.getDeviceChannelList(m_DeviceId);
+   return m_lChannels;
 }
 
-///Set the current device rate
-void VideoDevice::setRate(const VideoRate& rate)
+///Save the current settings
+void VideoDevice::save()
 {
-   m_Rate = rate;
+   //In case new (unsupported) fields are added, merge with existing
    VideoManagerInterface& interface = DBus::VideoManager::instance();
    MapStringString pref = interface.getPreferences(m_DeviceId);
-   pref[PreferenceNames::RATE] = rate;
+   pref[VideoDevice::PreferenceNames::CHANNEL] = activeChannel()->name();
+   pref[VideoDevice::PreferenceNames::SIZE   ] = activeChannel()->activeResolution()->name();
+   pref[VideoDevice::PreferenceNames::RATE   ] = activeChannel()->activeResolution()->activeRate()->name();
    interface.setPreferences(m_DeviceId,pref);
 }
 
-///Set the current resolution
-void VideoDevice::setResolution(const Resolution& resolution) //??? No device
+///Get the device id
+const QString VideoDevice::id() const
 {
-   m_Resolution = resolution;
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
-   MapStringString pref = interface.getPreferences(m_DeviceId);
-   pref[PreferenceNames::SIZE] = resolution.toString();
-   interface.setPreferences(m_DeviceId,pref);
+   return m_DeviceId;
 }
 
-///Set the current device channel
-void VideoDevice::setChannel(const VideoChannel& channel) //??? No device
+///Get the device name
+const QString VideoDevice::name() const
 {
-   m_Channel = channel;
    VideoManagerInterface& interface = DBus::VideoManager::instance();
-   MapStringString pref = interface.getPreferences(m_DeviceId);
-   pref[PreferenceNames::CHANNEL] = channel;
-   interface.setPreferences(m_DeviceId,pref);
+   return QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::NAME];;
 }
 
-///Get the current resolution
-const Resolution VideoDevice::resolution()
+///Is this device the default one
+bool VideoDevice::isActive() const
 {
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
-   if ((!m_Resolution.isValid()) || m_Resolution == QSize(0,0))
-      m_Resolution = Resolution(QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::SIZE]);
-   return m_Resolution;
+   return QString(DBus::VideoManager::instance().getActiveDevice()) == m_DeviceId;
 }
 
-///Get the current channel
-const VideoChannel VideoDevice::channel() //??? No device
+Resolution* VideoChannel::activeResolution()
 {
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
-   if (m_Channel.isEmpty())
-      m_Channel = QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::CHANNEL];
-   return m_Channel;
+   //If it is the current device, then there is "current" resolution
+   if ((!m_pCurrentResolution) && m_pDevice->isActive()) {
+      VideoManagerInterface& interface = DBus::VideoManager::instance();
+      const QString res = QMap<QString,QString>(interface.getPreferences(m_pDevice->id()))[VideoDevice::PreferenceNames::SIZE];
+      foreach(Resolution* r, validResolutions()) {
+         if (r->name() == res) {
+            m_pCurrentResolution = r;
+            break;
+         }
+      }
+   }
+   //If it isn't the current _or_ the current res is invalid, pick the first valid one
+   if (!m_pCurrentResolution && validResolutions().size()) {
+      m_pCurrentResolution = validResolutions()[0];
+   }
+
+   return m_pCurrentResolution;
 }
 
-///Get the current rate
-const VideoRate VideoDevice::rate()
-{
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
-   if (m_Rate.isEmpty())
-      m_Rate = QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::RATE];
-   return m_Rate;
+bool VideoChannel::setActiveResolution(Resolution* res) {
+   if ((!res) || m_lValidResolutions.indexOf(res) == -1 || res->name().isEmpty()) {
+      qWarning() << "Invalid active resolution" << (res?res->name():"NULL");
+      return false;
+   }
+   m_pCurrentResolution = res;
+   m_pDevice->save();
+   return true;
 }
 
-///Get a list of valid resolution
-const QList<Resolution> VideoDevice::resolutionList(const VideoChannel& channel)
+VideoRate* Resolution::activeRate()
 {
-   QList<Resolution> toReturn;
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
-   const QStringList list = interface.getDeviceSizeList(m_DeviceId,channel);
-   foreach(const QString& res,list) {
-      toReturn << Resolution(res);
+   if (!m_pChannel) {
+      qWarning() << "Trying to get the active rate of an unattached resolution";
+      return nullptr;
+   }
+   if (!m_pCurrentRate && m_pChannel && m_pChannel->device()->isActive()) {
+      VideoManagerInterface& interface = DBus::VideoManager::instance();
+      const QString rate = QMap<QString,QString>(
+         interface.getPreferences(m_pChannel->device()->id()))[VideoDevice::PreferenceNames::RATE];
+      foreach(VideoRate* r, m_lValidRates) {
+         if (r->name() == rate) {
+            m_pCurrentRate = r;
+            break;
+         }
+      }
    }
-   return toReturn;
+   if ((!m_pCurrentRate) && m_lValidRates.size())
+      m_pCurrentRate = m_lValidRates[0];
+
+   return m_pCurrentRate;
 }
 
-///Get the device id
-const QString VideoDevice::id() const
+int Resolution::index() const
 {
-   return m_DeviceId;
+   return m_pChannel?m_pChannel->validResolutions().indexOf(const_cast<Resolution*>(this)):-1;
 }
 
-///Get the device name
-const QString VideoDevice::name()
+int VideoChannel::index() {
+   return m_pDevice->channelList().indexOf(this);
+}
+
+int VideoRate::index() {
+   return m_pResolution->validRates().indexOf(this);
+}
+
+bool VideoDevice::setActiveChannel(VideoChannel* chan)
 {
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
-   return QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::NAME];;
+   if (!chan || !m_lChannels.indexOf(chan)) {
+      qWarning() << "Trying to set an invalid channel" << (chan?chan->name():"NULL") << "for" << id();
+      return false;
+   }
+   m_pCurrentChannel = chan;
+   save();
+   return true;
 }
 
-///Is this device the default one
-bool VideoDevice::isActive()
+VideoChannel::VideoChannel(VideoDevice* dev,const QString& name) :
+   m_Name(name),m_pCurrentResolution(nullptr),m_pDevice(dev)
 {
-   return QString(DBus::VideoManager::instance().getActiveDevice()) == m_DeviceId;
+   m_pCurrentResolution = nullptr;
+   m_pCurrentResolution = nullptr;
+   m_pCurrentResolution = nullptr;
+   m_pCurrentResolution = nullptr;
+   m_pCurrentResolution = nullptr;
 }
+
+VideoChannel* VideoDevice::activeChannel() const
+{
+   if (!m_pCurrentChannel) {
+      VideoManagerInterface& interface = DBus::VideoManager::instance();
+      const QString chan = QMap<QString,QString>(interface.getPreferences(m_DeviceId))[VideoDevice::PreferenceNames::CHANNEL];
+      foreach(VideoChannel* c, m_lChannels) {
+         if (c->name() == chan) {
+            const_cast<VideoDevice*>(this)->m_pCurrentChannel = c;
+            break;
+         }
+      }
+   }
+   if (!m_pCurrentChannel && m_lChannels.size()) {
+      const_cast<VideoDevice*>(this)->m_pCurrentChannel = m_lChannels[0];
+   }
+   return m_pCurrentChannel;
+}
\ No newline at end of file
diff --git a/src/videodevice.h b/src/videodevice.h
index 35a2d742..34e8a8d4 100644
--- a/src/videodevice.h
+++ b/src/videodevice.h
@@ -26,25 +26,90 @@
 
 //SFLPhone
 class VideoRenderer;
+class Resolution;
+class VideoRate;
+class VideoChannel;
+class VideoDevice;
 
 ///@typedef VideoChannel A channel available in a Device
-typedef QString VideoChannel;
+class LIB_EXPORT VideoChannel
+{
+   //Only VideoDevice can add resolutions
+   friend class VideoDevice;
+public:
+   QString name() const {
+      return m_Name;
+   }
+   Resolution* activeResolution();
+   QList<Resolution*> validResolutions() const {
+      return m_lValidResolutions;
+   }
+   VideoDevice* device() const {
+      return m_pDevice;
+   }
+   int index();
+
+   bool setActiveResolution(Resolution* res);
+
+private:
+   VideoChannel(VideoDevice* dev,const QString& name);
+   virtual ~VideoChannel() {}
+   QString m_Name;
+   QList<Resolution*> m_lValidResolutions;
+   Resolution*        m_pCurrentResolution;
+   VideoDevice*       m_pDevice;
+};
 
 ///@typedef VideoRate The rate for a device
-typedef QString VideoRate;
+class LIB_EXPORT VideoRate
+{
+   //Can only be created by VideoDevice
+   friend class VideoDevice;
+
+public:
+   virtual ~VideoRate() {}
+   QString name() const {
+      return m_Name;
+   }
+   int index();
+private:
+   VideoRate(const Resolution* res,const QString& name) :
+      m_Name(name),m_pResolution(res) {}
+   QString m_Name;
+   const Resolution* m_pResolution;
+};
 
 ///@struct Resolution Equivalent of "640x480"
 class LIB_EXPORT Resolution : public QSize {
+   //Only VideoDevice can add validated rates
+   friend class VideoDevice;
 public:
    //Constructor
    Resolution(uint _width, uint _height);
-   Resolution(const QString& size = QString());
+   Resolution(const QString& size = QString(), VideoChannel* chan = nullptr);
    Resolution(const Resolution& res);
    Resolution(const QSize& size);
    explicit Resolution();
    //Getter
-   const QString toString() const;
-
+   const QString name() const;
+   const QList<VideoRate*> validRates() const {
+      return m_lValidRates;
+   }
+   int index() const;
+   VideoRate* activeRate();
+   bool setActiveRate(VideoRate* rate) {
+      if (!rate || (m_lValidRates.indexOf(rate) != -1)) {
+         qWarning() << "Trying to set an invalid rate";
+         return false;
+      }
+      return true;
+   }
+private:
+
+   //Attributes
+   QList<VideoRate*> m_lValidRates;
+   VideoRate*        m_pCurrentRate;
+   VideoChannel*     m_pChannel;
 };
 
 class VideoModel;
@@ -54,27 +119,25 @@ class LIB_EXPORT VideoDevice : public QObject {
    Q_OBJECT
    friend class VideoModel;
    friend class VideoDeviceModel;
+
+   //Need to access the PreferenceNames table
+   friend class VideoChannel;
+   friend class Resolution;
    public:
       //Constants
       constexpr static const char* NONE = "";
 
       //Getter
-      const QStringList         rateList(const VideoChannel& channel, const Resolution& resolution);
-      const QList<Resolution>   resolutionList(const VideoChannel& channel);
-      const QList<VideoChannel> channelList ();
-      const Resolution          resolution  ();
-      const VideoChannel        channel     ();
-      const VideoRate           rate        ();
-      const QString             id          () const;
-      const QString             name        ();
-      bool  isActive                        ();
+      QList<VideoChannel*> channelList      () const;
+      VideoChannel*        activeChannel    () const;
+      const QString        id               () const;
+      const QString        name             () const;
+      bool  isActive                        () const;
 
       //Static getter
 
       //Setter
-      void setRate       ( const VideoRate&    rate       );
-      void setResolution ( const Resolution&   resolution );
-      void setChannel    ( const VideoChannel& channel    );
+      bool setActiveChannel(VideoChannel* chan);
 
    private:
       //Constructor
@@ -82,10 +145,12 @@ class LIB_EXPORT VideoDevice : public QObject {
       ~VideoDevice();
 
       //Attributes
-      QString m_DeviceId;
-      QString m_Rate;
-      QString m_Channel;
-      Resolution m_Resolution;
+      QString       m_DeviceId          ;
+      VideoChannel* m_pCurrentChannel   ;
+      QList<VideoChannel*> m_lChannels  ;
+
+      //Helper
+      void save();
 
       class PreferenceNames {
       public:
@@ -95,7 +160,7 @@ class LIB_EXPORT VideoDevice : public QObject {
          constexpr static const char* SIZE    = "size"   ;
       };
 
-   signals:
+   Q_SIGNALS:
       void renderingStarted(VideoRenderer*);
       void renderingStopped(VideoRenderer*);
       void renderStateChanged(bool state);
diff --git a/src/videodevicemodel.cpp b/src/videodevicemodel.cpp
index 71d1febd..07bd35ea 100644
--- a/src/videodevicemodel.cpp
+++ b/src/videodevicemodel.cpp
@@ -193,7 +193,7 @@ VideoDeviceResolutionModel* VideoDeviceModel::resolutionModel() const
 QVariant VideoDeviceResolutionModel::data( const QModelIndex& idx, int role) const
 {
    if(idx.column() == 0 && role == Qt::DisplayRole)
-      return QVariant(m_lResolutions[idx.row()]->toString());
+      return QVariant(VideoDeviceModel::instance()->activeDevice()->activeChannel()->validResolutions()[idx.row()]->name());
    return QVariant();
 }
 
@@ -201,7 +201,7 @@ QVariant VideoDeviceResolutionModel::data( const QModelIndex& idx, int role) con
 int VideoDeviceResolutionModel::rowCount( const QModelIndex& par ) const
 {
    Q_UNUSED(par)
-   return m_lResolutions.size();
+   return VideoDeviceModel::instance()->activeDevice()->activeChannel()->validResolutions().size();
 }
 
 ///Items flag
@@ -233,19 +233,20 @@ VideoDeviceResolutionModel::~VideoDeviceResolutionModel()
 }
 
 
-Resolution VideoDeviceResolutionModel::activeResolution() const
+Resolution* VideoDeviceResolutionModel::activeResolution() const
 {
-   return VideoDeviceModel::instance()->activeDevice()->resolution();
+   return VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution();
 }
 
 ///Save the current model over dbus
 void VideoDeviceResolutionModel::setActive(const QModelIndex& idx)
 {
    if (idx.isValid()) {
-      QSize s1(*m_lResolutions[idx.row()]),s2(VideoDeviceModel::instance()->activeDevice()->resolution());
+      Resolution* r = VideoDeviceModel::instance()->activeDevice()->activeChannel()->validResolutions()[idx.row()];
+      QSize s1(*r),s2(*VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution());
       if (s1 == s2)
          return;
-      VideoDeviceModel::instance()->activeDevice()->setResolution(m_lResolutions[idx.row()]->toString());
+      VideoDeviceModel::instance()->activeDevice()->activeChannel()->setActiveResolution(r);
       emit changed();
       emit currentIndexChanged(idx.row());
    }
@@ -262,32 +263,15 @@ void VideoDeviceResolutionModel::setActive(const int idx)
 void VideoDeviceResolutionModel::reload()
 {
    QHash<QString,Resolution*> devicesHash;
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
    VideoDevice* active = VideoDeviceModel::instance()->activeDevice();
    if (active) {
-      const QStringList deviceList = interface.getDeviceSizeList(active->id(),
-                                                               VideoDeviceModel::instance()->rateModel()->activeRate());
-      if (deviceList.size() == m_hResolutions.size()) {
-         m_lResolutions = m_hResolutions.values();
-      }
 
-      foreach(const QString& deviceName,deviceList) {
-         if (!m_hResolutions.contains(deviceName)) {
-            devicesHash[deviceName] = new Resolution(deviceName);
-         }
-         else {
-            devicesHash[deviceName] = m_hResolutions[deviceName];
-         }
-      }
-      m_hResolutions.clear();
-      m_hResolutions = devicesHash;
-      m_lResolutions = m_hResolutions.values();
       emit layoutChanged();
 
       VideoDeviceModel::instance()->rateModel()->reload();
 
       emit changed();
-      emit currentIndexChanged(m_lResolutions.indexOf(m_hResolutions[activeResolution().toString()]));
+      emit currentIndexChanged(activeResolution()->index());
    }
    else {
       m_hResolutions.clear();
@@ -298,15 +282,7 @@ void VideoDeviceResolutionModel::reload()
 
 int VideoDeviceResolutionModel::currentIndex() const
 {
-   const Resolution& res = activeResolution();
-   for (int i=0;i<m_lResolutions.size();i++) {
-      Resolution* availableRes  = m_lResolutions[i];
-      if (res.width() == availableRes->width() && res.height() == availableRes->height()) {
-         return i;
-      }
-   }
-   qWarning() << "Invalid resolution";
-   return -1;
+   return VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->index();
 }
 
 
@@ -324,16 +300,16 @@ VideoDeviceChannelModel* VideoDeviceModel::channelModel() const
 }
 
 
-QString VideoDeviceChannelModel::activeChannel() const
+VideoChannel* VideoDeviceChannelModel::activeChannel() const
 {
-   return VideoDeviceModel::instance()->activeDevice()->channel();
+   return VideoDeviceModel::instance()->activeDevice()->activeChannel();
 }
 
 ///Get data from the model
 QVariant VideoDeviceChannelModel::data( const QModelIndex& idx, int role) const
 {
    if(idx.column() == 0 && role == Qt::DisplayRole)
-      return QVariant(m_lChannels[idx.row()]);
+      return QVariant(activeChannel()->name());
    return QVariant();
 }
 
@@ -341,7 +317,7 @@ QVariant VideoDeviceChannelModel::data( const QModelIndex& idx, int role) const
 int VideoDeviceChannelModel::rowCount( const QModelIndex& par ) const
 {
    Q_UNUSED(par)
-   return m_lChannels.size();
+   return VideoDeviceModel::instance()->activeDevice()->channelList().size();
 }
 
 ///Items flag
@@ -375,7 +351,8 @@ VideoDeviceChannelModel::~VideoDeviceChannelModel()
 void VideoDeviceChannelModel::setActive(const QModelIndex& idx)
 {
    if (idx.isValid()) {
-      VideoDeviceModel::instance()->activeDevice()->setChannel(m_lChannels[idx.row()]);
+      VideoChannel* c = VideoDeviceModel::instance()->activeDevice()->channelList()[idx.row()];
+      VideoDeviceModel::instance()->activeDevice()->setActiveChannel(c);
       emit changed();
       emit currentIndexChanged(idx.row());
    }
@@ -389,29 +366,23 @@ void VideoDeviceChannelModel::setActive(const int idx)
 
 void VideoDeviceChannelModel::reload()
 {
-   QHash<QString,QString> devicesHash;
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
    VideoDevice* active = VideoDeviceModel::instance()->activeDevice();
    if (active) {
-      const QStringList deviceList = interface.getDeviceChannelList(active->id());
 
-      m_lChannels = deviceList;
       emit layoutChanged();
 
       VideoDeviceModel::instance()->resolutionModel()->reload();
 
-      setActive(m_lChannels.indexOf(activeChannel()));
+      setActive(activeChannel()->index());
    }
    else {
-      //There is no channel when there is no devices
-      m_lChannels.clear();
       emit layoutChanged();
    }
 }
 
 int VideoDeviceChannelModel::currentIndex() const
 {
-   return m_lChannels.indexOf(activeChannel());
+   return activeChannel()->index();
 }
 
 
@@ -427,16 +398,16 @@ VideoDeviceRateModel* VideoDeviceModel::rateModel() const
    return m_pRateModel;
 }
 
-QString VideoDeviceRateModel::activeRate() const
+VideoRate* VideoDeviceRateModel::activeRate() const
 {
-   return VideoDeviceModel::instance()->activeDevice()->rate();
+   return VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->activeRate();
 }
 
 ///Get data from the model
 QVariant VideoDeviceRateModel::data( const QModelIndex& idx, int role) const
 {
-   if(idx.isValid() && idx.column() == 0 && role == Qt::DisplayRole && idx.row() < m_lRates.size())
-      return QVariant(m_lRates[idx.row()]);
+   if(idx.isValid() && idx.column() == 0 && role == Qt::DisplayRole)
+      return QVariant(VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->validRates()[idx.row()]->name());
    return QVariant();
 }
 
@@ -444,7 +415,7 @@ QVariant VideoDeviceRateModel::data( const QModelIndex& idx, int role) const
 int VideoDeviceRateModel::rowCount( const QModelIndex& par ) const
 {
    Q_UNUSED(par)
-   return m_lRates.size();
+   return VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->validRates().size();
 }
 
 ///Items flag
@@ -478,7 +449,8 @@ VideoDeviceRateModel::~VideoDeviceRateModel()
 void VideoDeviceRateModel::setActive(const QModelIndex& idx)
 {
    if (idx.isValid()) {
-      VideoDeviceModel::instance()->activeDevice()->setRate(m_lRates[idx.row()]);
+      VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->setActiveRate(
+         VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->validRates()[idx.row()]);
       emit changed();
       emit currentIndexChanged(idx.row());
    }
@@ -495,27 +467,19 @@ void VideoDeviceRateModel::setActive(const int idx)
 void VideoDeviceRateModel::reload()
 {
    QHash<QString,VideoDevice*> devicesHash;
-   VideoManagerInterface& interface = DBus::VideoManager::instance();
    VideoDevice* active = VideoDeviceModel::instance()->activeDevice();
    if (active) {
-      const QStringList deviceList = interface.getDeviceRateList(active->id                                                       (),
-         VideoDeviceModel::instance()->channelModel()->activeChannel      (),
-         VideoDeviceModel::instance()->resolutionModel()->activeResolution().toString()
-      );
-      m_lRates = deviceList;
       emit layoutChanged();
-      const int currentRate = m_lRates.indexOf(activeRate());
-      setActive(currentRate==-1?0:currentRate);
+      setActive(activeRate()->index());
    }
    else {
-      m_lRates.clear();
       emit layoutChanged();
    }
 }
 
 int VideoDeviceRateModel::currentIndex() const
 {
-   return m_lRates.indexOf(activeRate());
+   return activeRate()->index();
 }
 
 
@@ -542,19 +506,19 @@ QVariant ExtendedVideoDeviceModel::data( const QModelIndex& index, int role ) co
       case ExtendedDeviceList::NONE:
          switch(role) {
             case Qt::DisplayRole:
-               return "NONE";
+               return tr("NONE");
          };
          break;
       case ExtendedDeviceList::SCREEN:
          switch(role) {
             case Qt::DisplayRole:
-               return "SCREEN";
+               return tr("SCREEN");
          };
          break;
       case ExtendedDeviceList::FILE:
          switch(role) {
             case Qt::DisplayRole:
-               return "FILE";
+               return tr("FILE");
          };
          break;
       default:
@@ -600,16 +564,18 @@ void ExtendedVideoDeviceModel::switchTo(const int idx)
 {
    switch (idx) {
       case ExtendedDeviceList::NONE:
-         DBus::VideoManager::instance().switchInput("");
+         DBus::VideoManager::instance().switchInput(ProtocolPrefix::NONE);
          break;
       case ExtendedDeviceList::SCREEN:
-         DBus::VideoManager::instance().switchInput("display://0:100x100");
+         DBus::VideoManager::instance().switchInput( QString(ProtocolPrefix::DISPLAY)+"0:100x100");
          break;
       case ExtendedDeviceList::FILE:
-         DBus::VideoManager::instance().switchInput(!m_CurrentFile.isEmpty()?"file://"+m_CurrentFile.path():"");
+         DBus::VideoManager::instance().switchInput(
+            !m_CurrentFile.isEmpty()?+ProtocolPrefix::FILE+m_CurrentFile.path():ProtocolPrefix::NONE
+         );
          break;
       default:
-         DBus::VideoManager::instance().switchInput("v4l2://"+
+         DBus::VideoManager::instance().switchInput(ProtocolPrefix::V4L2 +
             VideoDeviceModel::instance()->index(idx-ExtendedDeviceList::__COUNT,0).data(Qt::DisplayRole).toString());
          break;
    };
diff --git a/src/videodevicemodel.h b/src/videodevicemodel.h
index 2308ccfb..cbd0359c 100644
--- a/src/videodevicemodel.h
+++ b/src/videodevicemodel.h
@@ -29,6 +29,7 @@
 //SFLPhone
 class VideoDevice;
 
+//DEPRECATED
 ///Abstract model for managing account video codec list
 class LIB_EXPORT VideoDeviceResolutionModel : public QAbstractListModel {
    #pragma GCC diagnostic push
@@ -47,13 +48,14 @@ public:
    Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
    virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
 
-   Resolution activeResolution() const;
+   Resolution* activeResolution() const;
    int currentIndex() const;
 
 private:
+
    //Attrbutes
    QHash<QString,Resolution*>   m_hResolutions  ;
-   QList<Resolution*> m_lResolutions;
+//    QList<Resolution*> m_lResolutions;
    static VideoDeviceResolutionModel* m_spInstance;
 
 public Q_SLOTS:
@@ -67,6 +69,7 @@ Q_SIGNALS:
 };
 Q_DECLARE_METATYPE(VideoDeviceResolutionModel*)
 
+//DEPRECATED
 ///Abstract model for managing account video codec list
 class LIB_EXPORT VideoDeviceChannelModel : public QAbstractListModel {
    #pragma GCC diagnostic push
@@ -87,12 +90,12 @@ public:
 
    static VideoDeviceChannelModel* instance();
 
-   QString activeChannel() const;
+   VideoChannel* activeChannel() const;
    int currentIndex() const;
 
 private:
    //Attrbutes
-   QList<QString> m_lChannels;
+//    QList<QString> m_lChannels;
 
 
 public Q_SLOTS:
@@ -126,6 +129,15 @@ public:
    //Singleton
    static ExtendedVideoDeviceModel* instance();
 private:
+   //Constants
+   class ProtocolPrefix {
+   public:
+      constexpr static const char* NONE    = ""          ;
+      constexpr static const char* DISPLAY = "display://";
+      constexpr static const char* FILE    = "file://"   ;
+      constexpr static const char* V4L2    = "v4l2://"   ;
+   };
+
    struct Display {
       Display() : res("0x0"),point(0,0),index(0){}
       Resolution res ; /* Resolution 0x0 for native */
@@ -144,6 +156,7 @@ public Q_SLOTS:
    void setDisplay(int index, Resolution res = Resolution("0x0"), QPoint point = QPoint(0,0));
 };
 
+//DEPRECATED
 ///Abstract model for managing account video codec list
 class LIB_EXPORT VideoDeviceRateModel : public QAbstractListModel {
    #pragma GCC diagnostic push
@@ -162,12 +175,12 @@ public:
    Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
    virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
 
-   QString activeRate() const;
+   VideoRate* activeRate() const;
    int currentIndex() const;
 
 private:
    //Attrbutes
-   QList<QString> m_lRates;
+//    QList<QString> m_lRates;
 
 public Q_SLOTS:
    void setActive(const QModelIndex& idx);
diff --git a/src/videomodel.cpp b/src/videomodel.cpp
index c97986d2..f33915b3 100644
--- a/src/videomodel.cpp
+++ b/src/videomodel.cpp
@@ -32,7 +32,8 @@
 VideoModel* VideoModel::m_spInstance = nullptr;
 
 ///Constructor
-VideoModel::VideoModel():QThread(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_SSMutex(new QMutex())
+VideoModel::VideoModel():QThread(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_SSMutex(new QMutex()),
+m_pActiveDevice(nullptr)
 {
    VideoManagerInterface& interface = DBus::VideoManager::instance();
    connect( &interface , SIGNAL(deviceEvent())                           , this, SLOT(deviceEvent())                           );
@@ -69,7 +70,8 @@ VideoRenderer* VideoModel::getRenderer(const Call* call) const
 VideoRenderer* VideoModel::previewRenderer()
 {
    if (!m_lRenderers["local"]) {
-      m_lRenderers["local"] = new VideoRenderer("local","", VideoDeviceModel::instance()->activeDevice()->resolution());
+      m_lRenderers["local"] = new VideoRenderer("local","",
+         VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution());
    }
    return m_lRenderers["local"];
 }
@@ -109,13 +111,41 @@ void VideoModel::deviceEvent()
    
 }
 
+VideoDevice* VideoModel::activeDevice() const
+{
+   if (!m_pActiveDevice) {
+      VideoManagerInterface& interface = DBus::VideoManager::instance();
+      const QString activeDeviceId =  interface.getActiveDevice();
+      foreach(VideoDevice* dev, m_hDevices) {
+         if (dev->id() == activeDeviceId) {
+            const_cast<VideoModel*>(this)->m_pActiveDevice = dev;
+            break;
+         }
+      }
+   }
+   if (!m_pActiveDevice) {
+      qWarning() << "No active devices";
+   }
+   return m_pActiveDevice;
+}
+
 ///A video is not being rendered
 void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int width, int height)
 {
    Q_UNUSED(id)
 
+   Resolution* res;
+   if (VideoDeviceModel::instance()->activeDevice() 
+      && VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->width() == width) {
+      //FIXME flawed logic
+      res = VideoModel::activeDevice()->activeChannel()->activeResolution();
+   }
+   else {
+      res = new Resolution(width,height); //FIXME leak
+   }
+
    if (m_lRenderers[id] == nullptr ) {
-      m_lRenderers[id] = new VideoRenderer(id,shmPath,Resolution(width,height));
+      m_lRenderers[id] = new VideoRenderer(id,shmPath,res); 
       m_lRenderers[id]->moveToThread(this);
       if (!isRunning())
          start();
@@ -123,7 +153,7 @@ void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int
    else {
       VideoRenderer* renderer = m_lRenderers[id];
       renderer->setShmPath(shmPath);
-      renderer->setResolution(QSize(width,height));
+      renderer->setResolution(res);
    }
 
    m_lRenderers[id]->startRendering();
diff --git a/src/videomodel.h b/src/videomodel.h
index f89787ba..69997a69 100644
--- a/src/videomodel.h
+++ b/src/videomodel.h
@@ -46,13 +46,13 @@ public:
    VideoRenderer* getRenderer(const Call* call) const;
    VideoRenderer* previewRenderer();
    QList<VideoDevice*> devices();
-//    VideoDevice* activeDevice() const;
+   VideoDevice* activeDevice() const;
    VideoDevice* device(const QString &id);
    QMutex* startStopMutex() const;
 
    //Setters
    void setBufferSize(uint size);
-//    void setActiveDevice(const VideoDevice* device);
+   void setActiveDevice(const VideoDevice* device);
    void switchDevice(const VideoDevice* device) const;
 
 protected:
@@ -74,6 +74,7 @@ private:
    QMutex*        m_SSMutex     ;
    QHash<QString,VideoRenderer*> m_lRenderers;
    QHash<QString,VideoDevice*>   m_hDevices  ;
+   VideoDevice*   m_pActiveDevice;
 
 public Q_SLOTS:
    void stopPreview ();
diff --git a/src/videorenderer.cpp b/src/videorenderer.cpp
index 3e052ac2..1dc75a3f 100644
--- a/src/videorenderer.cpp
+++ b/src/videorenderer.cpp
@@ -55,10 +55,10 @@ struct SHMHeader{
 };
 
 ///Constructor
-VideoRenderer::VideoRenderer(const QString& id, const QString& shmPath, Resolution res): QObject(nullptr),
-   m_Width(res.width()), m_Height(res.height()), m_ShmPath(shmPath), fd(-1),
+VideoRenderer::VideoRenderer(const QString& id, const QString& shmPath, const Resolution* res): QObject(nullptr),
+   m_Width(res->width()), m_Height(res->height()), m_ShmPath(shmPath), fd(-1),
    m_pShmArea((SHMHeader*)MAP_FAILED), m_ShmAreaLen(0), m_BufferGen(0),
-   m_isRendering(false),m_pTimer(nullptr),m_Res(res),m_pMutex(new QMutex()),
+   m_isRendering(false),m_pTimer(nullptr),m_pRes(const_cast<Resolution*>(res)),m_pMutex(new QMutex()),
    m_Id(id),m_FrameIdx(false),m_pSSMutex(new QMutex())
 {
    setObjectName("VideoRenderer:"+id);
@@ -330,9 +330,9 @@ const QByteArray& VideoRenderer::currentFrame()
 }
 
 ///Return the current resolution
-Resolution VideoRenderer::activeResolution()
+const Resolution* VideoRenderer::activeResolution()
 {
-   return m_Res;
+   return m_pRes;
 }
 
 ///Get mutex, in case renderer and views are not in the same thread
@@ -354,11 +354,11 @@ int VideoRenderer::fps() const
  *                                                                           *
  ****************************************************************************/
 
-void VideoRenderer::setResolution(QSize size)
+void VideoRenderer::setResolution(Resolution* res)
 {
-   m_Res = size;
-   m_Width = size.width();
-   m_Height = size.height();
+   m_pRes = res;
+   m_Width  = res->width();
+   m_Height = res->height();
 }
 
 void VideoRenderer::setShmPath(const QString& path)
diff --git a/src/videorenderer.h b/src/videorenderer.h
index a27494ab..d2abb62e 100644
--- a/src/videorenderer.h
+++ b/src/videorenderer.h
@@ -41,7 +41,7 @@ class LIB_EXPORT VideoRenderer : public QObject {
 
    public:
       //Constructor
-      VideoRenderer (const QString& id, const QString& shmPath, const Resolution res);
+      VideoRenderer (const QString& id, const QString& shmPath, const Resolution* res);
       ~VideoRenderer();
 
       //Mutators
@@ -50,37 +50,37 @@ class LIB_EXPORT VideoRenderer : public QObject {
       bool startShm ();
 
       //Getters
-      const char* rawData         ()      ;
-      bool        isRendering     ()      ;
+      const char*       rawData         ()      ;
+      bool              isRendering     ()      ;
       const QByteArray& currentFrame    ()      ;
-      Resolution  activeResolution()      ;
-      QMutex*     mutex           ()      ;
-      int         fps             () const;
+      const Resolution* activeResolution()      ;
+      QMutex*           mutex           ()      ;
+      int               fps             () const;
 
       //Setters
-      void setResolution(QSize   size);
+      void setResolution(Resolution* res);
       void setShmPath   (const QString& path);
 
    private:
       //Attributes
-      uint       m_Width      ;
-      uint       m_Height     ;
-      QString    m_ShmPath    ;
-      int        fd           ;
-      SHMHeader* m_pShmArea   ;
-      signed int m_ShmAreaLen ;
-      uint       m_BufferGen  ;
-      bool       m_isRendering;
-      QTimer*    m_pTimer     ;
-      QByteArray m_Frame[2]   ;
-      bool       m_FrameIdx   ;
-      Resolution m_Res        ;
-      QMutex*    m_pMutex     ;
-      QMutex*    m_pSSMutex   ;
-      QString    m_Id         ;
-      int        m_fpsC       ;
-      int        m_Fps        ;
-      QTime      m_CurrentTime;
+      uint              m_Width      ;
+      uint              m_Height     ;
+      QString           m_ShmPath    ;
+      int               fd           ;
+      SHMHeader      *  m_pShmArea   ;
+      signed int        m_ShmAreaLen ;
+      uint              m_BufferGen  ;
+      bool              m_isRendering;
+      QTimer*           m_pTimer     ;
+      QByteArray        m_Frame[2]   ;
+      bool              m_FrameIdx   ;
+      Resolution*       m_pRes       ;
+      QMutex*           m_pMutex     ;
+      QMutex*           m_pSSMutex   ;
+      QString           m_Id         ;
+      int               m_fpsC       ;
+      int               m_Fps        ;
+      QTime             m_CurrentTime;
 
       //Constants
       static const int TIMEOUT_SEC = 1; // 1 second
-- 
GitLab