diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp
index febf35ad1febba5964d243fe5a9c93a9f9bc7dd5..694431ba6fe8bff37274fe785994954368313c53 100644
--- a/src/media/media_decoder.cpp
+++ b/src/media/media_decoder.cpp
@@ -325,11 +325,8 @@ MediaDemuxer::decode()
     }
 
     auto& cb = streams_[streamIndex];
-    if (cb) {
-        DecodeStatus ret = cb(*packet.get());
-        if (ret == DecodeStatus::FallBack)
-            return Status::FallBack;
-    }
+    if (cb)
+        cb(*packet.get());
     return Status::Success;
 }
 
@@ -338,7 +335,7 @@ MediaDecoder::MediaDecoder(const std::shared_ptr<MediaDemuxer>& demuxer, int ind
    avStream_(demuxer->getStream(index))
 {
     demuxer->setStreamCallback(index, [this](AVPacket& packet) {
-        return decode(packet);
+        decode(packet);
     });
     setupStream();
 }
@@ -349,7 +346,7 @@ MediaDecoder::MediaDecoder(const std::shared_ptr<MediaDemuxer>& demuxer, int ind
   callback_(std::move(observer))
 {
     demuxer->setStreamCallback(index, [this](AVPacket& packet) {
-        return decode(packet);
+        decode(packet);
     });
     setupStream();
 }
@@ -410,7 +407,7 @@ int MediaDecoder::setup(AVMediaType type)
         return -1;
     avStream_ = demuxer_->getStream(stream);
     demuxer_->setStreamCallback(stream, [this](AVPacket& packet) {
-        return decode(packet);
+        decode(packet);
     });
     return setupStream();
 }
@@ -429,14 +426,14 @@ MediaDecoder::setupStream()
     // it has been disabled already by the video_receive_thread/video_input
     enableAccel_ &= Manager::instance().videoPreferences.getDecodingAccelerated();
 
-    if (enableAccel_ and not fallback_) {
+    if (enableAccel_) {
         auto APIs = video::HardwareAccel::getCompatibleAccel(decoderCtx_->codec_id,
                     decoderCtx_->width, decoderCtx_->height, CODEC_DECODER);
         for (const auto& it : APIs) {
             accel_ = std::make_unique<video::HardwareAccel>(it);    // save accel
             auto ret = accel_->initAPI(false, nullptr);
             if (ret < 0) {
-                accel_.reset();
+                accel_ = nullptr;
                 continue;
             }
             if(prepareDecoderContext() < 0)
@@ -511,20 +508,13 @@ MediaDecoder::updateStartTime(int64_t startTime) {
      startTime_ = startTime;
 }
 
-DecodeStatus
+MediaDecoder::Status
 MediaDecoder::decode(AVPacket& packet)
 {
     int frameFinished = 0;
     auto ret = avcodec_send_packet(decoderCtx_, &packet);
-    if ( accel_ && (ret == AVERROR(EINVAL) or ret == AVERROR(EPERM)) ) {
-        JAMI_WARN("Decoding error falling back to software");
-        fallback_ = true;
-        accel_.reset();
-        avcodec_flush_buffers(decoderCtx_);
-        setupStream();
-        return DecodeStatus::FallBack;
-    } else if (ret < 0 && ret != AVERROR(EAGAIN)) {
-        return ret == AVERROR_EOF ? DecodeStatus::Success : DecodeStatus::DecodeError;
+    if (ret < 0 && ret != AVERROR(EAGAIN)) {
+        return ret == AVERROR_EOF ? Status::Success : Status::DecodeError;
     }
 
     auto f = (inputDecoder_->type == AVMEDIA_TYPE_VIDEO)
@@ -533,7 +523,7 @@ MediaDecoder::decode(AVPacket& packet)
     auto frame = f->pointer();
     ret = avcodec_receive_frame(decoderCtx_, frame);
     if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
-        return DecodeStatus::DecodeError;
+        return Status::DecodeError;
     }
     if (ret >= 0)
         frameFinished = 1;
@@ -554,7 +544,7 @@ MediaDecoder::decode(AVPacket& packet)
             auto target_relative = static_cast<std::int64_t>(frame_time.real() * 1e6);
             auto target_absolute = startTime_ + target_relative;
             if (target_relative < seekTime_) {
-                return DecodeStatus::Success;
+                return Status::Success;
             }
             //required frame found. Reset seek time
             if (target_relative >= seekTime_) {
@@ -568,9 +558,9 @@ MediaDecoder::decode(AVPacket& packet)
 
         if (callback_)
             callback_(std::move(f));
-        return DecodeStatus::FrameFinished;
+        return Status::FrameFinished;
     }
-    return DecodeStatus::Success;
+    return Status::Success;
 }
 
 void
@@ -599,7 +589,7 @@ MediaDecoder::enableAccel(bool enableAccel)
 }
 #endif
 
-DecodeStatus
+MediaDecoder::Status
 MediaDecoder::flush()
 {
     AVPacket inpacket;
@@ -609,12 +599,12 @@ MediaDecoder::flush()
     int ret = 0;
     ret = avcodec_send_packet(decoderCtx_, &inpacket);
     if (ret < 0 && ret != AVERROR(EAGAIN))
-        return ret == AVERROR_EOF ? DecodeStatus::Success : DecodeStatus::DecodeError;
+        return ret == AVERROR_EOF ? Status::Success : Status::DecodeError;
 
     auto result = std::make_shared<MediaFrame>();
     ret = avcodec_receive_frame(decoderCtx_, result->pointer());
     if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
-        return DecodeStatus::DecodeError;
+        return Status::DecodeError;
     if (ret >= 0)
         frameFinished = 1;
 
@@ -622,10 +612,10 @@ MediaDecoder::flush()
         av_packet_unref(&inpacket);
         if (callback_)
             callback_(std::move(result));
-        return DecodeStatus::FrameFinished;
+        return Status::FrameFinished;
     }
 
-    return DecodeStatus::Success;
+    return Status::Success;
 }
 #endif // ENABLE_VIDEO
 
diff --git a/src/media/media_decoder.h b/src/media/media_decoder.h
index 48edd213f05f0a65915a27710f780639be4fae0c..c0e5b0cfdf5929f456d5e39094376f0f7bbf22fe 100644
--- a/src/media/media_decoder.h
+++ b/src/media/media_decoder.h
@@ -68,16 +68,6 @@ class Resampler;
 class MediaIOHandle;
 class MediaDecoder;
 
-enum class DecodeStatus {
-    Success,
-    FrameFinished,
-    EndOfFile,
-    ReadError,
-    DecodeError,
-    RestartRequired,
-    FallBack
-};
-
 class MediaDemuxer {
 public:
     MediaDemuxer();
@@ -87,15 +77,14 @@ public:
         Success,
         EndOfFile,
         ReadBufferOverflow,
-        ReadError,
-        FallBack
+        ReadError
     };
 
     enum class CurrentState {
         Demuxing,
         Finished
     };
-    using StreamCallback = std::function<DecodeStatus (AVPacket&)>;
+    using StreamCallback = std::function<void(AVPacket&)>;
 
     int openInput(const DeviceParams&);
 
@@ -156,6 +145,14 @@ private:
 class MediaDecoder
 {
 public:
+    enum class Status {
+        Success,
+        FrameFinished,
+        EndOfFile,
+        ReadError,
+        DecodeError,
+        RestartRequired
+    };
 
     MediaDecoder();
     MediaDecoder(MediaObserver observer);
@@ -175,7 +172,7 @@ public:
     int setupVideo() { return setup(AVMEDIA_TYPE_VIDEO); }
 
     MediaDemuxer::Status decode();
-    DecodeStatus flush();
+    Status flush();
 
     int getWidth() const;
     int getHeight() const;
@@ -199,7 +196,7 @@ public:
 private:
     NON_COPYABLE(MediaDecoder);
 
-    DecodeStatus decode(AVPacket&);
+    Status decode(AVPacket&);
 
     rational<unsigned> getTimeBase() const;
 
diff --git a/src/media/socket_pair.cpp b/src/media/socket_pair.cpp
index fcdc3796e21f69999a200f7ff8a202bb16c46ec1..24bd51041948ce9e7203a46911e34a8921894a7c 100644
--- a/src/media/socket_pair.cpp
+++ b/src/media/socket_pair.cpp
@@ -647,6 +647,12 @@ SocketPair::getLastLatency()
         return -1;
 }
 
+void
+SocketPair::setPacketLossCallback(std::function<void(void)> cb)
+{
+    packetLossCallback_ = std::move(cb);
+}
+
 void
 SocketPair::setRtpDelayCallback(std::function<void(int, int)> cb)
 {
diff --git a/src/media/socket_pair.h b/src/media/socket_pair.h
index b18631d6ccc586d8389926762afa93d6af5f5682..f9b0650297cdcb1031cf97fb721451c7aa519851 100644
--- a/src/media/socket_pair.h
+++ b/src/media/socket_pair.h
@@ -168,9 +168,7 @@ class SocketPair {
         bool waitForRTCP(std::chrono::seconds interval);
         double getLastLatency();
 
-        void setPacketLossCallback(std::function<void(void)> cb) {
-            packetLossCallback_ = std::move(cb);
-        }
+        void setPacketLossCallback(std::function<void (void)> cb);
         void setRtpDelayCallback(std::function<void (int, int)> cb);
 
         int writeData(uint8_t* buf, int buf_size);
diff --git a/src/media/video/accel.cpp b/src/media/video/accel.cpp
index e8514cde08baa2bde36bf5dcdbb8957d55eb33e9..b76163629b8f11b119df3ac8e197d9b3e819272a 100644
--- a/src/media/video/accel.cpp
+++ b/src/media/video/accel.cpp
@@ -77,7 +77,9 @@ getFormatCb(AVCodecContext* codecCtx, const AVPixelFormat* formats)
 {
     auto accel = static_cast<HardwareAccel*>(codecCtx->opaque);
 
+    AVPixelFormat fallback = AV_PIX_FMT_NONE;
     for (int i = 0; formats[i] != AV_PIX_FMT_NONE; ++i) {
+        fallback = formats[i];
         if (accel && formats[i] == accel->getFormat()) {
             // found hardware format for codec with api
             JAMI_DBG() << "Found compatible hardware format for "
@@ -86,7 +88,9 @@ getFormatCb(AVCodecContext* codecCtx, const AVPixelFormat* formats)
             return formats[i];
         }
     }
-    return AV_PIX_FMT_NONE;
+
+    JAMI_WARN() << "Not using hardware decoding";
+    return fallback;
 }
 
 int
diff --git a/src/media/video/video_receive_thread.cpp b/src/media/video/video_receive_thread.cpp
index 6a86e8f6877c29a246cb60044d59e6db1b892124..61625fab6d69067976c767e5e8462d96f2eafa97 100644
--- a/src/media/video/video_receive_thread.cpp
+++ b/src/media/video/video_receive_thread.cpp
@@ -192,10 +192,6 @@ void VideoReceiveThread::decodeFrame()
         status == MediaDemuxer::Status::ReadError) {
         loop_.stop();
     }
-    if (status == MediaDemuxer::Status::FallBack) {
-        if (keyFrameRequestCallback_)
-            keyFrameRequestCallback_();
-    }
 }
 
 void VideoReceiveThread::enterConference()
diff --git a/src/media/video/video_receive_thread.h b/src/media/video/video_receive_thread.h
index 757bd8829d1be9d25d8123867e37d96357c184c1..12521439eedea480d5d07f1c99704b790cae9999 100644
--- a/src/media/video/video_receive_thread.h
+++ b/src/media/video/video_receive_thread.h
@@ -55,9 +55,7 @@ public:
     void startLoop(const std::function<void(MediaType)>& cb);
 
     void addIOContext(SocketPair& socketPair);
-    void setRequestKeyFrameCallback(std::function<void (void)> cb) {
-      keyFrameRequestCallback_ = std::move(cb);
-    };
+    void setRequestKeyFrameCallback(std::function<void (void)>);
     void enterConference();
     void exitConference();
 
@@ -108,8 +106,6 @@ private:
     bool setup();
     void process();
     void cleanup();
-
-    std::function<void(void)> keyFrameRequestCallback_;
 };
 
 }} // namespace jami::video
