diff --git a/src/conference.cpp b/src/conference.cpp
index 81911aa214777fd2c09c887837eb73403fa85fc4..5054a2f7e1590e13ede037ae2a1d411f3bd64f23 100644
--- a/src/conference.cpp
+++ b/src/conference.cpp
@@ -200,11 +200,13 @@ Conference::~Conference()
         if (call->isPeerRecording())
             call->peerRecording(true);
     });
-    for (auto it = confSinksMap_.begin(); it != confSinksMap_.end();) {
-        if (videoMixer_)
-            videoMixer_->detach(it->second.get());
-        it->second->stop();
-        it = confSinksMap_.erase(it);
+    if (videoMixer_) {
+        auto& sink = videoMixer_->getSink();
+        for (auto it = confSinksMap_.begin(); it != confSinksMap_.end();) {
+            sink->detach(it->second.get());
+            it->second->stop();
+            it = confSinksMap_.erase(it);
+        }
     }
 #endif // ENABLE_VIDEO
 #ifdef ENABLE_PLUGIN
@@ -761,11 +763,11 @@ Conference::createSinks(const ConfInfo& infos)
     std::lock_guard<std::mutex> lk(sinksMtx_);
     if (!videoMixer_)
         return;
-
+    auto& sink = videoMixer_->getSink();
     Manager::instance().createSinkClients(getConfId(),
                                           infos,
-                                          std::static_pointer_cast<video::VideoGenerator>(
-                                              videoMixer_),
+                                          std::static_pointer_cast<video::VideoFrameActiveWriter>(
+                                              sink),
                                           confSinksMap_);
 }
 
