diff options
author | Anton Khirnov <anton@khirnov.net> | 2024-06-12 12:42:27 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2024-08-12 14:42:20 +0200 |
commit | 048e978e8eb3dc645114102655cdcb065c3eb6c2 (patch) | |
tree | 38cf071aebece1de71ef565236d3c9e3b223b7b8 | |
parent | 64743b45b5741969074213004ca2f44a89f1ffb3 (diff) | |
download | ffmpeg-048e978e8eb3dc645114102655cdcb065c3eb6c2.tar.gz |
lavc/decode: wrap AV_FRAME_FLAG_DISCARD handling in a loop
Makes sure discarded frames do not cause EAGAIN to be returned during
flushing, which is forbidden.
-rw-r--r-- | libavcodec/decode.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/libavcodec/decode.c b/libavcodec/decode.c index d8e60567bd..a5d4f696b2 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -613,17 +613,22 @@ 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) { + while (1) { frame->pict_type = dc->initial_pict_type; frame->flags |= dc->intra_only_flag; ret = codec->cb.receive_frame(avctx, frame); emms_c(); if (!ret) { - if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) - ret = (frame->flags & AV_FRAME_FLAG_DISCARD) ? AVERROR(EAGAIN) : 0; - else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { int64_t discarded_samples = 0; ret = discard_samples(avctx, frame, &discarded_samples); } + if (ret == AVERROR(EAGAIN) || (frame->flags & AV_FRAME_FLAG_DISCARD)) { + av_frame_unref(frame); + continue; + } + } + break; } } else ret = decode_simple_receive_frame(avctx, frame); |