diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp
index 989e0ac898fd8db74c1c63822b844a5da776a5bd..0512111a5cf905f8c6cf912d7fe81395ac7b07a9 100644
--- a/src/media/media_decoder.cpp
+++ b/src/media/media_decoder.cpp
@@ -363,19 +363,33 @@ MediaDecoder::decode(VideoFrame& result)
     int frameFinished = 0;
 #if LIBAVCODEC_VERSION_CHECK(57, 25, 0, 48, 101)
     ret = avcodec_send_packet(decoderCtx_, &inpacket);
-    if (ret < 0)
+    if (ret < 0) {
+#ifdef RING_ACCEL
+        if (accel_->hasFailed())
+            return Status::RestartRequired;
+#endif
         return ret == AVERROR_EOF ? Status::Success : Status::DecodeError;
-
+    }
     ret = avcodec_receive_frame(decoderCtx_, frame);
-    if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
+    if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
+#ifdef RING_ACCEL
+        if (accel_->hasFailed())
+            return Status::RestartRequired;
+#endif
         return Status::DecodeError;
+    }
     if (ret >= 0)
         frameFinished = 1;
 #else
     ret = avcodec_decode_video2(decoderCtx_, frame,
                                     &frameFinished, &inpacket);
-    if (ret <= 0)
+    if (ret <= 0) {
+#ifdef RING_ACCEL
+        if (accel_->hasFailed())
+            return Status::RestartRequired;
+#endif
         return Status::DecodeError;
+    }
 #endif
 
     av_packet_unref(&inpacket);
diff --git a/src/media/video/accel.cpp b/src/media/video/accel.cpp
index bf4ff124291d86114a5460f28f92d134a505c2a0..5bd9dc49857ac8b7438bdfbec61bbce9754d4cec 100644
--- a/src/media/video/accel.cpp
+++ b/src/media/video/accel.cpp
@@ -81,11 +81,11 @@ allocateBufferCb(AVCodecContext* codecCtx, AVFrame* frame, int flags)
 {
     if (auto accel = static_cast<HardwareAccel*>(codecCtx->opaque)) {
         if (!accel->hasFailed() && accel->allocateBuffer(frame, flags) == 0) {
-            accel->succeed();
+            accel->succeedAllocation();
             return 0;
         }
 
-        accel->fail(false);
+        accel->failAllocation();
     }
 
     return avcodec_default_get_buffer2(codecCtx, frame, flags);
@@ -96,14 +96,28 @@ HardwareAccel::HardwareAccel(const std::string& name, const AVPixelFormat format
     , format_(format)
 {}
 
+void
+HardwareAccel::failAllocation()
+{
+    ++allocationFails_;
+    fail(false);
+}
+
+void
+HardwareAccel::failExtraction()
+{
+    ++extractionFails_;
+    fail(false);
+}
+
 void
 HardwareAccel::fail(bool forceFallback)
 {
-    ++failCount_;
-    if (failCount_ >= MAX_ACCEL_FAILURES || forceFallback) {
+    if (allocationFails_ >= MAX_ACCEL_FAILURES || extractionFails_ >= MAX_ACCEL_FAILURES || forceFallback) {
         RING_ERR("Hardware acceleration failure");
         fallback_ = true;
-        failCount_ = 0;
+        allocationFails_ = 0;
+        extractionFails_ = 0;
         codecCtx_->get_format = avcodec_default_get_format;
         codecCtx_->get_buffer2 = avcodec_default_get_buffer2;
     }
@@ -135,12 +149,12 @@ HardwareAccel::extractData(VideoFrame& input)
         av_frame_unref(inFrame);
         av_frame_move_ref(inFrame, outFrame);
     } catch (const std::runtime_error& e) {
-        fail(false);
+        failExtraction();
         RING_ERR("%s", e.what());
         return false;
     }
 
-    succeed();
+    succeedExtraction();
     return true;
 }
 
diff --git a/src/media/video/accel.h b/src/media/video/accel.h
index d33864706254b324a1a6e4e22c58397dc60a22fe..265f6d379eefb3eb28c56e8fd63cc050179a6531 100644
--- a/src/media/video/accel.h
+++ b/src/media/video/accel.h
@@ -43,8 +43,11 @@ class HardwareAccel {
         void setHeight(int height) { height_ = height; }
         void setProfile(int profile) { profile_ = profile; }
 
+        void failAllocation();
+        void failExtraction();
         void fail(bool forceFallback);
-        void succeed() { failCount_ = 0; } // call on success of allocateBuffer or extractData
+        void succeedAllocation() { allocationFails_ = 0; }
+        void succeedExtraction() { extractionFails_ = 0; }
 
         // wrapper to take care of boilerplate before calling the derived class's implementation
         bool extractData(VideoFrame& input);
@@ -59,8 +62,9 @@ class HardwareAccel {
         AVCodecContext* codecCtx_ = nullptr;
         std::string name_;
         AVPixelFormat format_;
-        unsigned failCount_ = 0; // how many failures in a row, reset on success
-        bool fallback_ = false; // true when failCount_ exceeds a certain number
+        unsigned allocationFails_ = 0; // how many times in a row allocateBuffer has failed
+        unsigned extractionFails_ = 0; // how many times in a row extractData has failed
+        bool fallback_ = false; // set to true when successive failures exceeds MAX_ACCEL_FAILURES
         int width_ = -1;
         int height_ = -1;
         int profile_ = -1;