diff mbox series

[FFmpeg-devel,31/39] lavc/decode: wrap AV_FRAME_FLAG_DISCARD handling in a loop

Message ID 20240716171155.31838-31-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,01/39] tests/fate/vcodec: add vsynth tests for FFV1 version 2 | expand

Checks

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

Commit Message

Anton Khirnov July 16, 2024, 5:11 p.m. UTC
Makes sure discarded frames do not cause EAGAIN to be returned during
flushing, which is forbidden.
---
 libavcodec/decode.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Comments

Michael Niedermayer July 17, 2024, 9:20 p.m. UTC | #1
On Tue, Jul 16, 2024 at 07:11:46PM +0200, Anton Khirnov wrote:
> Makes sure discarded frames do not cause EAGAIN to be returned during
> flushing, which is forbidden.
> ---
>  libavcodec/decode.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)

giving execution back to the user at finer granularity would be better

thx

[...]
Anton Khirnov July 18, 2024, 8:14 a.m. UTC | #2
Quoting Michael Niedermayer (2024-07-17 23:20:19)
> On Tue, Jul 16, 2024 at 07:11:46PM +0200, Anton Khirnov wrote:
> > Makes sure discarded frames do not cause EAGAIN to be returned during
> > flushing, which is forbidden.
> > ---
> >  libavcodec/decode.c | 11 ++++++++---
> >  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> giving execution back to the user at finer granularity would be better

That's not how our API works, unless I misunderstand what you're
suggesting.
diff mbox series

Patch

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 6ad74bd94b..b17cfba26f 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);