aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2024-06-12 12:42:27 +0200
committerAnton Khirnov <anton@khirnov.net>2024-08-12 14:42:20 +0200
commit048e978e8eb3dc645114102655cdcb065c3eb6c2 (patch)
tree38cf071aebece1de71ef565236d3c9e3b223b7b8
parent64743b45b5741969074213004ca2f44a89f1ffb3 (diff)
downloadffmpeg-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.c11
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);