diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fe167beb675d5b7c1017e7c95a9ae1bbbe8224c3..9ac8c87a745dca00665786d12810aa7a95b1f743 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -85,11 +85,12 @@ set( qtsflphone_LIB_SRCS
   contactmodel.cpp
   itembackendmodel.cpp
   video/videodevicemodel.cpp
+  video/sourcesmodel.cpp
   video/videocodecmodel.cpp
   video/videochannel.cpp
   video/videoresolution.cpp
   video/videorate.cpp
-  video/videomodel.cpp
+  video/videomanager.cpp
   audio/alsapluginmodel.cpp
   audio/codecmodel.cpp
   audio/inputdevicemodel.cpp
@@ -165,9 +166,10 @@ set( qtsflphone_LIB_HDRS
   abstractitembackendmodelextension.h
   video/videodevice.h
   video/videodevicemodel.h
+  video/sourcesmodel.h
   video/videocodec.h
   video/videocodecmodel.h
-  video/videomodel.h
+  video/videomanager.h
   video/videorenderer.h
   video/videoresolution.h
   video/videochannel.h
diff --git a/src/call.cpp b/src/call.cpp
index 75f7d325ff1de999ce696e87171357707e69ec85..69d3f0f4c3073404bf3a3feba141dcac91fcf7cd 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -36,7 +36,7 @@
 #include "uri.h"
 #include "account.h"
 #include "accountmodel.h"
-#include "video/videomodel.h"
+#include "video/videomanager.h"
 #include "historymodel.h"
 #include "instantmessagingmodel.h"
 #include "useractionmodel.h"
@@ -727,7 +727,7 @@ AbstractHistoryBackend* Call::backend() const
 bool Call::hasVideo() const
 {
    #ifdef ENABLE_VIDEO
-   return VideoModel::instance()->getRenderer(this) != nullptr;
+   return VideoManager::instance()->getRenderer(this) != nullptr;
    #else
    return false;
    #endif
@@ -786,7 +786,7 @@ bool Call::isSecure() const
 VideoRenderer* Call::videoRenderer() const
 {
    #ifdef ENABLE_VIDEO
-   return VideoModel::instance()->getRenderer(this);
+   return VideoManager::instance()->getRenderer(this);
    #else
    return nullptr;
    #endif
diff --git a/src/imconversationmanager.cpp b/src/imconversationmanager.cpp
index 7b13b90a3e4bbc06800ae477173d73fc2121c3b9..01dd9934bf893dc68059df19e677b61f5c47c96e 100644
--- a/src/imconversationmanager.cpp
+++ b/src/imconversationmanager.cpp
@@ -30,6 +30,7 @@ class IMConversationManagerPrivate : public QObject
 {
    Q_OBJECT
 public:
+   friend class Call;
    IMConversationManagerPrivate(IMConversationManager* parent);
 
    //Attributes
diff --git a/src/imconversationmanager.h b/src/imconversationmanager.h
index 22d45c0a992c639b257ca61020937bd52e424289..b25434a76ba0579048e86db406a8e670e9aa6d26 100644
--- a/src/imconversationmanager.h
+++ b/src/imconversationmanager.h
@@ -43,7 +43,7 @@ public:
 private:
    //Constructor
    explicit IMConversationManager();
-   ~IMConversationManager();
+   virtual ~IMConversationManager();
 
    IMConversationManagerPrivate* d_ptr;
    Q_DECLARE_PRIVATE(IMConversationManager)
diff --git a/src/keyexchangemodel.cpp b/src/keyexchangemodel.cpp
index 8989061e068348b404912d2f2326c5bd3bd7faef..66449577625e6ebb3a566ff158296721e824a4c6 100644
--- a/src/keyexchangemodel.cpp
+++ b/src/keyexchangemodel.cpp
@@ -21,7 +21,15 @@
 
 #include "account.h"
 
-const TypedStateMachine< TypedStateMachine< bool , KeyExchangeModel::Type > , KeyExchangeModel::Options > KeyExchangeModel::availableOptions = {{
+class KeyExchangeModelPrivate
+{
+public:
+   KeyExchangeModelPrivate();
+   Account* m_pAccount;
+   static const TypedStateMachine< TypedStateMachine< bool , KeyExchangeModel::Type > , KeyExchangeModel::Options > availableOptions;
+};
+
+const TypedStateMachine< TypedStateMachine< bool , KeyExchangeModel::Type > , KeyExchangeModel::Options > KeyExchangeModelPrivate::availableOptions = {{
    /*                  */  /* ZRTP */ /* SDES */ /* NONE */
    /* RTP_FALLBACK     */ {{ false    , true     , false   }},
    /* DISPLAY_SAS      */ {{ true     , false    , false   }},
@@ -30,8 +38,20 @@ const TypedStateMachine< TypedStateMachine< bool , KeyExchangeModel::Type > , Ke
    /* DISPLAY_SAS_ONCE */ {{ true     , false    , false   }},
 }};
 
+KeyExchangeModelPrivate::KeyExchangeModelPrivate() : m_pAccount(nullptr)
+{
+}
+
 
-KeyExchangeModel::KeyExchangeModel(Account* account) : QAbstractListModel(account),m_pAccount(account) {}
+KeyExchangeModel::KeyExchangeModel(Account* account) : QAbstractListModel(account),d_ptr(new KeyExchangeModelPrivate())
+{
+   d_ptr->m_pAccount = account;
+}
+
+KeyExchangeModel::~KeyExchangeModel()
+{
+   delete d_ptr;
+}
 
 //Model functions
 QVariant KeyExchangeModel::data( const QModelIndex& index, int role) const
@@ -114,35 +134,35 @@ KeyExchangeModel::Type KeyExchangeModel::fromDaemonName(const QString& name)
 
 void KeyExchangeModel::enableSRTP(bool enable)
 {
-   if (enable && m_pAccount->keyExchange() == KeyExchangeModel::Type::NONE) {
-      m_pAccount->setKeyExchange(KeyExchangeModel::Type::ZRTP);
+   if (enable && d_ptr->m_pAccount->keyExchange() == KeyExchangeModel::Type::NONE) {
+      d_ptr->m_pAccount->setKeyExchange(KeyExchangeModel::Type::ZRTP);
    }
    else if (!enable) {
-      m_pAccount->setKeyExchange(KeyExchangeModel::Type::NONE);
+      d_ptr->m_pAccount->setKeyExchange(KeyExchangeModel::Type::NONE);
    }
 }
 
 bool KeyExchangeModel::isRtpFallbackEnabled() const
 {
-   return availableOptions[Options::RTP_FALLBACK][m_pAccount->keyExchange()];
+   return d_ptr->availableOptions[Options::RTP_FALLBACK][d_ptr->m_pAccount->keyExchange()];
 }
 
 bool KeyExchangeModel::isDisplaySASEnabled() const
 {
-   return availableOptions[Options::DISPLAY_SAS][m_pAccount->keyExchange()];
+   return d_ptr->availableOptions[Options::DISPLAY_SAS][d_ptr->m_pAccount->keyExchange()];
 }
 
 bool KeyExchangeModel::isDisplaySasOnce() const
 {
-   return availableOptions[Options::DISPLAY_SAS_ONCE][m_pAccount->keyExchange()];
+   return d_ptr->availableOptions[Options::DISPLAY_SAS_ONCE][d_ptr->m_pAccount->keyExchange()];
 }
 
 bool KeyExchangeModel::areWarningSupressed() const
 {
-   return availableOptions[Options::NOT_SUPP_WARNING][m_pAccount->keyExchange()];
+   return d_ptr->availableOptions[Options::NOT_SUPP_WARNING][d_ptr->m_pAccount->keyExchange()];
 }
 
 bool KeyExchangeModel::isHelloHashEnabled() const
 {
-   return availableOptions[Options::HELLO_HASH][m_pAccount->keyExchange()];
+   return d_ptr->availableOptions[Options::HELLO_HASH][d_ptr->m_pAccount->keyExchange()];
 }
diff --git a/src/keyexchangemodel.h b/src/keyexchangemodel.h
index 8563c3e279757a573dd35ff16aa255d9cf30ca12..f511a11456a5935af64b4350733f00fc6c58505a 100644
--- a/src/keyexchangemodel.h
+++ b/src/keyexchangemodel.h
@@ -23,6 +23,8 @@
 
 class Account;
 
+class KeyExchangeModelPrivate;
+
 ///Static model for handling encryption types
 class LIB_EXPORT KeyExchangeModel : public QAbstractListModel {
    #pragma GCC diagnostic push
@@ -66,12 +68,13 @@ public:
 
    //Private constructor, can only be called by 'Account'
    explicit KeyExchangeModel(Account* account);
+   virtual ~KeyExchangeModel();
 
    //Model functions
-   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
-   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
-   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
-   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+   virtual QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   virtual int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool          setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
 
    //Getters
    QModelIndex                   toIndex       (KeyExchangeModel::Type type) const;
@@ -86,8 +89,7 @@ public:
 
 
 private:
-   Account* m_pAccount;
-   static const TypedStateMachine< TypedStateMachine< bool , KeyExchangeModel::Type > , KeyExchangeModel::Options > availableOptions;
+   KeyExchangeModelPrivate* d_ptr;
 
 public Q_SLOTS:
    void enableSRTP(bool enable);
diff --git a/src/lastusednumbermodel.h b/src/lastusednumbermodel.h
index 9efbe3a9ca0b2d45126123518bbf033bce202995..7c2d0f59d40007ec0b2cb0c15f0183fe414d0808 100644
--- a/src/lastusednumbermodel.h
+++ b/src/lastusednumbermodel.h
@@ -46,8 +46,8 @@ public:
 
 private:
    //Private constructor
-   LastUsedNumberModel();
-   ~LastUsedNumberModel();
+   explicit LastUsedNumberModel();
+   virtual ~LastUsedNumberModel();
 
    LastUsedNumberModelPrivate* d_ptr;
    Q_DECLARE_PRIVATE(LastUsedNumberModel)
diff --git a/src/numbercategory.cpp b/src/numbercategory.cpp
index e19ea85dd9993b7b2163e9548b329bef6cd36ada..11e7f061310bcabcbba2670d58b75adfbd2a8fdb 100644
--- a/src/numbercategory.cpp
+++ b/src/numbercategory.cpp
@@ -21,30 +21,45 @@
 
 #include "visitors/pixmapmanipulationvisitor.h"
 
+class NumberCategoryPrivate
+{
+public:
+   NumberCategoryPrivate();
+   //Attributes
+   QString m_Name;
+   QPixmap* m_pIcon;
+};
+
+NumberCategoryPrivate::NumberCategoryPrivate() : m_pIcon(nullptr), m_Name()
+{
+}
 
-NumberCategory::NumberCategory(QObject* parent, const QString& name) : QObject(parent), m_pIcon(nullptr),m_Name(name)
+NumberCategory::NumberCategory(QObject* parent, const QString& name) : QObject(parent), d_ptr(new NumberCategoryPrivate())
 {
+   d_ptr->m_Name = name;
 }
 
 NumberCategory::~NumberCategory()
-{}
+{
+   delete d_ptr;
+}
 
 QVariant NumberCategory::icon(bool isTracked, bool isPresent) const
 {
-   return PixmapManipulationVisitor::instance()->numberCategoryIcon(m_pIcon,QSize(),isTracked,isPresent);
+   return PixmapManipulationVisitor::instance()->numberCategoryIcon(d_ptr->m_pIcon,QSize(),isTracked,isPresent);
 }
 
 QString  NumberCategory::name() const
 {
-   return m_Name;
+   return d_ptr->m_Name;
 }
 
 void NumberCategory::setIcon(QPixmap*pixmap)
 {
-   m_pIcon = pixmap;
+   d_ptr->m_pIcon = pixmap;
 }
 
 void NumberCategory::setName(const QString& name)
 {
-   m_Name = name;
+   d_ptr->m_Name = name;
 }
diff --git a/src/numbercategory.h b/src/numbercategory.h
index d0ca8ed6deb4a9e7aa80660fa5ff9a6e0ed24bf0..c6a017c62ac7f05aa66b53bed415f7b343581cf6 100644
--- a/src/numbercategory.h
+++ b/src/numbercategory.h
@@ -23,6 +23,7 @@
 #include "typedefs.h"
 
 class QPixmap;
+class NumberCategoryPrivate;
 
 /**
  * This class represent a PhoneNumber category. Categories usually
@@ -45,9 +46,9 @@ private:
    NumberCategory(QObject* parent, const QString& name);
    virtual ~NumberCategory();
 
-   //Attributes
-   QString m_Name;
-   QPixmap* m_pIcon;
+   NumberCategoryPrivate* d_ptr;
+   Q_DECLARE_PRIVATE(NumberCategory)
+
 };
 
 #endif //NUMBERCATEGORY_H
diff --git a/src/numbercategorymodel.h b/src/numbercategorymodel.h
index ce78cd58a488b7c10727f10071084324f4c469e7..f05794a06a52a3332549c8f3d3f99e77b5d7be8b 100644
--- a/src/numbercategorymodel.h
+++ b/src/numbercategorymodel.h
@@ -38,9 +38,9 @@ public:
    };
 
    //Abstract model member
-   virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole ) const override;
-   virtual int rowCount(const QModelIndex& parent = QModelIndex()             ) const override;
-   virtual Qt::ItemFlags flags(const QModelIndex& index                       ) const override;
+   virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole    ) const override;
+   virtual int rowCount(const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags(const QModelIndex& index                          ) const override;
    virtual bool setData(const QModelIndex& index, const QVariant &value, int role) override;
 
    //Mutator
@@ -65,7 +65,6 @@ private:
    ~NumberCategoryModel();
 
    NumberCategoryModelPrivate* d_ptr;
-   Q_DECLARE_PRIVATE(NumberCategoryModel)
 
    //Singleton
    static NumberCategoryModel* m_spInstance;
diff --git a/src/private/videochannel_p.h b/src/private/videochannel_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..9993a6802100e7172dfb3640cab35fe4c2925f12
--- /dev/null
+++ b/src/private/videochannel_p.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ *   Copyright (C) 2014 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef VIDEOCHANNELPRIVATE_H
+#define VIDEOCHANNELPRIVATE_H
+
+class VideoChannelPrivate
+{
+public:
+   VideoChannelPrivate();
+   QString                 m_Name;
+   QList<VideoResolution*> m_lValidResolutions;
+   VideoResolution*        m_pCurrentResolution;
+   VideoDevice*            m_pDevice;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/private/videocodec_p.h b/src/private/videocodec_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4db32414492096f98862188a291aca56aaf84c8
--- /dev/null
+++ b/src/private/videocodec_p.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ *   Copyright (C) 2014 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef VIDEOCODECPRIVATE_H
+#define VIDEOCODECPRIVATE_H
+
+typedef QHash<QString,VideoCodec*> CodecHash;
+
+class VideoCodecPrivate
+{
+public:
+   VideoCodecPrivate();
+
+   //Consts
+   class CodecFields {
+   public:
+      constexpr static const char* PARAMETERS = "parameters";
+      constexpr static const char* ENABLED    = "enabled"   ;
+      constexpr static const char* BITRATE    = "bitrate"   ;
+      constexpr static const char* NAME       = "name"      ;
+   };
+
+   //Attributes
+   static CodecHash m_slCodecs  ;
+   QString          m_Name      ;
+   uint             m_Bitrate   ;
+   bool             m_Enabled   ;
+   static bool      m_sInit     ;
+   QString          m_Parameters;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/private/videodevice_p.h b/src/private/videodevice_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..4cbc417d4fab1ee64ac00722e9254603003be2ba
--- /dev/null
+++ b/src/private/videodevice_p.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ *   Copyright (C) 2014 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef VIDEODEVICEPRIVATE_H
+#define VIDEODEVICEPRIVATE_H
+
+class VideoDevicePrivate
+{
+public:
+   class PreferenceNames {
+   public:
+      constexpr static const char* RATE    = "rate"   ;
+      constexpr static const char* NAME    = "name"   ;
+      constexpr static const char* CHANNEL = "channel";
+      constexpr static const char* SIZE    = "size"   ;
+   };
+
+   VideoDevicePrivate();
+
+   //Attributes
+   QString              m_DeviceId       ;
+   VideoChannel*        m_pCurrentChannel;
+   QList<VideoChannel*> m_lChannels      ;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/uri.cpp b/src/uri.cpp
index d881a7ae6165a25a13913ea9bcc73b474c954e2f..4fb7b978dadcdb26505c709f329a02c6caf3cde8 100644
--- a/src/uri.cpp
+++ b/src/uri.cpp
@@ -19,32 +19,65 @@
 
 constexpr const char* URI::schemeNames[];
 
-URI::URI(const QString& other):QString()
-   ,m_Parsed(false),m_HeaderType(SchemeType::NONE)
+class UriPrivate
 {
-   m_Stripped                     = strip(other,m_HeaderType);
-   (*static_cast<QString*>(this)) = m_Stripped               ;
+public:
+   UriPrivate(QString* uri);
+   //Attributes
+   QString          m_Hostname    ;
+   QString          m_Userinfo    ;
+   QStringList      m_lAttributes ;
+   QString          m_Stripped    ;
+   URI::SchemeType  m_HeaderType  ;
+   bool             m_hasChevrons ;
+   bool             m_Parsed      ;
+
+   //Helper
+   static QString strip(const QString& uri, URI::SchemeType& sheme);
+   void parse();
+private:
+   QString* q_ptr;
+};
+
+UriPrivate::UriPrivate(QString* uri) : m_Parsed(false),m_HeaderType(URI::SchemeType::NONE),q_ptr(uri)
+{
+}
+
+URI::URI(const QString& other):QString(), d_ptr(new UriPrivate(this))
+{
+   d_ptr->m_Stripped              = UriPrivate::strip(other,d_ptr->m_HeaderType);
+   (*static_cast<QString*>(this)) = d_ptr->m_Stripped                           ;
+}
+
+URI::URI(const URI& o):QString(), d_ptr(new UriPrivate(this))
+{
+   d_ptr->m_Parsed     = o.d_ptr->m_Parsed    ;
+   d_ptr->m_Hostname   = o.d_ptr->m_Hostname  ;
+   d_ptr->m_HeaderType = o.d_ptr->m_HeaderType;
+   d_ptr->m_Userinfo   = o.d_ptr->m_Userinfo  ;
+   d_ptr->m_Stripped   = o.d_ptr->m_Stripped  ;
+
+   (*static_cast<QString*>(this)) = o.d_ptr->m_Stripped;
 }
 
-URI::URI(const URI& o):QString(),m_Parsed(o.m_Parsed),m_Hostname(o.m_Hostname),
-   m_HeaderType(o.m_HeaderType),m_Userinfo(o.m_Userinfo),m_Stripped(o.m_Stripped)
+URI::~URI()
 {
-   (*static_cast<QString*>(this)) = o.m_Stripped;
+   delete d_ptr;
 }
 
 ///Strip out <sip:****> from the URI
-QString URI::strip(const QString& uri, SchemeType& sheme)
+QString UriPrivate::strip(const QString& uri, URI::SchemeType& sheme)
 {
    if (uri.isEmpty())
       return QString();
    int start(0),end(uri.size()-1); //Other type of comparisons were too slow
    if (end > 5 && uri[0] == '<' ) {
       if (uri[4] == ':') {
-         sheme = uri[1] == 's'?SchemeType::SIP:SchemeType::IAX;
+         sheme = uri[1] == 's'?URI::SchemeType::SIP : URI::SchemeType::IAX;
          start = 5;
       }
       else if (uri[5] == ':') {
-         sheme = SchemeType::SIPS;
+         sheme = URI::SchemeType::SIPS;
          start = 6;
       }
    }
@@ -59,23 +92,23 @@ QString URI::strip(const QString& uri, SchemeType& sheme)
 ///Return the domaine of an URI (<sip:12345@example.com>)
 QString URI::hostname() const
 {
-   if (!m_Parsed)
-      const_cast<URI*>(this)->parse();
-   return m_Hostname;
+   if (!d_ptr->m_Parsed)
+      const_cast<URI*>(this)->d_ptr->parse();
+   return d_ptr->m_Hostname;
 }
 
 bool URI::hasHostname() const
 {
-   if (!m_Parsed)
-      const_cast<URI*>(this)->parse();
-   return !m_Hostname.isEmpty();
+   if (!d_ptr->m_Parsed)
+      const_cast<URI*>(this)->d_ptr->parse();
+   return !d_ptr->m_Hostname.isEmpty();
 }
 
 ///Keep a cache of the values to avoid re-parsing them
-void URI::parse()
+void UriPrivate::parse()
 {
-   if (indexOf('@') != -1) {
-      const QStringList splitted = split('@');
+   if (q_ptr->indexOf('@') != -1) {
+      const QStringList splitted = q_ptr->split('@');
       m_Hostname = splitted[1];//splitted[1].left(splitted[1].size())
       m_Userinfo = splitted[0];
       m_Parsed = true;
@@ -84,9 +117,9 @@ void URI::parse()
 
 QString URI::userinfo() const
 {
-   if (!m_Parsed)
-      const_cast<URI*>(this)->parse();
-   return m_Userinfo;
+   if (!d_ptr->m_Parsed)
+      const_cast<URI*>(this)->d_ptr->parse();
+   return d_ptr->m_Userinfo;
 }
 
 /**
@@ -95,6 +128,6 @@ QString URI::userinfo() const
 QString URI::fullUri() const
 {
    return QString("<%1%2>")
-      .arg(schemeNames[static_cast<int>(m_HeaderType == SchemeType::NONE?SchemeType::SIP:m_HeaderType)])
+      .arg(schemeNames[static_cast<int>(d_ptr->m_HeaderType == SchemeType::NONE?SchemeType::SIP:d_ptr->m_HeaderType)])
       .arg(*this);
 }
\ No newline at end of file
diff --git a/src/uri.h b/src/uri.h
index 152c635100ae73aad702493ef428cd24e69ab7a2..896274d26fb0c8b2d874036cf086440a61135166 100644
--- a/src/uri.h
+++ b/src/uri.h
@@ -22,6 +22,8 @@
 
 #include <QStringList>
 
+class UriPrivate;
+
 /**
     * @class URI A specialised string with multiple attributes
     * 
@@ -75,6 +77,7 @@ public:
     */
    URI(const QString& other);
    URI(const URI&     other);
+   virtual ~URI();
 
    ///@enum SchemeType The very first part of the URI followed by a ':'
    enum class SchemeType {
@@ -114,17 +117,7 @@ public:
    bool    hasHostname() const;
 
 private:
-   QString     m_Hostname    ;
-   QString     m_Userinfo    ;
-   QStringList m_lAttributes ;
-   QString     m_Stripped    ;
-   SchemeType  m_HeaderType  ;
-   bool        m_hasChevrons ;
-   bool        m_Parsed      ;
-
-   //Helper
-   static QString strip(const QString& uri, SchemeType& sheme);
-   void parse();
+   UriPrivate* d_ptr;
 };
 // Q_DECLARE_METATYPE(URI*)
 
diff --git a/src/useractionmodel.cpp b/src/useractionmodel.cpp
index 3724a5fb5ef174623238ef5dc7f92cf53b8cce12..988ad6d149606572d1c3f0c6df119c49cb67e6bc 100644
--- a/src/useractionmodel.cpp
+++ b/src/useractionmodel.cpp
@@ -19,8 +19,25 @@
 
 #include "call.h"
 
+class UserActionModelPrivate : public QObject
+{
+   Q_OBJECT
+public:
+   UserActionModelPrivate(UserActionModel* parent);
+   static const TypedStateMachine< TypedStateMachine< bool , Call::State > , UserActionModel::Action > availableActionMap;
+
+   //Attribues
+   Call* m_pCall;
+
+private:
+   UserActionModel* q_ptr;
+
+private Q_SLOTS:
+   void slotStateChanged();
+};
+
 //Enabled actions
-const TypedStateMachine< TypedStateMachine< bool , Call::State > , UserActionModel::Action > UserActionModel::availableActionMap = {{
+const TypedStateMachine< TypedStateMachine< bool , Call::State > , UserActionModel::Action > UserActionModelPrivate::availableActionMap = {{
             /* INCOMING  RINGING CURRENT DIALING  HOLD  FAILURE BUSY  TRANSFERRED TRANSF_HOLD  OVER  ERROR CONFERENCE CONFERENCE_HOLD:*/
  /*PICKUP   */ {{ true   , true ,  false,  false, false, false, false,   false,     false,    false, false,  false,      false    }},
  /*HOLD     */ {{ false  , false,  true ,  false, false, false, false,   true ,     false,    false, false,  true ,      false    }},
@@ -33,9 +50,19 @@ const TypedStateMachine< TypedStateMachine< bool , Call::State > , UserActionMod
  /*HANGUP   */ {{ false  , true ,  true ,  true , true , true , true ,   true ,     true ,    false, true ,  true ,      true     }},
 }};
 
-UserActionModel::UserActionModel(Call* parent) : QObject(parent),m_pCall(parent)
+UserActionModelPrivate::UserActionModelPrivate(UserActionModel* parent) : QObject(parent),q_ptr(parent),m_pCall(nullptr)
+{
+}
+
+UserActionModel::UserActionModel(Call* parent) : QObject(parent),d_ptr(new UserActionModelPrivate(this))
 {
    Q_ASSERT(parent != nullptr);
+   d_ptr->m_pCall = parent;
+}
+
+UserActionModel::~UserActionModel()
+{
+   
 }
 
 // QVariant UserActionModel::data(const QModelIndex& index, int role ) const
@@ -75,12 +102,12 @@ UserActionModel::UserActionModel(Call* parent) : QObject(parent),m_pCall(parent)
 
 bool UserActionModel::isActionEnabled( UserActionModel::Action action ) const
 {
-   return availableActionMap[action][m_pCall->state()];
+   return d_ptr->availableActionMap[action][d_ptr->m_pCall->state()];
 }
 
-void UserActionModel::slotStateChanged()
+void UserActionModelPrivate::slotStateChanged()
 {
-   emit actionStateChanged();
+   emit q_ptr->actionStateChanged();
 }
 
 
@@ -153,3 +180,5 @@ bool UserActionModel::isAcceptEnabled() const
 {
    return isActionEnabled(UserActionModel::Action::ACCEPT);
 }
+
+#include <useractionmodel.moc>
diff --git a/src/useractionmodel.h b/src/useractionmodel.h
index 781143124d0ad5ca1a640707d57267460ab5ae5f..2d8edb264fbfa3a5e759a3388169aab836b83c36 100644
--- a/src/useractionmodel.h
+++ b/src/useractionmodel.h
@@ -25,6 +25,7 @@
 #include "call.h"
 
 class Call;
+class UserActionModelPrivate;
 
 /**
  * @class UserActionModel Hold available actions for a given call state
@@ -71,6 +72,7 @@ public:
 
    //Constructor
    explicit UserActionModel(Call* parent);
+   virtual ~UserActionModel();
 
    //Abstract model members
 //    virtual QVariant      data       (const QModelIndex& index, int role = Qt::DisplayRole  ) const;
@@ -95,13 +97,8 @@ public:
    bool isAcceptEnabled  () const;
 
 private:
-   static const TypedStateMachine< TypedStateMachine< bool , Call::State > , UserActionModel::Action > availableActionMap;
-
-   //Attribues
-   Call* m_pCall;
-
-private Q_SLOTS:
-   void slotStateChanged();
+   UserActionModelPrivate* d_ptr;
+   Q_DECLARE_PRIVATE(UserActionModel)
 
 Q_SIGNALS:
    void actionStateChanged();
diff --git a/src/video/sourcesmodel.cpp b/src/video/sourcesmodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c0840a3d124b0c663422e90916816e4f5633c6c5
--- /dev/null
+++ b/src/video/sourcesmodel.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+ *   Copyright (C) 2014 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#include "sourcesmodel.h"
+#include <QtCore/QUrl>
+#include <QtCore/QCoreApplication>
+#include "../dbus/videomanager.h"
+#include "videodevicemodel.h"
+
+class VideoSourcesModelPrivate
+{
+public:
+   VideoSourcesModelPrivate();
+
+   //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() : rect(0,0,0,0),index(0){}
+      QRect rect;
+      int index ; /* X11 display ID, usually 0 */
+   };
+
+   QUrl m_CurrentFile;
+   Display m_Display;
+   int m_CurrentSelection;
+};
+
+VideoSourcesModelPrivate::VideoSourcesModelPrivate() : m_CurrentSelection(-1)
+{
+   
+}
+
+VideoSourcesModel* VideoSourcesModel::m_spInstance = nullptr;
+
+VideoSourcesModel::VideoSourcesModel() : QAbstractListModel(QCoreApplication::instance()),
+d_ptr(new VideoSourcesModelPrivate())
+{
+   d_ptr->m_Display.rect = QRect(0,0,0,0);
+}
+
+VideoSourcesModel* VideoSourcesModel::instance()
+{
+   if (!m_spInstance)
+      m_spInstance = new VideoSourcesModel();
+   return m_spInstance;
+}
+
+QVariant VideoSourcesModel::data( const QModelIndex& index, int role ) const
+{
+   switch (index.row()) {
+      case ExtendedDeviceList::NONE:
+         switch(role) {
+            case Qt::DisplayRole:
+               return tr("NONE");
+         };
+         break;
+      case ExtendedDeviceList::SCREEN:
+         switch(role) {
+            case Qt::DisplayRole:
+               return tr("SCREEN");
+         };
+         break;
+      case ExtendedDeviceList::FILE:
+         switch(role) {
+            case Qt::DisplayRole:
+               return tr("FILE");
+         };
+         break;
+      default:
+         return VideoDeviceModel::instance()->data(VideoDeviceModel::instance()->index(index.row()-ExtendedDeviceList::__COUNT,0),role);
+   };
+   return QVariant();
+}
+
+int VideoSourcesModel::rowCount( const QModelIndex& parent ) const
+{
+   Q_UNUSED(parent)
+   return VideoDeviceModel::instance()->rowCount() + ExtendedDeviceList::__COUNT;
+}
+
+Qt::ItemFlags VideoSourcesModel::flags( const QModelIndex& idx ) const
+{
+   switch (idx.row()) {
+      case ExtendedDeviceList::NONE  :
+      case ExtendedDeviceList::SCREEN:
+      case ExtendedDeviceList::FILE  :
+         return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+         break;
+      default:
+         return VideoDeviceModel::instance()->flags(VideoDeviceModel::instance()->index(idx.row()-ExtendedDeviceList::__COUNT,0));
+   };
+}
+
+bool VideoSourcesModel::setData( const QModelIndex& index, const QVariant &value, int role)
+{
+   Q_UNUSED(index)
+   Q_UNUSED(value)
+   Q_UNUSED(role)
+   return false;
+}
+
+void VideoSourcesModel::switchTo(const QModelIndex& idx)
+{
+   switchTo(idx.row());
+}
+
+///This model is designed for "live" switching rather than configuration
+void VideoSourcesModel::switchTo(const int idx)
+{
+   switch (idx) {
+      case ExtendedDeviceList::NONE:
+         DBus::VideoManager::instance().switchInput(VideoSourcesModelPrivate::ProtocolPrefix::NONE);
+         break;
+      case ExtendedDeviceList::SCREEN:
+         DBus::VideoManager::instance().switchInput( QString(VideoSourcesModelPrivate::ProtocolPrefix::DISPLAY)+QString(":%1 %2x%3")
+            .arg(d_ptr->m_Display.index)
+            .arg(d_ptr->m_Display.rect.width())
+            .arg(d_ptr->m_Display.rect.height()));
+         break;
+      case ExtendedDeviceList::FILE:
+         DBus::VideoManager::instance().switchInput(
+            !d_ptr->m_CurrentFile.isEmpty()?+VideoSourcesModelPrivate::ProtocolPrefix::FILE+d_ptr->m_CurrentFile.path():VideoSourcesModelPrivate::ProtocolPrefix::NONE
+         );
+         break;
+      default:
+         DBus::VideoManager::instance().switchInput(VideoSourcesModelPrivate::ProtocolPrefix::V4L2 +
+            VideoDeviceModel::instance()->index(idx-ExtendedDeviceList::__COUNT,0).data(Qt::DisplayRole).toString());
+         break;
+   };
+   d_ptr->m_CurrentSelection = (ExtendedDeviceList) idx;
+}
+
+void VideoSourcesModel::switchTo(VideoDevice* device)
+{
+   DBus::VideoManager::instance().switchInput(VideoSourcesModelPrivate::ProtocolPrefix::V4L2 + device->id());
+}
+
+VideoDevice* VideoSourcesModel::deviceAt(const QModelIndex& idx) const
+{
+   if (!idx.isValid()) return nullptr;
+   switch (idx.row()) {
+      case ExtendedDeviceList::NONE:
+      case ExtendedDeviceList::SCREEN:
+      case ExtendedDeviceList::FILE:
+         return nullptr;
+      default:
+         return VideoDeviceModel::instance()->devices()[idx.row()-ExtendedDeviceList::__COUNT];
+   };
+}
+
+int VideoSourcesModel::activeIndex() const
+{
+   if (d_ptr->m_CurrentSelection == -1) {
+      return ExtendedDeviceList::__COUNT + VideoDeviceModel::instance()->activeIndex();
+   }
+   return d_ptr->m_CurrentSelection;
+}
+
+void VideoSourcesModel::setFile(const QUrl& url)
+{
+   d_ptr->m_CurrentFile = url;
+   switchTo(ExtendedDeviceList::FILE);
+}
+
+void VideoSourcesModel::setDisplay(int index, QRect rect)
+{
+   d_ptr->m_Display.index  = index ;
+   d_ptr->m_Display.rect   = rect  ;
+   switchTo(ExtendedDeviceList::SCREEN);
+}
diff --git a/src/video/sourcesmodel.h b/src/video/sourcesmodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d152acf63584ca59c8169d16d7804cc7f6a9aa1
--- /dev/null
+++ b/src/video/sourcesmodel.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+ *   Copyright (C) 2014 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef VIDEOSOURCESMODEL_H
+#define VIDEOSOURCESMODEL_H
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QRect>
+#include "../typedefs.h"
+
+//SFLPhone
+class VideoDevice;
+
+class VideoSourcesModelPrivate;
+
+//TODO qt5, use QIdentityProxyModel
+class LIB_EXPORT VideoSourcesModel : public QAbstractListModel {
+   Q_OBJECT
+public:
+   enum ExtendedDeviceList {
+      NONE   ,
+      SCREEN ,
+      FILE   ,
+      __COUNT
+   };
+   virtual QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   virtual int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool          setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
+
+   VideoDevice* deviceAt(const QModelIndex& idx) const;
+
+   int activeIndex() const;
+
+   //Singleton
+   static VideoSourcesModel* instance();
+private:
+   explicit VideoSourcesModel();
+
+   VideoSourcesModelPrivate* d_ptr;
+   static VideoSourcesModel* m_spInstance;
+
+public Q_SLOTS:
+   void switchTo(const QModelIndex& idx);
+   void switchTo(const int idx);
+   void switchTo(VideoDevice* device);
+   void setFile(const QUrl& url);
+   void setDisplay(int index, QRect rect = QRect(0,0,0,0));
+};
+
+#endif
\ No newline at end of file
diff --git a/src/video/videochannel.cpp b/src/video/videochannel.cpp
index 63a7e05fb5e1635e0c1f7c592e201183f3db66cc..105de01b163cec95fba1db51723bfe98f4a06999 100644
--- a/src/video/videochannel.cpp
+++ b/src/video/videochannel.cpp
@@ -21,23 +21,36 @@
 #include "videoresolution.h"
 #include "videodevice.h"
 #include "../dbus/videomanager.h"
+#include "../private/videochannel_p.h"
+#include "../private/videodevice_p.h"
 
-VideoChannel::VideoChannel(VideoDevice* dev,const QString& name) :
-   m_Name(name),m_pCurrentResolution(nullptr),m_pDevice(dev)
+VideoChannelPrivate::VideoChannelPrivate() : m_pCurrentResolution(nullptr)
 {
 }
 
+VideoChannel::VideoChannel(VideoDevice* dev,const QString& name) : QAbstractListModel(dev),
+d_ptr(new VideoChannelPrivate())
+{
+   d_ptr->m_Name    = name;
+   d_ptr->m_pDevice = dev;
+}
+
+VideoChannel::~VideoChannel()
+{
+   delete d_ptr;
+}
+
 QVariant VideoChannel::data( const QModelIndex& index, int role) const
 {
    if (index.isValid() && role == Qt::DisplayRole) {
-      return m_lValidResolutions[index.row()]->name();
+      return d_ptr->m_lValidResolutions[index.row()]->name();
    }
    return QVariant();
 }
 
 int VideoChannel::rowCount( const QModelIndex& parent) const
 {
-   return (parent.isValid())?0:m_lValidResolutions.size();
+   return (parent.isValid())?0:d_ptr->m_lValidResolutions.size();
 }
 
 Qt::ItemFlags VideoChannel::flags( const QModelIndex& idx) const
@@ -56,57 +69,57 @@ bool VideoChannel::setData( const QModelIndex& index, const QVariant &value, int
 }
 
 int VideoChannel::relativeIndex() {
-   return m_pDevice->channelList().indexOf(this);
+   return d_ptr->m_pDevice->channelList().indexOf(this);
 }
 
 bool VideoChannel::setActiveResolution(int idx)
 {
-   if (idx < 0 || idx >= m_lValidResolutions.size()) return false;
-   return setActiveResolution(m_lValidResolutions[idx]);
+   if (idx < 0 || idx >= d_ptr->m_lValidResolutions.size()) return false;
+   return setActiveResolution(d_ptr->m_lValidResolutions[idx]);
 }
 
 bool VideoChannel::setActiveResolution(VideoResolution* res) {
-   if ((!res) || m_lValidResolutions.indexOf(res) == -1 || res->name().isEmpty()) {
+   if ((!res) || d_ptr->m_lValidResolutions.indexOf(res) == -1 || res->name().isEmpty()) {
       qWarning() << "Invalid active resolution" << (res?res->name():"NULL");
       return false;
    }
-   m_pCurrentResolution = res;
-   m_pDevice->save();
+   d_ptr->m_pCurrentResolution = res;
+   d_ptr->m_pDevice->save();
    return true;
 }
 
 VideoResolution* VideoChannel::activeResolution()
 {
    //If it is the current device, then there is "current" resolution
-   if ((!m_pCurrentResolution) && m_pDevice->isActive()) {
+   if ((!d_ptr->m_pCurrentResolution) && d_ptr->m_pDevice->isActive()) {
       VideoManagerInterface& interface = DBus::VideoManager::instance();
-      const QString res = QMap<QString,QString>(interface.getSettings(m_pDevice->id()))[VideoDevice::PreferenceNames::SIZE];
+      const QString res = QMap<QString,QString>(interface.getSettings(d_ptr->m_pDevice->id()))[VideoDevicePrivate::PreferenceNames::SIZE];
       foreach(VideoResolution* r, validResolutions()) {
          if (r->name() == res) {
-            m_pCurrentResolution = r;
+            d_ptr->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().first();
+   if (!d_ptr->m_pCurrentResolution && validResolutions().size()) {
+      d_ptr->m_pCurrentResolution = validResolutions().first();
    }
 
-   return m_pCurrentResolution;
+   return d_ptr->m_pCurrentResolution;
 }
 
 QString VideoChannel::name() const
 {
-   return m_Name;
+   return d_ptr->m_Name;
 }
 
 QList<VideoResolution*> VideoChannel::validResolutions() const
 {
-   return m_lValidResolutions;
+   return d_ptr->m_lValidResolutions;
 }
 VideoDevice* VideoChannel::device() const
 {
-   return m_pDevice;
+   return d_ptr->m_pDevice;
 }
 
diff --git a/src/video/videochannel.h b/src/video/videochannel.h
index d2fd35f706124fd351b5b7d02686e7bcbd54222d..6ebb72d52b2b95727439115492dab759189b8658 100644
--- a/src/video/videochannel.h
+++ b/src/video/videochannel.h
@@ -24,6 +24,8 @@
 class VideoResolution;
 class VideoDevice;
 
+class VideoChannelPrivate;
+
 ///@typedef VideoChannel A channel available in a Device
 class LIB_EXPORT VideoChannel : public QAbstractListModel
 {
@@ -40,18 +42,16 @@ public:
    bool setActiveResolution(int idx);
 
    //Model
-   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
-   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
-   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
-   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+   virtual QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   virtual int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool          setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
 
 private:
    VideoChannel(VideoDevice* dev,const QString& name);
-   virtual ~VideoChannel() {}
-   QString m_Name;
-   QList<VideoResolution*> m_lValidResolutions;
-   VideoResolution*        m_pCurrentResolution;
-   VideoDevice*       m_pDevice;
+   virtual ~VideoChannel();
+
+   VideoChannelPrivate* d_ptr;
 };
 
 #endif
diff --git a/src/video/videocodec.cpp b/src/video/videocodec.cpp
index be47abb6f730c10a8f3ce01e0f6324487f278b01..99ec95b64e8a1010135c08386c4e3a4a5a021240 100644
--- a/src/video/videocodec.cpp
+++ b/src/video/videocodec.cpp
@@ -16,68 +16,83 @@
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
  ***************************************************************************/
 #include "videocodec.h"
+#include "../private/videocodec_p.h"
 
 #include <account.h>
 
-QHash<QString,VideoCodec*> VideoCodec::m_slCodecs;
-bool VideoCodec::m_sInit = false;
+
+QHash<QString,VideoCodec*> VideoCodecPrivate::m_slCodecs;
+bool VideoCodecPrivate::m_sInit = false;
+
+VideoCodecPrivate::VideoCodecPrivate() : m_Enabled(false),m_Bitrate(0)
+{
+}
 
 ///Private constructor
-VideoCodec::VideoCodec(const QString &codecName, uint bitRate, bool enabled) : QObject(),
-m_Name(codecName),m_Bitrate(bitRate),m_Enabled(enabled)
+VideoCodec::VideoCodec(const QString &codecName, uint bitRate, bool enabled) : QObject(nullptr),
+d_ptr(new VideoCodecPrivate())
 {
+   d_ptr->m_Name    = codecName;
+   d_ptr->m_Bitrate = bitRate  ;
+   d_ptr->m_Enabled = enabled  ;
+
    setObjectName("VideoCodec"+codecName);
 }
 
+VideoCodec::~VideoCodec()
+{
+   delete d_ptr;
+}
+
 ///Get the current codec name
 QString VideoCodec::name() const
 {
-   return m_Name;
+   return d_ptr->m_Name;
 }
 
 ///Get the current codec id
 uint VideoCodec::bitrate() const
 {
-   return m_Bitrate;
+   return d_ptr->m_Bitrate;
 }
 
 ///Get the current codec id
 bool VideoCodec::isEnabled() const
 {
-   return m_Enabled;
+   return d_ptr->m_Enabled;
 }
 
 ///Set the codec bitrate
 void VideoCodec::setBitrate(const uint bitrate)
 {
-   m_Bitrate = bitrate;
+   d_ptr->m_Bitrate = bitrate;
 }
 
 ///Set if the codec is enabled
 void VideoCodec::setEnabled(const bool enabled)
 {
-   m_Enabled = enabled;
+   d_ptr->m_Enabled = enabled;
 }
 
 ///Set codec parameters
 void VideoCodec::setParamaters(const QString& params )
 {
-   m_Parameters = params;
+   d_ptr->m_Parameters = params;
 }
 
 ///Get codec parameters
 QString VideoCodec::parameters() const
 {
-   return m_Parameters;
+   return d_ptr->m_Parameters;
 }
 
 ///Generate a daemon compatible codec representation
 QMap<QString,QString> VideoCodec::toMap() const
 {
    QMap<QString,QString> ret;
-   ret[CodecFields::ENABLED    ] = isEnabled ()?"true":"false";
-   ret[CodecFields::BITRATE    ] = QString::number(bitrate());
-   ret[CodecFields::NAME       ] = name      ();
-   ret[CodecFields::PARAMETERS ] = parameters();
+   ret[VideoCodecPrivate::CodecFields::ENABLED    ] = isEnabled ()?"true":"false";
+   ret[VideoCodecPrivate::CodecFields::BITRATE    ] = QString::number(bitrate());
+   ret[VideoCodecPrivate::CodecFields::NAME       ] = name      ();
+   ret[VideoCodecPrivate::CodecFields::PARAMETERS ] = parameters();
    return ret;
 }
diff --git a/src/video/videocodec.h b/src/video/videocodec.h
index 1b460ef71accdd6df5a87412d7b4b2893f09be71..4600d963a5e7cbb71b8b402782d18fa65125ebd2 100644
--- a/src/video/videocodec.h
+++ b/src/video/videocodec.h
@@ -24,7 +24,7 @@
 class Account;
 class VideoCodec;
 
-typedef QHash<QString,VideoCodec*> CodecHash;
+class VideoCodecPrivate;
 
 ///VideoCodec: Codecs used for video calls
 class LIB_EXPORT VideoCodec : public QObject {
@@ -37,15 +37,6 @@ class LIB_EXPORT VideoCodec : public QObject {
       Q_PROPERTY(bool    enabled    READ isEnabled  WRITE setEnabled   )
       Q_PROPERTY(QString parameters READ parameters WRITE setParamaters)
 
-      //Consts
-      class CodecFields {
-      public:
-         constexpr static const char* PARAMETERS = "parameters";
-         constexpr static const char* ENABLED    = "enabled"   ;
-         constexpr static const char* BITRATE    = "bitrate"   ;
-         constexpr static const char* NAME       = "name"      ;
-      };
-
       //Static setters
       static void setActiveCodecList(Account* account, QStringList codecs);
 
@@ -64,15 +55,9 @@ class LIB_EXPORT VideoCodec : public QObject {
    private:
       //Constructor
       VideoCodec(const QString &codecName, uint bitRate, bool enabled);
-      ~VideoCodec(){}
+      virtual ~VideoCodec();
 
-      //Attributes
-      static CodecHash m_slCodecs;
-      QString          m_Name;
-      uint             m_Bitrate;
-      bool             m_Enabled;
-      static bool      m_sInit;
-      QString          m_Parameters;
+      VideoCodecPrivate* d_ptr;
 };
 
 #endif
diff --git a/src/video/videocodecmodel.cpp b/src/video/videocodecmodel.cpp
index b7fb1691726bc2537dfe5b85bd51e8cf2ac3fb23..ed68adc121217fd76f929cecf5486d9bee262dea 100644
--- a/src/video/videocodecmodel.cpp
+++ b/src/video/videocodecmodel.cpp
@@ -19,20 +19,41 @@
 #include <call.h>
 #include <account.h>
 #include <video/videocodec.h>
+#include "../private/videocodec_p.h"
 #include "../dbus/videomanager.h"
 
 #include <QtCore/QCoreApplication>
 
+class VideoCodecModelPrivate
+{
+public:
+   VideoCodecModelPrivate();
+
+   //Attrbutes
+   QList<VideoCodec*> m_lCodecs;
+   Account*           m_pAccount;
+};
+
+VideoCodecModelPrivate::VideoCodecModelPrivate() : m_pAccount(nullptr)
+{}
+
+///Constructor
+VideoCodecModel::VideoCodecModel(Account* account) : QAbstractListModel(QCoreApplication::instance()),d_ptr(new VideoCodecModelPrivate())
+{
+   d_ptr->m_pAccount = account;
+   reload();
+}
+
 ///Get data from the model
 QVariant VideoCodecModel::data( const QModelIndex& idx, int role) const
 {
    if(idx.column() == 0 && role == Qt::DisplayRole)
-      return QVariant(m_lCodecs[idx.row()]->name());
+      return QVariant(d_ptr->m_lCodecs[idx.row()]->name());
    else if(idx.column() == 0 && role == Qt::CheckStateRole) {
-      return QVariant(m_lCodecs[idx.row()]->isEnabled()?Qt::Checked:Qt::Unchecked);
+      return QVariant(d_ptr->m_lCodecs[idx.row()]->isEnabled()?Qt::Checked:Qt::Unchecked);
    }
    else if (idx.column() == 0 && role == VideoCodecModel::BITRATE_ROLE)
-      return QVariant(m_lCodecs[idx.row()]->bitrate());
+      return QVariant(d_ptr->m_lCodecs[idx.row()]->bitrate());
    return QVariant();
 }
 
@@ -40,7 +61,7 @@ QVariant VideoCodecModel::data( const QModelIndex& idx, int role) const
 int VideoCodecModel::rowCount( const QModelIndex& par ) const
 {
    Q_UNUSED(par)
-   return m_lCodecs.size();
+   return d_ptr->m_lCodecs.size();
 }
 
 ///Items flag
@@ -56,15 +77,15 @@ bool VideoCodecModel::setData(const QModelIndex& idx, const QVariant &value, int
 {
 
    if (idx.column() == 0 && role == Qt::CheckStateRole) {
-      bool changed = m_lCodecs[idx.row()]->isEnabled() != (value == Qt::Checked);
-      m_lCodecs[idx.row()]->setEnabled(value == Qt::Checked);
+      bool changed = d_ptr->m_lCodecs[idx.row()]->isEnabled() != (value == Qt::Checked);
+      d_ptr->m_lCodecs[idx.row()]->setEnabled(value == Qt::Checked);
       if (changed)
          emit dataChanged(idx, idx);
       return true;
    }
    else if (idx.column() == 0 && role == VideoCodecModel::BITRATE_ROLE) {
-      bool changed = m_lCodecs[idx.row()]->bitrate() != value.toUInt();
-      m_lCodecs[idx.row()]->setBitrate(value.toInt());
+      bool changed = d_ptr->m_lCodecs[idx.row()]->bitrate() != value.toUInt();
+      d_ptr->m_lCodecs[idx.row()]->setBitrate(value.toInt());
       if (changed)
          emit dataChanged(idx, idx);
       return true;
@@ -72,40 +93,35 @@ bool VideoCodecModel::setData(const QModelIndex& idx, const QVariant &value, int
    return false;
 }
 
-///Constructor
-VideoCodecModel::VideoCodecModel(Account* account) : QAbstractListModel(QCoreApplication::instance()),m_pAccount(account)
-{
-   reload();
-}
-
 ///Destructor
 VideoCodecModel::~VideoCodecModel()
 {
-   while (m_lCodecs.size()) {
-      VideoCodec* c = m_lCodecs[0];
-      m_lCodecs.removeAt(0);
+   while (d_ptr->m_lCodecs.size()) {
+      VideoCodec* c = d_ptr->m_lCodecs[0];
+      d_ptr->m_lCodecs.removeAt(0);
       delete c;
    }
+   delete d_ptr;
 }
 
 ///Force a model reload from dbus
 void VideoCodecModel::reload()
 {
-   while (m_lCodecs.size()) {
-      VideoCodec* c = m_lCodecs[0];
-      m_lCodecs.removeAt(0);
+   while (d_ptr->m_lCodecs.size()) {
+      VideoCodec* c = d_ptr->m_lCodecs[0];
+      d_ptr->m_lCodecs.removeAt(0);
       delete c;
    }
    VideoManagerInterface& interface = DBus::VideoManager::instance();
-   const VectorMapStringString codecs =  interface.getCodecs(m_pAccount->id());
+   const VectorMapStringString codecs =  interface.getCodecs(d_ptr->m_pAccount->id());
    foreach(const MapStringString& h,codecs) {
-      VideoCodec* c = new VideoCodec(h[VideoCodec::CodecFields::NAME],
-                                     h[VideoCodec::CodecFields::BITRATE].toInt(),
-                                     h[VideoCodec::CodecFields::ENABLED]=="true");
-      c->setParamaters(h[VideoCodec::CodecFields::PARAMETERS]);
-      m_lCodecs << c;
+      VideoCodec* c = new VideoCodec(h[VideoCodecPrivate::CodecFields::NAME],
+                                     h[VideoCodecPrivate::CodecFields::BITRATE].toInt(),
+                                     h[VideoCodecPrivate::CodecFields::ENABLED]=="true");
+      c->setParamaters(h[VideoCodecPrivate::CodecFields::PARAMETERS]);
+      d_ptr->m_lCodecs << c;
    }
-   emit dataChanged(index(0,0), index(m_lCodecs.size()-1,0));
+   emit dataChanged(index(0,0), index(d_ptr->m_lCodecs.size()-1,0));
 }
 
 ///Save the current model over dbus
@@ -113,19 +129,19 @@ void VideoCodecModel::save()
 {
    VideoManagerInterface& interface = DBus::VideoManager::instance();
    VectorMapStringString toSave;
-   foreach(VideoCodec* vc,m_lCodecs) {
+   foreach(VideoCodec* vc, d_ptr->m_lCodecs) {
       toSave << vc->toMap();
    }
-   interface.setCodecs(m_pAccount->id(),toSave);
+   interface.setCodecs(d_ptr->m_pAccount->id(),toSave);
 }
 
 ///Increase codec priority
 bool VideoCodecModel::moveUp(QModelIndex idx)
 {
    if(idx.row() > 0 && idx.row() <= rowCount()) {
-      VideoCodec* data2 = m_lCodecs[idx.row()];
-      m_lCodecs.removeAt(idx.row());
-      m_lCodecs.insert(idx.row() - 1, data2);
+      VideoCodec* data2 = d_ptr->m_lCodecs[idx.row()];
+      d_ptr->m_lCodecs.removeAt(idx.row());
+      d_ptr->m_lCodecs.insert(idx.row() - 1, data2);
       emit dataChanged(index(idx.row() - 1, 0, QModelIndex()), index(idx.row(), 0, QModelIndex()));
       return true;
    }
@@ -136,9 +152,9 @@ bool VideoCodecModel::moveUp(QModelIndex idx)
 bool VideoCodecModel::moveDown(QModelIndex idx)
 {
    if(idx.row() >= 0 && idx.row() < rowCount()) {
-      VideoCodec* data2 = m_lCodecs[idx.row()];
-      m_lCodecs.removeAt(idx.row());
-      m_lCodecs.insert(idx.row() + 1, data2);
+      VideoCodec* data2 = d_ptr->m_lCodecs[idx.row()];
+      d_ptr->m_lCodecs.removeAt(idx.row());
+      d_ptr->m_lCodecs.insert(idx.row() + 1, data2);
       emit dataChanged(index(idx.row(), 0, QModelIndex()), index(idx.row() + 1, 0, QModelIndex()));
       return true;
    }
diff --git a/src/video/videocodecmodel.h b/src/video/videocodecmodel.h
index fd7346c75e36b0b9d6d19d470832255176275e4c..8fee8bf41244b697a3d6ec02735574ba3c522853 100644
--- a/src/video/videocodecmodel.h
+++ b/src/video/videocodecmodel.h
@@ -30,6 +30,8 @@ class Account;
 class VideoCodec;
 typedef QHash<QString,VideoCodec*> CodecHash;
 
+class VideoCodecModelPrivate;
+
 ///Abstract model for managing account video codec list
 class LIB_EXPORT VideoCodecModel : public QAbstractListModel {
    #pragma GCC diagnostic push
@@ -40,16 +42,16 @@ class LIB_EXPORT VideoCodecModel : public QAbstractListModel {
 public:
    //Private constructor, can only be called by 'Account'
    explicit VideoCodecModel(Account* account = nullptr);
-   ~VideoCodecModel();
+   virtual ~VideoCodecModel();
 
    //Roles
    static const int BITRATE_ROLE = 101;
 
    //Model functions
-   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
-   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
-   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
-   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+   virtual QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   virtual int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool  setData          ( const QModelIndex& index, const QVariant &value, int role)       override;
 
    void reload();
    void save();
@@ -57,9 +59,8 @@ public:
    bool moveDown(QModelIndex idx);
 
 private:
-   //Attrbutes
-   QList<VideoCodec*> m_lCodecs;
-   Account*           m_pAccount;
+   VideoCodecModelPrivate* d_ptr;
+
 };
 Q_DECLARE_METATYPE(VideoCodecModel*)
 #endif
diff --git a/src/video/videodevice.cpp b/src/video/videodevice.cpp
index ecf7b1d48cddfea55aa17d3f604318d5f4f53d35..c9899618d48f9e2745bb1b4c724f893a63201f1a 100644
--- a/src/video/videodevice.cpp
+++ b/src/video/videodevice.cpp
@@ -17,15 +17,24 @@
  ***************************************************************************/
 #include "videodevice.h"
 #include "../dbus/videomanager.h"
+#include "../private/videochannel_p.h"
+#include "../private/videodevice_p.h"
 #include "videodevicemodel.h"
 #include "videoresolution.h"
 #include "videorate.h"
 #include "videochannel.h"
 
+
+
+VideoDevicePrivate::VideoDevicePrivate() : m_pCurrentChannel(nullptr)
+{
+}
+
 ///Constructor
-VideoDevice::VideoDevice(const QString &id) : QAbstractListModel(nullptr), m_DeviceId(id),
-m_pCurrentChannel(nullptr)
+VideoDevice::VideoDevice(const QString &id) : QAbstractListModel(nullptr),
+d_ptr(new VideoDevicePrivate())
 {
+   d_ptr->m_DeviceId = id;
    VideoManagerInterface& interface = DBus::VideoManager::instance();
    MapStringMapStringVectorString cap = interface.getCapabilities(id);
    QMapIterator<QString, MapStringVectorString> channels(cap);
@@ -33,14 +42,14 @@ m_pCurrentChannel(nullptr)
       channels.next();
 
       VideoChannel* chan = new VideoChannel(this,channels.key());
-      m_lChannels << chan;
+      d_ptr->m_lChannels << chan;
 
       QMapIterator<QString, VectorString> resolutions(channels.value());
       while (resolutions.hasNext()) {
          resolutions.next();
 
          VideoResolution* res = new VideoResolution(resolutions.key(),chan);
-         chan->m_lValidResolutions << res;
+         chan->d_ptr->m_lValidResolutions << res;
 
          foreach(const QString& rate, resolutions.value()) {
             VideoRate* r = new VideoRate(res,rate);
@@ -54,19 +63,20 @@ m_pCurrentChannel(nullptr)
 ///Destructor
 VideoDevice::~VideoDevice()
 {
+   delete d_ptr;
 }
 
 QVariant VideoDevice::data( const QModelIndex& index, int role) const
 {
    if (index.isValid() && role == Qt::DisplayRole) {
-      return m_lChannels[index.row()]->name();
+      return d_ptr->m_lChannels[index.row()]->name();
    }
    return QVariant();
 }
 
 int VideoDevice::rowCount( const QModelIndex& parent) const
 {
-   return (parent.isValid())?0:m_lChannels.size();
+   return (parent.isValid())?0:d_ptr->m_lChannels.size();
 }
 
 Qt::ItemFlags VideoDevice::flags( const QModelIndex& idx) const
@@ -91,7 +101,7 @@ bool VideoDevice::setData( const QModelIndex& index, const QVariant &value, int
 ///Get the valid channel list
 QList<VideoChannel*> VideoDevice::channelList() const
 {
-   return m_lChannels;
+   return d_ptr->m_lChannels;
 }
 
 ///Save the current settings
@@ -99,24 +109,24 @@ void VideoDevice::save()
 {
    //In case new (unsupported) fields are added, merge with existing
    VideoManagerInterface& interface = DBus::VideoManager::instance();
-   MapStringString pref = interface.getSettings(m_DeviceId);
-   pref[VideoDevice::PreferenceNames::CHANNEL] = activeChannel()->name();
-   pref[VideoDevice::PreferenceNames::SIZE   ] = activeChannel()->activeResolution()->name();
-   pref[VideoDevice::PreferenceNames::RATE   ] = activeChannel()->activeResolution()->activeRate()->name();
-   interface.applySettings(m_DeviceId,pref);
+   MapStringString pref = interface.getSettings(d_ptr->m_DeviceId);
+   pref[VideoDevicePrivate::PreferenceNames::CHANNEL] = activeChannel()->name();
+   pref[VideoDevicePrivate::PreferenceNames::SIZE   ] = activeChannel()->activeResolution()->name();
+   pref[VideoDevicePrivate::PreferenceNames::RATE   ] = activeChannel()->activeResolution()->activeRate()->name();
+   interface.applySettings(d_ptr->m_DeviceId,pref);
 }
 
 ///Get the device id
 const QString VideoDevice::id() const
 {
-   return m_DeviceId;
+   return d_ptr->m_DeviceId;
 }
 
 ///Get the device name
 const QString VideoDevice::name() const
 {
    VideoManagerInterface& interface = DBus::VideoManager::instance();
-   return QMap<QString,QString>(interface.getSettings(m_DeviceId))[PreferenceNames::NAME];;
+   return QMap<QString,QString>(interface.getSettings(d_ptr->m_DeviceId))[VideoDevicePrivate::PreferenceNames::NAME];;
 }
 
 ///Is this device the default one
@@ -127,35 +137,35 @@ bool VideoDevice::isActive() const
 
 bool VideoDevice::setActiveChannel(VideoChannel* chan)
 {
-   if (!chan || !m_lChannels.indexOf(chan)) {
+   if (!chan || !d_ptr->m_lChannels.indexOf(chan)) {
       qWarning() << "Trying to set an invalid channel" << (chan?chan->name():"NULL") << "for" << id();
       return false;
    }
-   m_pCurrentChannel = chan;
+   d_ptr->m_pCurrentChannel = chan;
    save();
    return true;
 }
 
 bool VideoDevice::setActiveChannel(int idx)
 {
-   if (idx < 0 || idx >= m_lChannels.size()) return false;
-   return setActiveChannel(m_lChannels[idx]);
+   if (idx < 0 || idx >= d_ptr->m_lChannels.size()) return false;
+   return setActiveChannel(d_ptr->m_lChannels[idx]);
 }
 
 VideoChannel* VideoDevice::activeChannel() const
 {
-   if (!m_pCurrentChannel) {
+   if (!d_ptr->m_pCurrentChannel) {
       VideoManagerInterface& interface = DBus::VideoManager::instance();
-      const QString chan = QMap<QString,QString>(interface.getSettings(m_DeviceId))[VideoDevice::PreferenceNames::CHANNEL];
-      foreach(VideoChannel* c, m_lChannels) {
+      const QString chan = QMap<QString,QString>(interface.getSettings(d_ptr->m_DeviceId))[VideoDevicePrivate::PreferenceNames::CHANNEL];
+      foreach(VideoChannel* c, d_ptr->m_lChannels) {
          if (c->name() == chan) {
-            const_cast<VideoDevice*>(this)->m_pCurrentChannel = c;
+            d_ptr->m_pCurrentChannel = c;
             break;
          }
       }
    }
-   if (!m_pCurrentChannel && m_lChannels.size()) {
-      const_cast<VideoDevice*>(this)->m_pCurrentChannel = m_lChannels[0];
+   if (!d_ptr->m_pCurrentChannel && d_ptr->m_lChannels.size()) {
+      d_ptr->m_pCurrentChannel = d_ptr->m_lChannels[0];
    }
-   return m_pCurrentChannel;
+   return d_ptr->m_pCurrentChannel;
 }
diff --git a/src/video/videodevice.h b/src/video/videodevice.h
index c2d0664da50ba32b77e0c67d8bf1236c3e161865..a85c9b7e81c5e1776b53d8d5bd4905e83e9cce0d 100644
--- a/src/video/videodevice.h
+++ b/src/video/videodevice.h
@@ -31,13 +31,15 @@ class VideoResolution;
 class VideoRate;
 class VideoChannel;
 class VideoDevice;
-
 class VideoModel;
 
+class VideoDevicePrivate;
+
 ///VideoDevice: V4L devices used to record video for video call
 class LIB_EXPORT VideoDevice : public QAbstractListModel {
    Q_OBJECT
-   friend class VideoModel;
+   friend class VideoManager;
+   friend class VideoManagerPrivate;
    friend class VideoDeviceModel;
 
    //Need to access the PreferenceNames table
@@ -45,14 +47,6 @@ class LIB_EXPORT VideoDevice : public QAbstractListModel {
    friend class Resolution;
    public:
 
-      class PreferenceNames {
-      public:
-         constexpr static const char* RATE    = "rate"   ;
-         constexpr static const char* NAME    = "name"   ;
-         constexpr static const char* CHANNEL = "channel";
-         constexpr static const char* SIZE    = "size"   ;
-      };
-
       //Constants
       constexpr static const char* NONE = "";
 
@@ -81,12 +75,10 @@ class LIB_EXPORT VideoDevice : public QAbstractListModel {
    private:
       //Constructor
       explicit VideoDevice(const QString &id);
-      ~VideoDevice();
+      virtual ~VideoDevice();
 
-      //Attributes
-      QString       m_DeviceId          ;
-      VideoChannel* m_pCurrentChannel   ;
-      QList<VideoChannel*> m_lChannels  ;
+      VideoDevicePrivate* d_ptr;
+      Q_DECLARE_PRIVATE(VideoDevice)
 
 
    Q_SIGNALS:
diff --git a/src/video/videodevicemodel.cpp b/src/video/videodevicemodel.cpp
index e31302e7ca0198d165925d4652f526a4c026bade..f612b707a08f0c6d74dda6f8b1224e54b9e953b3 100644
--- a/src/video/videodevicemodel.cpp
+++ b/src/video/videodevicemodel.cpp
@@ -26,6 +26,33 @@
 
 VideoDeviceModel* VideoDeviceModel::m_spInstance = nullptr;
 
+
+class VideoDeviceModelPrivate
+{
+public:
+   VideoDeviceModelPrivate();
+
+   //Attrbutes
+   QHash<QString,VideoDevice*> m_hDevices     ;
+   QList<VideoDevice*>         m_lDevices     ;
+   VideoDevice*                m_pDummyDevice ;
+   VideoDevice*                m_pActiveDevice;
+};
+
+
+VideoDeviceModelPrivate::VideoDeviceModelPrivate() : m_pDummyDevice(nullptr),m_pActiveDevice(nullptr)
+{
+   
+}
+
+///Constructor
+VideoDeviceModel::VideoDeviceModel() : QAbstractListModel(QCoreApplication::instance()),
+d_ptr(new VideoDeviceModelPrivate())
+{
+   m_spInstance = this;
+   reload();
+}
+
 VideoDeviceModel* VideoDeviceModel::instance()
 {
    if (!m_spInstance)
@@ -37,7 +64,7 @@ VideoDeviceModel* VideoDeviceModel::instance()
 QVariant VideoDeviceModel::data( const QModelIndex& idx, int role) const
 {
    if(idx.column() == 0 && role == Qt::DisplayRole)
-      return QVariant(m_lDevices[idx.row()]->id());
+      return QVariant(d_ptr->m_lDevices[idx.row()]->id());
    return QVariant();
 }
 
@@ -45,7 +72,7 @@ QVariant VideoDeviceModel::data( const QModelIndex& idx, int role) const
 int VideoDeviceModel::rowCount( const QModelIndex& par ) const
 {
    Q_UNUSED(par)
-   return m_lDevices.size();
+   return d_ptr->m_lDevices.size();
 }
 
 ///Items flag
@@ -65,22 +92,15 @@ bool VideoDeviceModel::setData(const QModelIndex& idx, const QVariant &value, in
    return false;
 }
 
-///Constructor
-VideoDeviceModel::VideoDeviceModel() : QAbstractListModel(QCoreApplication::instance()),
-m_pDummyDevice(nullptr),m_pActiveDevice(nullptr)
-{
-   m_spInstance = this;
-   reload();
-}
-
 ///Destructor
 VideoDeviceModel::~VideoDeviceModel()
 {
-   while (m_lDevices.size()) {
-      VideoDevice* c = m_lDevices[0];
-      m_lDevices.removeAt(0);
+   while (d_ptr->m_lDevices.size()) {
+      VideoDevice* c = d_ptr->m_lDevices[0];
+      d_ptr->m_lDevices.removeAt(0);
       delete c;
    }
+   delete d_ptr;
 }
 
 ///Save the current model over dbus
@@ -88,8 +108,8 @@ void VideoDeviceModel::setActive(const QModelIndex& idx)
 {
    if (idx.isValid()) {
       VideoManagerInterface& interface = DBus::VideoManager::instance();
-      interface.setDefaultDevice(m_lDevices[idx.row()]->id());
-      m_pActiveDevice = m_lDevices[idx.row()];
+      interface.setDefaultDevice(d_ptr->m_lDevices[idx.row()]->id());
+      d_ptr->m_pActiveDevice = d_ptr->m_lDevices[idx.row()];
       emit changed();
       emit currentIndexChanged(idx.row());
    }
@@ -107,9 +127,9 @@ void VideoDeviceModel::setActive(const VideoDevice* device)
    VideoManagerInterface& interface = DBus::VideoManager::instance();
 
    interface.setDefaultDevice(device?device->id():VideoDevice::NONE);
-   m_pActiveDevice = const_cast<VideoDevice*>(device);
+   d_ptr->m_pActiveDevice = const_cast<VideoDevice*>(device);
    emit changed();
-   const int idx = m_lDevices.indexOf((VideoDevice*)device);
+   const int idx = d_ptr->m_lDevices.indexOf((VideoDevice*)device);
    emit currentIndexChanged(idx);
 }
 
@@ -118,26 +138,26 @@ void VideoDeviceModel::reload()
    QHash<QString,VideoDevice*> devicesHash;
    VideoManagerInterface& interface = DBus::VideoManager::instance();
    const QStringList deviceList = interface.getDeviceList();
-   if (deviceList.size() == m_hDevices.size()) {
-      m_lDevices = m_hDevices.values();
+   if (deviceList.size() == d_ptr->m_hDevices.size()) {
+      d_ptr->m_lDevices = d_ptr->m_hDevices.values();
    }
 
    foreach(const QString& deviceName,deviceList) {
-      if (!m_hDevices[deviceName]) {
+      if (!d_ptr->m_hDevices[deviceName]) {
          devicesHash[deviceName] = new VideoDevice(deviceName);
       }
       else {
-         devicesHash[deviceName] = m_hDevices[deviceName];
+         devicesHash[deviceName] = d_ptr->m_hDevices[deviceName];
       }
    }
-   foreach(VideoDevice* dev,m_hDevices) {
+   foreach(VideoDevice* dev, d_ptr->m_hDevices) {
       if (dev && devicesHash.key(dev).isEmpty()) {
          delete dev;
       }
    }
-   m_hDevices.clear();
-   m_hDevices = devicesHash;
-   m_lDevices = m_hDevices.values();
+   d_ptr->m_hDevices.clear();
+   d_ptr->m_hDevices = devicesHash;
+   d_ptr->m_lDevices = d_ptr->m_hDevices.values();
 
    emit layoutChanged();
 //    channelModel   ()->reload();
@@ -147,182 +167,40 @@ void VideoDeviceModel::reload()
 
 VideoDevice* VideoDeviceModel::activeDevice() const
 {
-   if (!m_pActiveDevice) {
+   if (!d_ptr->m_pActiveDevice) {
       VideoManagerInterface& interface = DBus::VideoManager::instance();
       const QString deId = interface.getDefaultDevice();
-      if (!m_lDevices.size())
+      if (!d_ptr->m_lDevices.size())
          const_cast<VideoDeviceModel*>(this)->reload();
-      VideoDevice* dev =  m_hDevices[deId];
+      VideoDevice* dev =  d_ptr->m_hDevices[deId];
 
       //Handling null everywhere is too long, better create a dummy device and
       //log the event
       if (!dev) {
          if (!deId.isEmpty())
             qWarning() << "Requested unknown device" << deId;
-         if (!m_pDummyDevice)
-            const_cast<VideoDeviceModel*>(this)->m_pDummyDevice = new VideoDevice("None");
-         return m_pDummyDevice;
+         if (!d_ptr->m_pDummyDevice)
+            d_ptr->m_pDummyDevice = new VideoDevice("None");
+         return d_ptr->m_pDummyDevice;
       }
-      const_cast<VideoDeviceModel*>(this)->m_pActiveDevice = dev;
+      d_ptr->m_pActiveDevice = dev;
    }
-   return m_pActiveDevice;
+   return d_ptr->m_pActiveDevice;
 }
 
 
 int VideoDeviceModel::activeIndex() const
 {
-   return m_lDevices.indexOf(activeDevice());
-}
-
-
-// Extended Device list
-
-
-ExtendedVideoDeviceModel* ExtendedVideoDeviceModel::m_spInstance = nullptr;
-
-ExtendedVideoDeviceModel::ExtendedVideoDeviceModel() : QAbstractListModel(QCoreApplication::instance()),
-m_CurrentSelection(-1)
-{
-   m_Display.rect = QRect(0,0,0,0);
+   return d_ptr->m_lDevices.indexOf(activeDevice());
 }
 
-ExtendedVideoDeviceModel* ExtendedVideoDeviceModel::instance()
-{
-   if (!m_spInstance)
-      m_spInstance = new ExtendedVideoDeviceModel();
-   return m_spInstance;
-}
-
-QVariant ExtendedVideoDeviceModel::data( const QModelIndex& index, int role ) const
-{
-   switch (index.row()) {
-      case ExtendedDeviceList::NONE:
-         switch(role) {
-            case Qt::DisplayRole:
-               return tr("NONE");
-         };
-         break;
-      case ExtendedDeviceList::SCREEN:
-         switch(role) {
-            case Qt::DisplayRole:
-               return tr("SCREEN");
-         };
-         break;
-      case ExtendedDeviceList::FILE:
-         switch(role) {
-            case Qt::DisplayRole:
-               return tr("FILE");
-         };
-         break;
-      default:
-         return VideoDeviceModel::instance()->data(VideoDeviceModel::instance()->index(index.row()-ExtendedDeviceList::__COUNT,0),role);
-   };
-   return QVariant();
-}
-
-int ExtendedVideoDeviceModel::rowCount( const QModelIndex& parent ) const
-{
-   Q_UNUSED(parent)
-   return VideoDeviceModel::instance()->rowCount() + ExtendedDeviceList::__COUNT;
-}
-
-Qt::ItemFlags ExtendedVideoDeviceModel::flags( const QModelIndex& idx ) const
-{
-   switch (idx.row()) {
-      case ExtendedDeviceList::NONE  :
-      case ExtendedDeviceList::SCREEN:
-      case ExtendedDeviceList::FILE  :
-         return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
-         break;
-      default:
-         return VideoDeviceModel::instance()->flags(VideoDeviceModel::instance()->index(idx.row()-ExtendedDeviceList::__COUNT,0));
-   };
-}
-
-bool ExtendedVideoDeviceModel::setData( const QModelIndex& index, const QVariant &value, int role)
-{
-   Q_UNUSED(index)
-   Q_UNUSED(value)
-   Q_UNUSED(role)
-   return false;
-}
-
-void ExtendedVideoDeviceModel::switchTo(const QModelIndex& idx)
-{
-   switchTo(idx.row());
-}
-
-///This model is designed for "live" switching rather than configuration
-void ExtendedVideoDeviceModel::switchTo(const int idx)
-{
-   switch (idx) {
-      case ExtendedDeviceList::NONE:
-         DBus::VideoManager::instance().switchInput(ProtocolPrefix::NONE);
-         break;
-      case ExtendedDeviceList::SCREEN:
-         DBus::VideoManager::instance().switchInput( QString(ProtocolPrefix::DISPLAY)+QString(":%1 %2x%3")
-            .arg(m_Display.index)
-            .arg(m_Display.rect.width())
-            .arg(m_Display.rect.height()));
-         break;
-      case ExtendedDeviceList::FILE:
-         DBus::VideoManager::instance().switchInput(
-            !m_CurrentFile.isEmpty()?+ProtocolPrefix::FILE+m_CurrentFile.path():ProtocolPrefix::NONE
-         );
-         break;
-      default:
-         DBus::VideoManager::instance().switchInput(ProtocolPrefix::V4L2 +
-            VideoDeviceModel::instance()->index(idx-ExtendedDeviceList::__COUNT,0).data(Qt::DisplayRole).toString());
-         break;
-   };
-   m_CurrentSelection = (ExtendedDeviceList) idx;
-}
-
-void ExtendedVideoDeviceModel::switchTo(VideoDevice* device)
-{
-   DBus::VideoManager::instance().switchInput(ProtocolPrefix::V4L2 + device->id());
-}
-
-VideoDevice* ExtendedVideoDeviceModel::deviceAt(const QModelIndex& idx) const
-{
-   if (!idx.isValid()) return nullptr;
-   switch (idx.row()) {
-      case ExtendedDeviceList::NONE:
-      case ExtendedDeviceList::SCREEN:
-      case ExtendedDeviceList::FILE:
-         return nullptr;
-      default:
-         return VideoDeviceModel::instance()->devices()[idx.row()-ExtendedDeviceList::__COUNT];
-   };
-}
-
-int ExtendedVideoDeviceModel::activeIndex() const
-{
-   if (m_CurrentSelection == -1) {
-      return ExtendedDeviceList::__COUNT + VideoDeviceModel::instance()->activeIndex();
-   }
-   return m_CurrentSelection;
-}
-
-void ExtendedVideoDeviceModel::setFile(const QUrl& url)
-{
-   m_CurrentFile = url;
-   switchTo(ExtendedDeviceList::FILE);
-}
-
-void ExtendedVideoDeviceModel::setDisplay(int index, QRect rect)
-{
-   m_Display.index  = index ;
-   m_Display.rect   = rect  ;
-   switchTo(ExtendedDeviceList::SCREEN);
-}
 
 VideoDevice* VideoDeviceModel::getDevice(const QString& devId) const
 {
-   return m_hDevices[devId];
+   return d_ptr->m_hDevices[devId];
 }
 
 QList<VideoDevice*> VideoDeviceModel::devices() const
 {
-   return m_lDevices;
+   return d_ptr->m_lDevices;
 }
diff --git a/src/video/videodevicemodel.h b/src/video/videodevicemodel.h
index d50acff52da39c3ac9c7e757ee77f8cd6538cb87..0529ec7013e040d0034f151a0a364fcca410bab4 100644
--- a/src/video/videodevicemodel.h
+++ b/src/video/videodevicemodel.h
@@ -24,60 +24,10 @@
 #include <QtCore/QRect>
 #include "videodevice.h"
 
-//Qt
-
-//SFLPhone
-class VideoDevice;
 
-//TODO qt5, use QIdentityProxyModel
-class LIB_EXPORT ExtendedVideoDeviceModel : public QAbstractListModel {
-   Q_OBJECT
-public:
-   enum ExtendedDeviceList {
-      NONE   ,
-      SCREEN ,
-      FILE   ,
-      __COUNT
-   };
-   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
-   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
-   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
-   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
-
-   VideoDevice* deviceAt(const QModelIndex& idx) const;
-
-   int activeIndex() const;
-
-   //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() : rect(0,0,0,0),index(0){}
-      QRect rect;
-      int index ; /* X11 display ID, usually 0 */
-   };
-   explicit ExtendedVideoDeviceModel();
-   static ExtendedVideoDeviceModel* m_spInstance;
-   QUrl m_CurrentFile;
-   Display m_Display;
-   int m_CurrentSelection;
+//Qt
 
-public Q_SLOTS:
-   void switchTo(const QModelIndex& idx);
-   void switchTo(const int idx);
-   void switchTo(VideoDevice* device);
-   void setFile(const QUrl& url);
-   void setDisplay(int index, QRect rect = QRect(0,0,0,0));
-};
+class VideoDeviceModelPrivate;
 
 ///Abstract model for managing account video codec list
 class LIB_EXPORT VideoDeviceModel : public QAbstractListModel {
@@ -89,13 +39,13 @@ class LIB_EXPORT VideoDeviceModel : public QAbstractListModel {
 public:
    //Private constructor, can only be called by 'Account'
    explicit VideoDeviceModel();
-   ~VideoDeviceModel();
+   virtual ~VideoDeviceModel();
 
    //Model functions
-   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
-   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
-   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
-   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+   virtual QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   virtual int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool          setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
 
    static VideoDeviceModel* instance();
 
@@ -106,12 +56,8 @@ public:
    QList<VideoDevice*> devices() const;
 
 private:
-   //Attrbutes
-   QHash<QString,VideoDevice*> m_hDevices        ;
-   QList<VideoDevice*>         m_lDevices        ;
-   static VideoDeviceModel*    m_spInstance      ;
-   VideoDevice*                m_pDummyDevice    ;
-   VideoDevice*                m_pActiveDevice   ;
+   VideoDeviceModelPrivate* d_ptr;
+   static VideoDeviceModel* m_spInstance;
 
 public Q_SLOTS:
    void setActive(const QModelIndex& idx);
diff --git a/src/video/videomodel.cpp b/src/video/videomanager.cpp
similarity index 61%
rename from src/video/videomodel.cpp
rename to src/video/videomanager.cpp
index 493022c0030e0fa1cfe2bf20b63c0690690baa2c..a57aea596a50182b3d2b89b3b61408f1962c2115 100644
--- a/src/video/videomodel.cpp
+++ b/src/video/videomanager.cpp
@@ -15,7 +15,7 @@
  *   You should have received a copy of the GNU General Public License      *
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
  ***************************************************************************/
-#include "videomodel.h"
+#include "videomanager.h"
 
 //Qt
 #include <QtCore/QMutex>
@@ -32,90 +32,121 @@
 #include "videoresolution.h"
 
 //Static member
-VideoModel* VideoModel::m_spInstance = nullptr;
+VideoManager* VideoManager::m_spInstance = nullptr;
+
+class VideoManagerPrivate : public QObject
+{
+   Q_OBJECT
+
+public:
+   VideoManagerPrivate(VideoManager* parent);
+
+   //Attributes
+   bool           m_PreviewState;
+   uint           m_BufferSize  ;
+   uint           m_ShmKey      ;
+   uint           m_SemKey      ;
+   QMutex*        m_SSMutex     ;
+   QHash<QString,VideoRenderer*> m_lRenderers;
+
+private:
+   VideoManager* q_ptr;
+
+private Q_SLOTS:
+   void startedDecoding(const QString& id, const QString& shmPath, int width, int height);
+   void stoppedDecoding(const QString& id, const QString& shmPath);
+   void deviceEvent();
+
+};
+
+VideoManagerPrivate::VideoManagerPrivate(VideoManager* parent) : QObject(parent), q_ptr(parent),
+m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_SSMutex(new QMutex())
+{
+   
+}
 
 ///Constructor
-VideoModel::VideoModel():QThread(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_SSMutex(new QMutex())
+VideoManager::VideoManager():QThread(), d_ptr(new VideoManagerPrivate(this))
 {
    VideoManagerInterface& interface = DBus::VideoManager::instance();
-   connect( &interface , SIGNAL(deviceEvent())                           , this, SLOT(deviceEvent())                           );
-   connect( &interface , SIGNAL(startedDecoding(QString,QString,int,int,bool)), this, SLOT(startedDecoding(QString,QString,int,int)));
-   connect( &interface , SIGNAL(stoppedDecoding(QString,QString,bool))        , this, SLOT(stoppedDecoding(QString,QString))        );
+   connect( &interface , SIGNAL(deviceEvent())                           , d_ptr, SLOT(deviceEvent())                           );
+   connect( &interface , SIGNAL(startedDecoding(QString,QString,int,int,bool)), d_ptr, SLOT(startedDecoding(QString,QString,int,int)));
+   connect( &interface , SIGNAL(stoppedDecoding(QString,QString,bool))        , d_ptr, SLOT(stoppedDecoding(QString,QString))        );
 }
 
 
-VideoModel::~VideoModel()
+VideoManager::~VideoManager()
 {
-
+   delete d_ptr;
 }
 
 ///Singleton
-VideoModel* VideoModel::instance()
+VideoManager* VideoManager::instance()
 {
    if (!m_spInstance) {
-      m_spInstance = new VideoModel();
+      m_spInstance = new VideoManager();
    }
    return m_spInstance;
 }
 
 ///Return the call renderer or nullptr
-VideoRenderer* VideoModel::getRenderer(const Call* call) const
+VideoRenderer* VideoManager::getRenderer(const Call* call) const
 {
    if (!call) return nullptr;
-   return m_lRenderers[call->id()];
+   return d_ptr->m_lRenderers[call->id()];
 }
 
 ///Get the video preview renderer
-VideoRenderer* VideoModel::previewRenderer()
+VideoRenderer* VideoManager::previewRenderer()
 {
-   if (!m_lRenderers["local"]) {
+   if (!d_ptr->m_lRenderers["local"]) {
       VideoResolution* res = VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution();
       if (!res) {
          qWarning() << "Misconfigured video device";
          return nullptr;
       }
-      m_lRenderers["local"] = new VideoRenderer("local","",res->size());
+      d_ptr->m_lRenderers["local"] = new VideoRenderer("local","",res->size());
    }
-   return m_lRenderers["local"];
+   return d_ptr->m_lRenderers["local"];
 }
 
 ///Stop video preview
-void VideoModel::stopPreview()
+void VideoManager::stopPreview()
 {
    VideoManagerInterface& interface = DBus::VideoManager::instance();
    interface.stopCamera();
-   m_PreviewState = false;
+   d_ptr->m_PreviewState = false;
 }
 
 ///Start video preview
-void VideoModel::startPreview()
+void VideoManager::startPreview()
 {
-   if (m_PreviewState) return;
+   if (d_ptr->m_PreviewState) return;
    VideoManagerInterface& interface = DBus::VideoManager::instance();
    interface.startCamera();
-   m_PreviewState = true;
+   d_ptr->m_PreviewState = true;
 }
 
 ///Is the video model fetching preview from a camera
-bool VideoModel::isPreviewing()
+bool VideoManager::isPreviewing()
 {
-   return m_PreviewState;
+   return d_ptr->m_PreviewState;
 }
 
 ///@todo Set the video buffer size
-void VideoModel::setBufferSize(uint size)
+void VideoManager::setBufferSize(uint size)
 {
-   m_BufferSize = size;
+   d_ptr->m_BufferSize = size;
 }
 
 ///Event callback
-void VideoModel::deviceEvent()
+void VideoManagerPrivate::deviceEvent()
 {
-   
+   //TODO is there anything useful to do?
 }
 
 ///A video is not being rendered
-void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int width, int height)
+void VideoManagerPrivate::startedDecoding(const QString& id, const QString& shmPath, int width, int height)
 {
    Q_UNUSED(id)
 
@@ -131,9 +162,9 @@ void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int
 
    if (m_lRenderers[id] == nullptr ) {
       m_lRenderers[id] = new VideoRenderer(id,shmPath,res);
-      m_lRenderers[id]->moveToThread(this);
-      if (!isRunning())
-         start();
+      m_lRenderers[id]->moveToThread(q_ptr);
+      if (!q_ptr->isRunning())
+         q_ptr->start();
    }
    else {
       VideoRenderer* renderer = m_lRenderers[id];
@@ -148,17 +179,17 @@ void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int
    }
    if (id != "local") {
       qDebug() << "Starting video for call" << id;
-      emit videoCallInitiated(m_lRenderers[id]);
+      emit q_ptr->videoCallInitiated(m_lRenderers[id]);
    }
    else {
       m_PreviewState = true;
-      emit previewStateChanged(true);
-      emit previewStarted(m_lRenderers[id]);
+      emit q_ptr->previewStateChanged(true);
+      emit q_ptr->previewStarted(m_lRenderers[id]);
    }
 }
 
 ///A video stopped being rendered
-void VideoModel::stoppedDecoding(const QString& id, const QString& shmPath)
+void VideoManagerPrivate::stoppedDecoding(const QString& id, const QString& shmPath)
 {
    Q_UNUSED(shmPath)
    VideoRenderer* r = m_lRenderers[id];
@@ -174,22 +205,23 @@ void VideoModel::stoppedDecoding(const QString& id, const QString& shmPath)
    }
    if (id == "local") {
       m_PreviewState = false;
-      emit previewStateChanged(false);
-      emit previewStopped(r);
+      emit q_ptr->previewStateChanged(false);
+      emit q_ptr->previewStopped(r);
    }
 //    r->mutex()->lock();
    m_lRenderers[id] = nullptr;
    delete r;
 }
 
-void VideoModel::switchDevice(const VideoDevice* device) const
+void VideoManager::switchDevice(const VideoDevice* device) const
 {
    VideoManagerInterface& interface = DBus::VideoManager::instance();
    interface.switchInput(device->id());
 }
 
-QMutex* VideoModel::startStopMutex() const
+QMutex* VideoManager::startStopMutex() const
 {
-   return m_SSMutex;
+   return d_ptr->m_SSMutex;
 }
 
+#include <videomanager.moc>
diff --git a/src/video/videomodel.h b/src/video/videomanager.h
similarity index 76%
rename from src/video/videomodel.h
rename to src/video/videomanager.h
index e94cc30a37285f96ef93749f4feaec82e10bc812..25e3e996732a4f2c3c87c34a665da5cd04dbf4c3 100644
--- a/src/video/videomodel.h
+++ b/src/video/videomanager.h
@@ -31,28 +31,26 @@ class Call;
 class QMutex;
 struct SHMHeader;
 
+class VideoManagerPrivate;
+
 ///VideoModel: Video event dispatcher
-class LIB_EXPORT VideoModel : public QThread {
+class LIB_EXPORT VideoManager : public QThread {
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
    Q_OBJECT
    #pragma GCC diagnostic pop
 public:
    //Singleton
-   static VideoModel* instance();
+   static VideoManager* instance();
 
    //Getters
    bool       isPreviewing       ();
    VideoRenderer* getRenderer(const Call* call) const;
    VideoRenderer* previewRenderer();
-//    QList<VideoDevice*> devices();
-//    VideoDevice* activeDevice() const;
-//    VideoDevice* device(const QString &id);
    QMutex* startStopMutex() const;
 
    //Setters
    void setBufferSize(uint size);
-//    void setActiveDevice(const VideoDevice* device);
    void switchDevice(const VideoDevice* device) const;
 
 protected:
@@ -60,30 +58,19 @@ protected:
 
 private:
    //Constructor
-   VideoModel();
-   ~VideoModel();
+   explicit VideoManager();
+   virtual ~VideoManager();
 
-   //Static attributes
-   static VideoModel* m_spInstance;
+   VideoManagerPrivate* d_ptr;
+   Q_DECLARE_PRIVATE(VideoManager)
 
-   //Attributes
-   bool           m_PreviewState;
-   uint           m_BufferSize  ;
-   uint           m_ShmKey      ;
-   uint           m_SemKey      ;
-   QMutex*        m_SSMutex     ;
-   QHash<QString,VideoRenderer*> m_lRenderers;
-//    QHash<QString,VideoDevice*>   m_hDevices  ;
+   //Static attributes
+   static VideoManager* m_spInstance;
 
 public Q_SLOTS:
    void stopPreview ();
    void startPreview();
 
-private Q_SLOTS:
-   void startedDecoding(const QString& id, const QString& shmPath, int width, int height);
-   void stoppedDecoding(const QString& id, const QString& shmPath);
-   void deviceEvent();
-
 Q_SIGNALS:
    ///Emitted when a new frame is ready
 //    void frameUpdated();
diff --git a/src/video/videorate.h b/src/video/videorate.h
index d6013b65119c92d2ee6e7905806c8f680529a4f9..e77307dc256f9707da61ae163674d7b3f2651f33 100644
--- a/src/video/videorate.h
+++ b/src/video/videorate.h
@@ -22,6 +22,12 @@
 
 class VideoResolution;
 
+// class VideoRatePrivate
+// {
+// public:
+//    
+// };
+
 ///@typedef VideoRate The rate for a device
 class LIB_EXPORT VideoRate
 {
diff --git a/src/video/videorenderer.cpp b/src/video/videorenderer.cpp
index c94e617acf923aaa1fb03da8c5f890d2f01641d1..cf1d18a1ac387739bff15bb39c759aec1b47b4bd 100644
--- a/src/video/videorenderer.cpp
+++ b/src/video/videorenderer.cpp
@@ -36,7 +36,7 @@
 #endif
 
 #include <QtCore/QTimer>
-#include "videomodel.h"
+#include "videomanager.h"
 #include "videoresolution.h"
 
 ///Shared memory object
@@ -131,7 +131,7 @@ bool VideoRendererPrivate::renderToBitmap()
       return false;
    }
 
-   if(!VideoModel::instance()->startStopMutex()->tryLock())
+   if(!VideoManager::instance()->startStopMutex()->tryLock())
       return false;
 
    // wait for a new buffer
@@ -163,7 +163,7 @@ bool VideoRendererPrivate::renderToBitmap()
 //             break;
 //       }
       if ((err < 0) || (!shmLock())) {
-         VideoModel::instance()->startStopMutex()->unlock();
+         VideoManager::instance()->startStopMutex()->unlock();
          return false;
       }
       usleep((1/60.0)*100);
@@ -171,7 +171,7 @@ bool VideoRendererPrivate::renderToBitmap()
 
    if (!q_ptr->resizeShm()) {
       qDebug() << "Could not resize shared memory";
-      VideoModel::instance()->startStopMutex()->unlock();
+      VideoManager::instance()->startStopMutex()->unlock();
       return false;
    }
 
@@ -183,7 +183,7 @@ bool VideoRendererPrivate::renderToBitmap()
    shmUnlock();
    m_FrameIdx = !m_FrameIdx;
 
-   VideoModel::instance()->startStopMutex()->unlock();
+   VideoManager::instance()->startStopMutex()->unlock();
    return true;
 #else
    return false;
@@ -310,7 +310,7 @@ void VideoRendererPrivate::timedEvents()
 ///Start the rendering loop
 void VideoRenderer::startRendering()
 {
-   VideoModel::instance()->startStopMutex()->lock();
+   VideoManager::instance()->startStopMutex()->lock();
    QMutexLocker locker(d_ptr->m_pMutex);
    startShm();
    if (!d_ptr->m_pTimer) {
@@ -329,13 +329,13 @@ void VideoRenderer::startRendering()
       qDebug() << "Timer already started!";
 
    d_ptr->m_isRendering = true;
-   VideoModel::instance()->startStopMutex()->unlock();
+   VideoManager::instance()->startStopMutex()->unlock();
 }
 
 ///Stop the rendering loop
 void VideoRenderer::stopRendering()
 {
-   VideoModel::instance()->startStopMutex()->lock();
+   VideoManager::instance()->startStopMutex()->lock();
    QMutexLocker locker(d_ptr->m_pMutex);
    d_ptr->m_isRendering = false;
    qDebug() << "Stopping rendering on" << d_ptr->m_Id;
@@ -343,7 +343,7 @@ void VideoRenderer::stopRendering()
       d_ptr->m_pTimer->stop();
    emit stopped();
    stopShm();
-   VideoModel::instance()->startStopMutex()->unlock();
+   VideoManager::instance()->startStopMutex()->unlock();
 }
 
 
diff --git a/src/video/videoresolution.cpp b/src/video/videoresolution.cpp
index 08187d5e43c73d52d1b8bbd4a22dc9d664c4c2c1..9e90330ebe3b44e1ef6a9cfa6e1d6abaf9b4418b 100644
--- a/src/video/videoresolution.cpp
+++ b/src/video/videoresolution.cpp
@@ -18,6 +18,7 @@
 #include "videoresolution.h"
 
 #include "../dbus/videomanager.h"
+#include "../private/videodevice_p.h"
 #include "videochannel.h"
 #include "videorate.h"
 #include "videodevice.h"
@@ -100,7 +101,7 @@ VideoRate* VideoResolution::activeRate()
    if (!m_pCurrentRate && m_pChannel && m_pChannel->device()->isActive()) {
       VideoManagerInterface& interface = DBus::VideoManager::instance();
       const QString rate = QMap<QString,QString>(
-         interface.getSettings(m_pChannel->device()->id()))[VideoDevice::PreferenceNames::RATE];
+         interface.getSettings(m_pChannel->device()->id()))[VideoDevicePrivate::PreferenceNames::RATE];
       foreach(VideoRate* r, m_lValidRates) {
          if (r->name() == rate) {
             m_pCurrentRate = r;
diff --git a/src/video/videoresolution.h b/src/video/videoresolution.h
index a950251f55c0096d1e9d88d448c15876e52a61e4..e4e4a09a8794828d7267d7889bba46733e933948 100644
--- a/src/video/videoresolution.h
+++ b/src/video/videoresolution.h
@@ -26,6 +26,12 @@ class VideoRate;
 class VideoChannel;
 class VideoDevice;
 
+// class VideoResolutionPrivate
+// {
+// public:
+//    
+// };
+
 ///@struct VideoResolution Equivalent of "640x480"
 class LIB_EXPORT VideoResolution : public QAbstractListModel {
    Q_OBJECT
@@ -52,10 +58,10 @@ public:
    void setHeight(int height);
 
    //Model
-   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
-   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
-   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
-   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+   virtual QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   virtual int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool          setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
 
 
 private: