aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2023-06-20 15:40:40 +0200
committerAnton Khirnov <anton@khirnov.net>2023-07-07 12:07:24 +0200
commitc4332dfda934ae7f3fee1b4c09cb197c00519f92 (patch)
treef3da6553c5ce878ae5ee898b32cef8226459302e
parentfd915dc1da5f2dc7760dfd5f514c82c22f0597f8 (diff)
downloadffmpeg-c4332dfda934ae7f3fee1b4c09cb197c00519f92.tar.gz
lavc/decode: track whether the caller started draining with a separate flag
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.
-rw-r--r--libavcodec/decode.c15
1 files changed, 12 insertions, 3 deletions
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)