diff --git a/src/media/video/video_base.h b/src/media/video/video_base.h
index 8babcad8e41426091f64fdacc6853f294970793d..6954d1aac704f0b69df4a00bfa0ec295da0f687c 100644
--- a/src/media/video/video_base.h
+++ b/src/media/video/video_base.h
@@ -22,6 +22,7 @@
 #pragma once
 
 #include "noncopyable.h"
+#include "observer.h"
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -57,70 +58,6 @@ using VideoFrame = DRing::VideoFrame;
 
 namespace ring { namespace video {
 
-template <typename T> class Observer;
-template <typename T> class Observable;
-
-/*=== Observable =============================================================*/
-
-template <typename T>
-class Observable
-{
-public:
-    Observable() : observers_(), mutex_() {}
-    virtual ~Observable() {
-        std::lock_guard<std::mutex> lk(mutex_);
-        for (auto& o : observers_)
-            o->detached(this);
-    };
-
-    bool attach(Observer<T>* o) {
-        std::lock_guard<std::mutex> lk(mutex_);
-        if (o and observers_.insert(o).second) {
-            o->attached(this);
-            return true;
-        }
-        return false;
-    }
-
-    bool detach(Observer<T>* o) {
-        std::lock_guard<std::mutex> lk(mutex_);
-        if (o and observers_.erase(o)) {
-            o->detached(this);
-            return true;
-        }
-        return false;
-    }
-
-    void notify(T data) {
-        std::lock_guard<std::mutex> lk(mutex_);
-        for (auto observer : observers_)
-            observer->update(this, data);
-    }
-
-    int getObserversCount() {
-        std::lock_guard<std::mutex> lk(mutex_);
-        return observers_.size();
-    }
-
-private:
-    NON_COPYABLE(Observable<T>);
-
-    std::set<Observer<T>*> observers_;
-    std::mutex mutex_; // lock observers_
-};
-
-/*=== Observer =============================================================*/
-
-template <typename T>
-class Observer
-{
-public:
-    virtual ~Observer() {};
-    virtual void update(Observable<T>*, const T&) = 0;
-    virtual void attached(Observable<T>*) {};
-    virtual void detached(Observable<T>*) {};
-};
-
 struct VideoFrameActiveWriter: Observable<std::shared_ptr<VideoFrame>> {};
 struct VideoFramePassiveReader: Observer<std::shared_ptr<VideoFrame>> {};
 
diff --git a/src/observer.h b/src/observer.h
new file mode 100644
index 0000000000000000000000000000000000000000..1ff089dd82fd19d69ebd63e1abfc6ac50d448bc0
--- /dev/null
+++ b/src/observer.h
@@ -0,0 +1,99 @@
+/*
+ *  Copyright (C) 2013-2018 Savoir-faire Linux Inc.
+ *
+ *  Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
+ *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#pragma once
+
+#include "noncopyable.h"
+
+#include <cstdlib>
+#include <cstdint>
+#include <memory>
+#include <set>
+#include <mutex>
+#include <ciso646> // fix windows compiler bug
+
+namespace ring {
+
+template <typename T> class Observer;
+template <typename T> class Observable;
+
+/*=== Observable =============================================================*/
+
+template <typename T>
+class Observable
+{
+public:
+    Observable() : observers_(), mutex_() {}
+    virtual ~Observable() {
+        std::lock_guard<std::mutex> lk(mutex_);
+        for (auto& o : observers_)
+            o->detached(this);
+    };
+
+    bool attach(Observer<T>* o) {
+        std::lock_guard<std::mutex> lk(mutex_);
+        if (o and observers_.insert(o).second) {
+            o->attached(this);
+            return true;
+        }
+        return false;
+    }
+
+    bool detach(Observer<T>* o) {
+        std::lock_guard<std::mutex> lk(mutex_);
+        if (o and observers_.erase(o)) {
+            o->detached(this);
+            return true;
+        }
+        return false;
+    }
+
+    void notify(T data) {
+        std::lock_guard<std::mutex> lk(mutex_);
+        for (auto observer : observers_)
+            observer->update(this, data);
+    }
+
+    int getObserversCount() {
+        std::lock_guard<std::mutex> lk(mutex_);
+        return observers_.size();
+    }
+
+private:
+    NON_COPYABLE(Observable<T>);
+
+    std::set<Observer<T>*> observers_;
+    std::mutex mutex_; // lock observers_
+};
+
+/*=== Observer =============================================================*/
+
+template <typename T>
+class Observer
+{
+public:
+    virtual ~Observer() {};
+    virtual void update(Observable<T>*, const T&) = 0;
+    virtual void attached(Observable<T>*) {};
+    virtual void detached(Observable<T>*) {};
+};
+
+}; // namespace ring