Signed-off-by: James Almer <jamr...@gmail.com>
---
 libavcodec/avcodec.c  |  1 +
 libavcodec/decode.c   | 17 ++++++++++++++++-
 libavcodec/internal.h |  5 +++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index a85d3c2309..7818b6e33b 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -397,6 +397,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
         av_bsf_flush(avci->bsf);
     }
 
+    avci->fatal         = 0;
     avci->draining      = 0;
     avci->draining_done = 0;
     avci->nb_draining_errors = 0;
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 6be2d3d6ed..04c9d374ce 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -576,7 +576,9 @@ static int decode_receive_frame_internal(AVCodecContext 
*avctx, AVFrame *frame)
 
     av_assert0(!frame->buf[0]);
 
-    if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) {
+    if (avci->fatal) {
+        ret = avci->draining ? AVERROR_EOF : AVERROR_UNRECOVERABLE;
+    } else if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) {
         ret = codec->cb.receive_frame(avctx, frame);
         if (ret != AVERROR(EAGAIN))
             av_packet_unref(avci->last_pkt_props);
@@ -586,6 +588,9 @@ static int decode_receive_frame_internal(AVCodecContext 
*avctx, AVFrame *frame)
     if (ret == AVERROR_EOF)
         avci->draining_done = 1;
 
+    if (ret == AVERROR_UNRECOVERABLE)
+        avci->fatal = 1;
+
     /* preserve ret */
     ok = detect_colorspace(avctx, frame);
     if (ok < 0) {
@@ -648,6 +653,16 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext 
*avctx, const AVPacke
     if (avpkt && !avpkt->size && avpkt->data)
         return AVERROR(EINVAL);
 
+    if (avctx->internal->fatal) {
+        /* The API expects EOF signaling to always be handled even with
+         * decoding errors */
+        if (!avpkt || (!avpkt->data && !avpkt->side_data_elems)) {
+            avctx->internal->draining = 1;
+            return 0;
+        }
+        return AVERROR_UNRECOVERABLE;
+    }
+
     av_packet_unref(avci->buffer_pkt);
     if (avpkt && (avpkt->data || avpkt->side_data_elems)) {
         ret = av_packet_ref(avci->buffer_pkt, avpkt);
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 76a6ea6bc6..622f5728e2 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -142,6 +142,11 @@ typedef struct AVCodecInternal {
      */
     int draining;
 
+    /**
+     * An unrecoverable error was found, decoding can't proceed normally
+     */
+    int fatal;
+
     /**
      * Temporary buffers for newly received or not yet output packets/frames.
      */
-- 
2.38.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to