diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp
index 894f4bde6d3c19c34f58ec53fc3130a6d8ed506b..65fe1888823d45faf508d0b3d9c415308a1120bd 100644
--- a/src/media/media_decoder.cpp
+++ b/src/media/media_decoder.cpp
@@ -532,6 +532,8 @@ MediaDecoder::prepareDecoderContext()
         return -1;
     }
     avcodec_parameters_to_context(decoderCtx_, avStream_->codecpar);
+    width_ = decoderCtx_->width;
+    height_ = decoderCtx_->height;
     decoderCtx_->framerate = avStream_->avg_frame_rate;
     if (avStream_->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
         if (decoderCtx_->framerate.num == 0 || decoderCtx_->framerate.den == 0)
@@ -579,6 +581,18 @@ MediaDecoder::decode(AVPacket& packet)
                  : std::static_pointer_cast<MediaFrame>(std::make_shared<AudioFrame>());
     auto frame = f->pointer();
     ret = avcodec_receive_frame(decoderCtx_, frame);
+    if (resolutionChangedCallback_) {
+        if (decoderCtx_->width != width_ or decoderCtx_->height != height_) {
+            JAMI_DBG("Resolution changed from %dx%d to %dx%d",
+                width_,
+                height_,
+                decoderCtx_->width,
+                decoderCtx_->height);
+            width_ = decoderCtx_->width;
+            height_ = decoderCtx_->height;
+            resolutionChangedCallback_(width_, height_);
+        }
+    }
     if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
         return DecodeStatus::DecodeError;
     }
diff --git a/src/media/media_decoder.h b/src/media/media_decoder.h
index 826a9ab10bc7981b84fa64116c6fca957227ff45..64c4047b7c41fdc0eff269e23ece0f048a17961d 100644
--- a/src/media/media_decoder.h
+++ b/src/media/media_decoder.h
@@ -191,6 +191,8 @@ public:
 
     MediaStream getStream(std::string name = "") const;
 
+    void setResolutionChangedCallback(std::function<void(int, int)> cb) { resolutionChangedCallback_ = std::move(cb); }
+
 private:
     NON_COPYABLE(MediaDecoder);
 
@@ -223,6 +225,10 @@ private:
     int prepareDecoderContext();
     int64_t seekTime_ = -1;
     void resetSeekTime() { seekTime_ = -1; }
+    std::function<void(int, int)> resolutionChangedCallback_;
+
+    int width_;
+    int height_;
 
 protected:
     AVDictionary* options_ = nullptr;
diff --git a/src/media/video/video_receive_thread.cpp b/src/media/video/video_receive_thread.cpp
index 2c865832cdc4e61d02db2221bfb3196280ed43b4..690377af133f7e5c01603eb47f7391f1a81d02cf 100644
--- a/src/media/video/video_receive_thread.cpp
+++ b/src/media/video/video_receive_thread.cpp
@@ -82,6 +82,10 @@ VideoReceiveThread::setup()
                                             av_buffer_ref(displayMatrix.get()));
         publishFrame(std::static_pointer_cast<VideoFrame>(frame));
     }));
+    videoDecoder_->setResolutionChangedCallback([this] (int width, int height){
+        dstWidth_ = width;
+        dstHeight_ = height;
+    });
 
     dstWidth_ = args_.width;
     dstHeight_ = args_.height;