diff --git a/src/manager.cpp b/src/manager.cpp
index 8787b5748fd332617fbc9f1f30a57226fadedef1..b07364e482b9a456d7988d0b5ecf68d0c3b34953 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -3031,7 +3031,7 @@ Manager::createSinkClient(const std::string& id, bool mixer)
 void
 Manager::createSinkClients(const std::string& callId,
                            const ConfInfo& infos,
-                           const std::shared_ptr<video::VideoGenerator>& videoStream,
+                           const std::shared_ptr<video::VideoFrameActiveWriter>& videoStream,
                            std::map<std::string, std::shared_ptr<video::SinkClient>>& sinksMap)
 {
     std::lock_guard<std::mutex> lk(pimpl_->sinksMutex_);
@@ -3048,7 +3048,6 @@ Manager::createSinkClients(const std::string& callId,
             auto currentSink = getSinkClient(sinkId);
             if (currentSink) {
                 currentSink->setCrop(participant.x, participant.y, participant.w, participant.h);
-                currentSink->setFrameSize(participant.w, participant.h);
                 sinkIdsList.emplace(sinkId);
                 continue;
             }
diff --git a/src/manager.h b/src/manager.h
index 5956feb7c5c22ce19f82c491cbcda54d4419b204..f560e570fe767391f696d8cdedab7c4d324a56f2 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -810,12 +810,12 @@ public:
      * cache as a weak_ptr and populates sinksMap with sink ids and shared_ptrs.
      * @param callId
      * @param infos ConferenceInfos that will create the sinks
-     * @param videoStream the the VideoGenerator to with the sinks should be attached
+     * @param videoStream the the VideoFrameActiveWriter to which the sinks should be attached
      * @param sinksMap A map between sink ids and the respective shared pointer.
      */
     void createSinkClients(const std::string& callId,
                            const ConfInfo& infos,
-                           const std::shared_ptr<video::VideoGenerator>& videoStream,
+                           const std::shared_ptr<video::VideoFrameActiveWriter>& videoStream,
                            std::map<std::string, std::shared_ptr<video::SinkClient>>& sinksMap);
 
     /**
diff --git a/src/media/video/sinkclient.cpp b/src/media/video/sinkclient.cpp
index 4391faa39c5123074ec62c0bd09f98d20fe12e03..4dcbf2bba5b10472b83ca89a774e43de0917a08f 100644
--- a/src/media/video/sinkclient.cpp
+++ b/src/media/video/sinkclient.cpp
@@ -369,6 +369,7 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/,
             setFrameSize(outFrame->width(), outFrame->height());
             return;
         }
+        notify(std::static_pointer_cast<MediaFrame>(frame_p));
         avTarget_.push(std::move(outFrame));
         return;
     }
@@ -382,7 +383,7 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/,
         std::shared_ptr<VideoFrame> frame = std::make_shared<VideoFrame>();
 #ifdef RING_ACCEL
         auto desc = av_pix_fmt_desc_get(
-            (AVPixelFormat) (std::static_pointer_cast<VideoFrame>(frame_p))->format());
+            (AVPixelFormat)(std::static_pointer_cast<VideoFrame>(frame_p))->format());
         if (desc && (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
             try {
                 frame = HardwareAccel::transferToMainMemory(*std::static_pointer_cast<VideoFrame>(
@@ -414,6 +415,7 @@ SinkClient::update(Observable<std::shared_ptr<MediaFrame>>* /*obs*/,
             frame = std::static_pointer_cast<VideoFrame>(
                 std::shared_ptr<MediaFrame>(filter_->readOutput()));
         }
+        notify(std::static_pointer_cast<MediaFrame>(frame));
 
         if (crop_.w || crop_.h) {
             frame->pointer()->crop_top = crop_.y;
diff --git a/src/media/video/sinkclient.h b/src/media/video/sinkclient.h
index 67cf65feeee0d1edd91565cb184e2def63e11bcf..f97b7fda9c3ea229d3b37feb7208405cc763fbeb 100644
--- a/src/media/video/sinkclient.h
+++ b/src/media/video/sinkclient.h
@@ -48,12 +48,12 @@ class ShmHolder;
 
 class VideoScaler;
 
-class SinkClient : public VideoFramePassiveReader
+class SinkClient : public VideoFramePassiveReader, public VideoFrameActiveWriter
 {
 public:
     SinkClient(const std::string& id = "", bool mixer = false);
 
-    const std::string& getId() const noexcept {return id_;}
+    const std::string& getId() const noexcept { return id_; }
 
     std::string openedName() const noexcept;
 
@@ -76,7 +76,8 @@ public:
     void setFrameSize(int width, int height);
     void setCrop(int x, int y, int w, int h);
 
-    void registerTarget(const DRing::SinkTarget& target) noexcept {
+    void registerTarget(const DRing::SinkTarget& target) noexcept
+    {
         std::lock_guard<std::mutex> lock(mtx_);
         target_ = target;
     }
@@ -93,7 +94,10 @@ private:
     int width_ {0};
     int height_ {0};
 
-    struct Rect { int x {0}, y {0}, w {0}, h {0}; };
+    struct Rect
+    {
+        int x {0}, y {0}, w {0}, h {0};
+    };
     Rect crop_ {};
 
     bool started_ {false}; // used to arbitrate client's stop signal.
diff --git a/src/media/video/video_mixer.h b/src/media/video/video_mixer.h
index a39b9fff242c592e26f7ee7bb23bc34a4c851132..591f4d09210dce488dfa1dd12127d811f61e811f 100644
--- a/src/media/video/video_mixer.h
+++ b/src/media/video/video_mixer.h
@@ -91,6 +91,8 @@ public:
 
     void updateLayout();
 
+    std::shared_ptr<SinkClient>& getSink() { return sink_; }
+
 private:
     NON_COPYABLE(VideoMixer);
     struct VideoMixerSource;
diff --git a/src/media/video/video_receive_thread.h b/src/media/video/video_receive_thread.h
index 0f40bd1dece4b9fa93eef9b7b3ec8e62ba23dad9..c4b156c6839069ee846bf0469d3d3376705322f7 100644
--- a/src/media/video/video_receive_thread.h
+++ b/src/media/video/video_receive_thread.h
@@ -65,6 +65,7 @@ public:
     };
     void startSink();
     void stopSink();
+    std::shared_ptr<SinkClient>& getSink() { return sink_; }
 
     // as VideoGenerator
     int getWidth() const;
diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index eb8931ae980b0baa7612fe60691be745cee8af94..70cd5b24c2fa4e21307671a335f7cc749d09b206 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -2150,14 +2150,15 @@ SIPCall::stopAllMedia()
 
     {
         std::lock_guard<std::mutex> lk(sinksMtx_);
-        for (auto it = callSinksMap_.begin(); it != callSinksMap_.end();) {
-            auto& videoReceive = videoRtp->getVideoReceive();
-            if (videoReceive) {
-                videoReceive->detach(it->second.get());
+        auto& videoReceive = videoRtp->getVideoReceive();
+        if (videoReceive) {
+            auto& sink = videoReceive->getSink();
+            for (auto it = callSinksMap_.begin(); it != callSinksMap_.end();) {
+                sink->detach(it->second.get());
+
+                it->second->stop();
+                it = callSinksMap_.erase(it);
             }
-
-            it->second->stop();
-            it = callSinksMap_.erase(it);
         }
     }
 
@@ -3019,12 +3020,13 @@ SIPCall::createSinks(const ConfInfo& infos)
     auto& videoReceive = videoRtp->getVideoReceive();
     if (!videoReceive)
         return;
+    auto& sink = videoReceive->getSink();
     auto conf = conf_.lock();
     const auto& id = conf ? conf->getConfId() : getCallId();
     Manager::instance().createSinkClients(id,
                                           infos,
-                                          std::static_pointer_cast<video::VideoGenerator>(
-                                              videoReceive),
+                                          std::static_pointer_cast<video::VideoFrameActiveWriter>(
+                                              sink),
                                           callSinksMap_);
 }
 #endif