diff mbox series

[FFmpeg-devel,v2,07/10] lavc/decode: track whether the caller started draining with a separate flag

Message ID 20230703193229.8593-8-anton@khirnov.net
State Accepted
Commit c4332dfda934ae7f3fee1b4c09cb197c00519f92
Headers show
Series lavc generic-layer private data | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov July 3, 2023, 7:32 p.m. UTC
Decoding pipeline has multiple stages, some of which may have their own
delay (e.g. bitstream filters). The code currently uses
AVCodecInternal.draining to track all of them, but they do not have to
all be in sync.
---
 libavcodec/decode.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index acec9860a5..47714a9393 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -55,6 +55,11 @@  typedef struct DecodeContext {
 
     /* to prevent infinite loop on errors when draining */
     int nb_draining_errors;
+
+    /**
+     * The caller has submitted a NULL packet on input.
+     */
+    int draining_started;
 } DecodeContext;
 
 static DecodeContext *decode_ctx(AVCodecInternal *avci)
@@ -626,12 +631,13 @@  FF_ENABLE_DEPRECATION_WARNINGS
 int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
 {
     AVCodecInternal *avci = avctx->internal;
+    DecodeContext     *dc = decode_ctx(avci);
     int ret;
 
     if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))
         return AVERROR(EINVAL);
 
-    if (avctx->internal->draining)
+    if (dc->draining_started)
         return AVERROR_EOF;
 
     if (avpkt && !avpkt->size && avpkt->data)
@@ -642,7 +648,8 @@  int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke
         ret = av_packet_ref(avci->buffer_pkt, avpkt);
         if (ret < 0)
             return ret;
-    }
+    } else
+        dc->draining_started = 1;
 
     ret = av_bsf_send_packet(avci->bsf, avci->buffer_pkt);
     if (ret < 0) {
@@ -1756,6 +1763,7 @@  AVBufferRef *ff_hwaccel_frame_priv_alloc(AVCodecContext *avctx,
 void ff_decode_flush_buffers(AVCodecContext *avctx)
 {
     AVCodecInternal *avci = avctx->internal;
+    DecodeContext     *dc = decode_ctx(avci);
 
     av_packet_unref(avci->last_pkt_props);
     av_packet_unref(avci->in_pkt);
@@ -1765,7 +1773,8 @@  void ff_decode_flush_buffers(AVCodecContext *avctx)
 
     av_bsf_flush(avci->bsf);
 
-    decode_ctx(avci)->nb_draining_errors = 0;
+    dc->nb_draining_errors = 0;
+    dc->draining_started   = 0;
 }
 
 AVCodecInternal *ff_decode_internal_alloc(void)