diff --git a/src/media/video/video_rtp_session.cpp b/src/media/video/video_rtp_session.cpp
index fcd86eafdef7b02b04273116456c41bbb15365fa..c42e7a0486319cb9d91ec49d25066f694a552075 100644
--- a/src/media/video/video_rtp_session.cpp
+++ b/src/media/video/video_rtp_session.cpp
@@ -85,7 +85,10 @@ VideoRtpSession::updateMedia(const MediaDescription& send, const MediaDescriptio
 void
 VideoRtpSession::setRequestKeyFrameCallback(std::function<void(void)> cb)
 {
-    cbKeyFrameRequest_ = std::move(cb);
+    if (socketPair_)
+        socketPair_->setPacketLossCallback(std::move(cb));
+    else
+        JAMI_ERR("No socket pair, keyframe request callback not possible");
 }
 
 void VideoRtpSession::startSender()
@@ -141,9 +144,6 @@ void VideoRtpSession::startSender()
                                           send_, *socketPair_, initSeqVal_, mtu_));
             if (changeOrientationCallback_)
                 sender_->setChangeOrientationCallback(changeOrientationCallback_);
-            if (socketPair_)
-                socketPair_->setPacketLossCallback([this] (){
-                cbKeyFrameRequest_();});
 
         } catch (const MediaEncoderException &e) {
             JAMI_ERR("%s", e.what());
@@ -184,9 +184,6 @@ void VideoRtpSession::startReceiver()
         // XXX keyframe requests can timeout if unanswered
         receiveThread_->addIOContext(*socketPair_);
         receiveThread_->startLoop(onSuccessfulSetup_);
-        if (receiveThread_)
-            receiveThread_->setRequestKeyFrameCallback([this] (){
-                cbKeyFrameRequest_();});
     } else {
         JAMI_DBG("Video receiving disabled");
         if (receiveThread_)
diff --git a/src/media/video/video_rtp_session.h b/src/media/video/video_rtp_session.h
index b98db1c407bdc80ffa22524da3c00c19ad220f03..9a3da8b1504353b643bdbb634d04ea49820ff4c2 100644
--- a/src/media/video/video_rtp_session.h
+++ b/src/media/video/video_rtp_session.h
@@ -169,8 +169,6 @@ private:
     unsigned remb_dec_cnt_ {0};
 
     std::unique_ptr<CongestionControl> cc;
-
-    std::function<void(void)> cbKeyFrameRequest_;
 };
 
 }} // namespace jami::video