Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/4] avfilter/trim: consume all available frames and avoid activate reschedule
@ 2025-07-23 23:35 Marton Balint
  2025-07-23 23:35 ` [FFmpeg-devel] [PATCH 2/4] avfilter/af_afade: factorize functions generating frames Marton Balint
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Marton Balint @ 2025-07-23 23:35 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Marton Balint

There is no benefit in delaying processing all available frames.

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavfilter/trim.c | 42 +++++++++++++++++-------------------------
 1 file changed, 17 insertions(+), 25 deletions(-)

diff --git a/libavfilter/trim.c b/libavfilter/trim.c
index 7200680716..6d1016ac81 100644
--- a/libavfilter/trim.c
+++ b/libavfilter/trim.c
@@ -90,10 +90,8 @@ static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
     int drop;
 
     /* drop everything if EOF has already been returned */
-    if (s->eof) {
-        av_frame_free(&frame);
+    if (s->eof)
         return 0;
-    }
 
     if (s->start_frame >= 0 || s->start_pts != AV_NOPTS_VALUE) {
         drop = 1;
@@ -131,13 +129,10 @@ static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
 
     s->nb_frames++;
 
-    return ff_filter_frame(ctx->outputs[0], frame);
+    return 1;
 
 drop:
-    if (!s->eof)
-        ff_filter_set_ready(ctx, 100);
     s->nb_frames++;
-    av_frame_free(&frame);
     return 0;
 }
 #endif // CONFIG_TRIM_FILTER
@@ -152,10 +147,8 @@ static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
     int drop;
 
     /* drop everything if EOF has already been returned */
-    if (s->eof) {
-        av_frame_free(&frame);
+    if (s->eof)
         return 0;
-    }
 
     if (frame->pts != AV_NOPTS_VALUE)
         pts = av_rescale_q(frame->pts, inlink->time_base,
@@ -230,10 +223,8 @@ static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
 
     if (start_sample) {
         AVFrame *out = ff_get_audio_buffer(ctx->outputs[0], end_sample - start_sample);
-        if (!out) {
-            av_frame_free(&frame);
+        if (!out)
             return AVERROR(ENOMEM);
-        }
 
         av_frame_copy_props(out, frame);
         av_samples_copy(out->extended_data, frame->extended_data, 0, start_sample,
@@ -243,18 +234,16 @@ static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
             out->pts += av_rescale_q(start_sample, (AVRational){ 1, out->sample_rate },
                                      inlink->time_base);
 
-        av_frame_free(&frame);
-        frame = out;
+        av_frame_unref(frame);
+        av_frame_move_ref(frame, out);
+        av_frame_free(&out);
     } else
         frame->nb_samples = end_sample;
 
-    return ff_filter_frame(ctx->outputs[0], frame);
+    return 1;
 
 drop:
-    if (!s->eof)
-        ff_filter_set_ready(ctx, 100);
     s->nb_samples += frame->nb_samples;
-    av_frame_free(&frame);
     return 0;
 }
 #endif // CONFIG_ATRIM_FILTER
@@ -295,18 +284,21 @@ static int activate(AVFilterContext *ctx)
     TrimContext *s = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
+    AVFrame *frame = NULL;
+    int ret;
 
     FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
 
-    if (!s->eof && ff_inlink_queued_frames(inlink)) {
-        AVFrame *frame = NULL;
-        int ret;
-
-        ret = ff_inlink_consume_frame(inlink, &frame);
+    while ((ret = ff_inlink_consume_frame(inlink, &frame))) {
         if (ret < 0)
             return ret;
+
+        ret = s->filter_frame(inlink, frame);
         if (ret > 0)
-            return s->filter_frame(inlink, frame);
+            return ff_filter_frame(outlink, frame);
+        av_frame_free(&frame);
+        if (ret < 0)
+            return ret;
     }
 
     FF_FILTER_FORWARD_STATUS(inlink, outlink);
-- 
2.43.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [FFmpeg-devel] [PATCH 2/4] avfilter/af_afade: factorize functions generating frames
  2025-07-23 23:35 [FFmpeg-devel] [PATCH 1/4] avfilter/trim: consume all available frames and avoid activate reschedule Marton Balint
@ 2025-07-23 23:35 ` Marton Balint
  2025-07-23 23:35 ` [FFmpeg-devel] [PATCH 3/4] avfilter/af_afade: fix check_input for empty streams Marton Balint
  2025-07-23 23:36 ` [FFmpeg-devel] [PATCH 4/4] avfilter/af_afade: rework crossfade activate logic Marton Balint
  2 siblings, 0 replies; 4+ messages in thread
From: Marton Balint @ 2025-07-23 23:35 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Marton Balint

No change in functionality.

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavfilter/af_afade.c | 206 ++++++++++++++++++++++-------------------
 1 file changed, 111 insertions(+), 95 deletions(-)

diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c
index a9318c0ac5..b006420111 100644
--- a/libavfilter/af_afade.c
+++ b/libavfilter/af_afade.c
@@ -25,6 +25,7 @@
 
 #include "config_components.h"
 
+#include "libavutil/avassert.h"
 #include "libavutil/opt.h"
 #include "audio.h"
 #include "avfilter.h"
@@ -547,117 +548,132 @@ static int check_input(AVFilterLink *inlink)
     return ff_inlink_check_available_samples(inlink, queued_samples + 1) == 1;
 }
 
+static int pass_frame(AVFilterLink *inlink, AVFilterLink *outlink, int64_t *pts)
+{
+    AVFrame *in;
+    int ret = ff_inlink_consume_frame(inlink, &in);
+    if (ret < 0)
+        return ret;
+    av_assert1(ret);
+    in->pts = *pts;
+    *pts += av_rescale_q(in->nb_samples,
+            (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+    return ff_filter_frame(outlink, in);
+}
+
+static int pass_samples(AVFilterLink *inlink, AVFilterLink *outlink, unsigned nb_samples, int64_t *pts)
+{
+    AVFrame *in;
+    int ret = ff_inlink_consume_samples(inlink, nb_samples, nb_samples, &in);
+    if (ret < 0)
+        return ret;
+    av_assert1(ret);
+    in->pts = *pts;
+    *pts += av_rescale_q(in->nb_samples,
+            (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+    return ff_filter_frame(outlink, in);
+}
+
+static int pass_crossfade(AVFilterContext *ctx)
+{
+    AudioFadeContext *s = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFrame *out, *cf[2] = { NULL };
+    int ret;
+
+    if (s->overlap) {
+        out = ff_get_audio_buffer(outlink, s->nb_samples);
+        if (!out)
+            return AVERROR(ENOMEM);
+
+        ret = ff_inlink_consume_samples(ctx->inputs[0], s->nb_samples, s->nb_samples, &cf[0]);
+        if (ret < 0) {
+            av_frame_free(&out);
+            return ret;
+        }
+
+        ret = ff_inlink_consume_samples(ctx->inputs[1], s->nb_samples, s->nb_samples, &cf[1]);
+        if (ret < 0) {
+            av_frame_free(&out);
+            return ret;
+        }
+
+        s->crossfade_samples(out->extended_data, cf[0]->extended_data,
+                             cf[1]->extended_data,
+                             s->nb_samples, out->ch_layout.nb_channels,
+                             s->curve, s->curve2);
+        out->pts = s->pts;
+        s->pts += av_rescale_q(s->nb_samples,
+            (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+        s->passthrough = 1;
+        av_frame_free(&cf[0]);
+        av_frame_free(&cf[1]);
+        return ff_filter_frame(outlink, out);
+    } else {
+        out = ff_get_audio_buffer(outlink, s->nb_samples);
+        if (!out)
+            return AVERROR(ENOMEM);
+
+        ret = ff_inlink_consume_samples(ctx->inputs[0], s->nb_samples, s->nb_samples, &cf[0]);
+        if (ret < 0) {
+            av_frame_free(&out);
+            return ret;
+        }
+
+        s->fade_samples(out->extended_data, cf[0]->extended_data, s->nb_samples,
+                        outlink->ch_layout.nb_channels, -1, s->nb_samples - 1, s->nb_samples, s->curve, 0., 1.);
+        out->pts = s->pts;
+        s->pts += av_rescale_q(s->nb_samples,
+            (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+        av_frame_free(&cf[0]);
+        ret = ff_filter_frame(outlink, out);
+        if (ret < 0)
+            return ret;
+
+        out = ff_get_audio_buffer(outlink, s->nb_samples);
+        if (!out)
+            return AVERROR(ENOMEM);
+
+        ret = ff_inlink_consume_samples(ctx->inputs[1], s->nb_samples, s->nb_samples, &cf[1]);
+        if (ret < 0) {
+            av_frame_free(&out);
+            return ret;
+        }
+
+        s->fade_samples(out->extended_data, cf[1]->extended_data, s->nb_samples,
+                        outlink->ch_layout.nb_channels, 1, 0, s->nb_samples, s->curve2, 0., 1.);
+        out->pts = s->pts;
+        s->pts += av_rescale_q(s->nb_samples,
+            (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
+        s->passthrough = 1;
+        av_frame_free(&cf[1]);
+        return ff_filter_frame(outlink, out);
+    }
+}
+
 static int activate(AVFilterContext *ctx)
 {
     AudioFadeContext *s   = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    AVFrame *in = NULL, *out, *cf[2] = { NULL };
-    int ret = 0, nb_samples, status;
-    int64_t pts;
+    int ret = 0, nb_samples;
 
     FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
 
     if (s->passthrough && s->status[0]) {
-        ret = ff_inlink_consume_frame(ctx->inputs[1], &in);
-        if (ret > 0) {
-            in->pts = s->pts;
-            s->pts += av_rescale_q(in->nb_samples,
-                      (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
-            return ff_filter_frame(outlink, in);
-        } else if (ret < 0) {
-            return ret;
-        } else if (ff_inlink_acknowledge_status(ctx->inputs[1], &status, &pts)) {
-            ff_outlink_set_status(outlink, status, pts);
-            return 0;
-        } else if (!ret) {
-            if (ff_outlink_frame_wanted(outlink)) {
-                ff_inlink_request_frame(ctx->inputs[1]);
-                return 0;
-            }
-        }
+        if (ff_inlink_queued_frames(ctx->inputs[1]))
+            return pass_frame(ctx->inputs[1], outlink, &s->pts);
+        FF_FILTER_FORWARD_STATUS(ctx->inputs[1], outlink);
+        FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[1]);
     }
 
     nb_samples = ff_inlink_queued_samples(ctx->inputs[0]);
     if (nb_samples  > s->nb_samples) {
         nb_samples -= s->nb_samples;
         s->passthrough = 1;
-        ret = ff_inlink_consume_samples(ctx->inputs[0], nb_samples, nb_samples, &in);
-        if (ret < 0)
-            return ret;
-        in->pts = s->pts;
-        s->pts += av_rescale_q(in->nb_samples,
-            (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
-        return ff_filter_frame(outlink, in);
+        return pass_samples(ctx->inputs[0], outlink, nb_samples, &s->pts);
     } else if (s->status[0] && nb_samples >= s->nb_samples &&
                ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples) {
-        if (s->overlap) {
-            out = ff_get_audio_buffer(outlink, s->nb_samples);
-            if (!out)
-                return AVERROR(ENOMEM);
-
-            ret = ff_inlink_consume_samples(ctx->inputs[0], s->nb_samples, s->nb_samples, &cf[0]);
-            if (ret < 0) {
-                av_frame_free(&out);
-                return ret;
-            }
-
-            ret = ff_inlink_consume_samples(ctx->inputs[1], s->nb_samples, s->nb_samples, &cf[1]);
-            if (ret < 0) {
-                av_frame_free(&out);
-                return ret;
-            }
-
-            s->crossfade_samples(out->extended_data, cf[0]->extended_data,
-                                 cf[1]->extended_data,
-                                 s->nb_samples, out->ch_layout.nb_channels,
-                                 s->curve, s->curve2);
-            out->pts = s->pts;
-            s->pts += av_rescale_q(s->nb_samples,
-                (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
-            s->passthrough = 1;
-            av_frame_free(&cf[0]);
-            av_frame_free(&cf[1]);
-            return ff_filter_frame(outlink, out);
-        } else {
-            out = ff_get_audio_buffer(outlink, s->nb_samples);
-            if (!out)
-                return AVERROR(ENOMEM);
-
-            ret = ff_inlink_consume_samples(ctx->inputs[0], s->nb_samples, s->nb_samples, &cf[0]);
-            if (ret < 0) {
-                av_frame_free(&out);
-                return ret;
-            }
-
-            s->fade_samples(out->extended_data, cf[0]->extended_data, s->nb_samples,
-                            outlink->ch_layout.nb_channels, -1, s->nb_samples - 1, s->nb_samples, s->curve, 0., 1.);
-            out->pts = s->pts;
-            s->pts += av_rescale_q(s->nb_samples,
-                (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
-            av_frame_free(&cf[0]);
-            ret = ff_filter_frame(outlink, out);
-            if (ret < 0)
-                return ret;
-
-            out = ff_get_audio_buffer(outlink, s->nb_samples);
-            if (!out)
-                return AVERROR(ENOMEM);
-
-            ret = ff_inlink_consume_samples(ctx->inputs[1], s->nb_samples, s->nb_samples, &cf[1]);
-            if (ret < 0) {
-                av_frame_free(&out);
-                return ret;
-            }
-
-            s->fade_samples(out->extended_data, cf[1]->extended_data, s->nb_samples,
-                            outlink->ch_layout.nb_channels, 1, 0, s->nb_samples, s->curve2, 0., 1.);
-            out->pts = s->pts;
-            s->pts += av_rescale_q(s->nb_samples,
-                (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
-            s->passthrough = 1;
-            av_frame_free(&cf[1]);
-            return ff_filter_frame(outlink, out);
-        }
+        return pass_crossfade(ctx);
     } else if (ff_outlink_frame_wanted(outlink)) {
         if (!s->status[0] && check_input(ctx->inputs[0]))
             s->status[0] = AVERROR_EOF;
-- 
2.43.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [FFmpeg-devel] [PATCH 3/4] avfilter/af_afade: fix check_input for empty streams
  2025-07-23 23:35 [FFmpeg-devel] [PATCH 1/4] avfilter/trim: consume all available frames and avoid activate reschedule Marton Balint
  2025-07-23 23:35 ` [FFmpeg-devel] [PATCH 2/4] avfilter/af_afade: factorize functions generating frames Marton Balint
@ 2025-07-23 23:35 ` Marton Balint
  2025-07-23 23:36 ` [FFmpeg-devel] [PATCH 4/4] avfilter/af_afade: rework crossfade activate logic Marton Balint
  2 siblings, 0 replies; 4+ messages in thread
From: Marton Balint @ 2025-07-23 23:35 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Marton Balint

Use ff_outlink_get_status directly to get pending EOF state.

Fixes assertion failure with:
ffmpeg -lavfi "sine=f=1000:d=2[a];sine=f=440:d=2,atrim=end=0[b];[a][b]acrossfade=d=1" -f framecrc -
ffmpeg -lavfi "sine=f=1000:d=2,atrim=end=0[a];sine=f=440:d=2[b];[a][b]acrossfade=d=1" -f framecrc -

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavfilter/af_afade.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c
index b006420111..baf972d17d 100644
--- a/libavfilter/af_afade.c
+++ b/libavfilter/af_afade.c
@@ -541,13 +541,6 @@ CROSSFADE(flt, float)
 CROSSFADE(s16, int16_t)
 CROSSFADE(s32, int32_t)
 
-static int check_input(AVFilterLink *inlink)
-{
-    const int queued_samples = ff_inlink_queued_samples(inlink);
-
-    return ff_inlink_check_available_samples(inlink, queued_samples + 1) == 1;
-}
-
 static int pass_frame(AVFilterLink *inlink, AVFilterLink *outlink, int64_t *pts)
 {
     AVFrame *in;
@@ -675,10 +668,10 @@ static int activate(AVFilterContext *ctx)
                ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples) {
         return pass_crossfade(ctx);
     } else if (ff_outlink_frame_wanted(outlink)) {
-        if (!s->status[0] && check_input(ctx->inputs[0]))
+        if (!s->status[0] && ff_outlink_get_status(ctx->inputs[0]))
             s->status[0] = AVERROR_EOF;
         s->passthrough = !s->status[0];
-        if (check_input(ctx->inputs[1])) {
+        if (ff_outlink_get_status(ctx->inputs[1])) {
             s->status[1] = AVERROR_EOF;
             ff_outlink_set_status(outlink, AVERROR_EOF, AV_NOPTS_VALUE);
             return 0;
-- 
2.43.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [FFmpeg-devel] [PATCH 4/4] avfilter/af_afade: rework crossfade activate logic
  2025-07-23 23:35 [FFmpeg-devel] [PATCH 1/4] avfilter/trim: consume all available frames and avoid activate reschedule Marton Balint
  2025-07-23 23:35 ` [FFmpeg-devel] [PATCH 2/4] avfilter/af_afade: factorize functions generating frames Marton Balint
  2025-07-23 23:35 ` [FFmpeg-devel] [PATCH 3/4] avfilter/af_afade: fix check_input for empty streams Marton Balint
@ 2025-07-23 23:36 ` Marton Balint
  2 siblings, 0 replies; 4+ messages in thread
From: Marton Balint @ 2025-07-23 23:36 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Marton Balint

The new logic should be easier to follow.

It also uses ff_inlink_consume_frame() for all simple passthrough operations
making custom get_audio_buffer callback unnecessary.

Fate changes are because the new logic does not repacketize input audio up
until the crossfade. Content is the same.

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavfilter/af_afade.c           | 79 +++++++++++++---------------
 tests/ref/fate/filter-acrossfade | 88 ++++++++++++++++----------------
 2 files changed, 80 insertions(+), 87 deletions(-)

diff --git a/libavfilter/af_afade.c b/libavfilter/af_afade.c
index baf972d17d..d4ea1a7bab 100644
--- a/libavfilter/af_afade.c
+++ b/libavfilter/af_afade.c
@@ -42,9 +42,8 @@ typedef struct AudioFadeContext {
     double silence;
     double unity;
     int overlap;
-    int status[2];
-    int passthrough;
     int64_t pts;
+    int xfade_status;
 
     void (*fade_samples)(uint8_t **dst, uint8_t * const *src,
                          int nb_samples, int channels, int direction,
@@ -598,7 +597,6 @@ static int pass_crossfade(AVFilterContext *ctx)
         out->pts = s->pts;
         s->pts += av_rescale_q(s->nb_samples,
             (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
-        s->passthrough = 1;
         av_frame_free(&cf[0]);
         av_frame_free(&cf[1]);
         return ff_filter_frame(outlink, out);
@@ -638,7 +636,6 @@ static int pass_crossfade(AVFilterContext *ctx)
         out->pts = s->pts;
         s->pts += av_rescale_q(s->nb_samples,
             (AVRational){ 1, outlink->sample_rate }, outlink->time_base);
-        s->passthrough = 1;
         av_frame_free(&cf[1]);
         return ff_filter_frame(outlink, out);
     }
@@ -648,42 +645,50 @@ static int activate(AVFilterContext *ctx)
 {
     AudioFadeContext *s   = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    int ret = 0, nb_samples;
 
     FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, ctx);
 
-    if (s->passthrough && s->status[0]) {
+    // Read first input until EOF
+    if (s->xfade_status == 0) {
+        int queued_samples = ff_inlink_queued_samples(ctx->inputs[0]);
+        if (queued_samples > s->nb_samples) {
+            AVFrame *frame = ff_inlink_peek_frame(ctx->inputs[0], 0);
+            if (queued_samples - s->nb_samples >= frame->nb_samples)
+                return pass_frame(ctx->inputs[0], outlink, &s->pts);
+        }
+        if (ff_outlink_get_status(ctx->inputs[0])) {
+            if (queued_samples > s->nb_samples)
+                return pass_samples(ctx->inputs[0], outlink, queued_samples - s->nb_samples, &s->pts);
+            s->xfade_status = 1;
+        } else {
+            FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[0]);
+        }
+    }
+    // Read second input until enough data is ready or EOF
+    if (s->xfade_status == 1) {
+        if (ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples || ff_outlink_get_status(ctx->inputs[1])) {
+            s->xfade_status = 2;
+        } else {
+            FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[1]);
+        }
+    }
+    // Do crossfade
+    if (s->xfade_status == 2) {
+        s->xfade_status = 3;
+        // TODO: Do some partial crossfade if not all inputs have enough duration?
+        if (ff_inlink_queued_samples(ctx->inputs[0]) >= s->nb_samples &&
+            ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples)
+            return pass_crossfade(ctx);
+    }
+    // Read second input until EOF
+    if (s->xfade_status == 3) {
         if (ff_inlink_queued_frames(ctx->inputs[1]))
             return pass_frame(ctx->inputs[1], outlink, &s->pts);
         FF_FILTER_FORWARD_STATUS(ctx->inputs[1], outlink);
         FF_FILTER_FORWARD_WANTED(outlink, ctx->inputs[1]);
     }
 
-    nb_samples = ff_inlink_queued_samples(ctx->inputs[0]);
-    if (nb_samples  > s->nb_samples) {
-        nb_samples -= s->nb_samples;
-        s->passthrough = 1;
-        return pass_samples(ctx->inputs[0], outlink, nb_samples, &s->pts);
-    } else if (s->status[0] && nb_samples >= s->nb_samples &&
-               ff_inlink_queued_samples(ctx->inputs[1]) >= s->nb_samples) {
-        return pass_crossfade(ctx);
-    } else if (ff_outlink_frame_wanted(outlink)) {
-        if (!s->status[0] && ff_outlink_get_status(ctx->inputs[0]))
-            s->status[0] = AVERROR_EOF;
-        s->passthrough = !s->status[0];
-        if (ff_outlink_get_status(ctx->inputs[1])) {
-            s->status[1] = AVERROR_EOF;
-            ff_outlink_set_status(outlink, AVERROR_EOF, AV_NOPTS_VALUE);
-            return 0;
-        }
-        if (!s->status[0])
-            ff_inlink_request_frame(ctx->inputs[0]);
-        else
-            ff_inlink_request_frame(ctx->inputs[1]);
-        return 0;
-    }
-
-    return ret;
+    return FFERROR_NOT_READY;
 }
 
 static int acrossfade_config_output(AVFilterLink *outlink)
@@ -709,26 +714,14 @@ static int acrossfade_config_output(AVFilterLink *outlink)
     return 0;
 }
 
-static AVFrame *get_audio_buffer(AVFilterLink *inlink, int nb_samples)
-{
-    AVFilterContext *ctx = inlink->dst;
-    AudioFadeContext *s = ctx->priv;
-
-    return s->passthrough ?
-        ff_null_get_audio_buffer   (inlink, nb_samples) :
-        ff_default_get_audio_buffer(inlink, nb_samples);
-}
-
 static const AVFilterPad avfilter_af_acrossfade_inputs[] = {
     {
         .name         = "crossfade0",
         .type         = AVMEDIA_TYPE_AUDIO,
-        .get_buffer.audio = get_audio_buffer,
     },
     {
         .name         = "crossfade1",
         .type         = AVMEDIA_TYPE_AUDIO,
-        .get_buffer.audio = get_audio_buffer,
     },
 };
 
diff --git a/tests/ref/fate/filter-acrossfade b/tests/ref/fate/filter-acrossfade
index f80aa10b55..92231bec7d 100644
--- a/tests/ref/fate/filter-acrossfade
+++ b/tests/ref/fate/filter-acrossfade
@@ -3,50 +3,50 @@
 #codec_id 0: pcm_s16le
 #sample_rate 0: 44100
 #channel_layout_name 0: stereo
-0,          0,          0,     1912,     7648, 0x1294dd84
-0,       1912,       1912,     4096,    16384, 0x8d5eec9b
-0,       6008,       6008,     4096,    16384, 0x9f15e8a9
-0,      10104,      10104,     4096,    16384, 0x5594dd9d
-0,      14200,      14200,     4096,    16384, 0x5115d9bb
-0,      18296,      18296,     4096,    16384, 0x0511d717
-0,      22392,      22392,     4096,    16384, 0x9cbdd713
-0,      26488,      26488,     4096,    16384, 0x2f13e615
-0,      30584,      30584,     4096,    16384, 0x415ae9f7
-0,      34680,      34680,     4096,    16384, 0x8d5eec9b
-0,      38776,      38776,     4096,    16384, 0x9f15e8a9
-0,      42872,      42872,     4096,    16384, 0xd9809dcd
-0,      46968,      46968,     4096,    16384, 0x7b60ec15
-0,      51064,      51064,     4096,    16384, 0xe92de3eb
-0,      55160,      55160,     4096,    16384, 0x063d2c76
-0,      59256,      59256,     4096,    16384, 0xacbed331
-0,      63352,      63352,     4096,    16384, 0x1137d0c7
-0,      67448,      67448,     4096,    16384, 0xafbad1d7
-0,      71544,      71544,     4096,    16384, 0xb2a0040c
-0,      75640,      75640,     4096,    16384, 0x83222d0c
-0,      79736,      79736,     4096,    16384, 0x97993592
-0,      83832,      83832,     4096,    16384, 0x9e4200b2
-0,      87928,      87928,     4096,    16384, 0xf24c2685
-0,      92024,      92024,     4096,    16384, 0x0b23a4c8
-0,      96120,      96120,     4096,    16384, 0x9105fcde
-0,     100216,     100216,     4096,    16384, 0xd4b64a6f
-0,     104312,     104312,     4096,    16384, 0xef56c48a
-0,     108408,     108408,     4096,    16384, 0xb12b9599
-0,     112504,     112504,     4096,    16384, 0x18bbeefd
-0,     116600,     116600,     4096,    16384, 0x3fe2d14b
-0,     120696,     120696,     4096,    16384, 0xf6d6fdff
-0,     124792,     124792,     4096,    16384, 0x2e538447
-0,     128888,     128888,     4096,    16384, 0xd8251663
-0,     132984,     132984,     4096,    16384, 0xd783c943
-0,     137080,     137080,     4096,    16384, 0x3d64f7cf
-0,     141176,     141176,     4096,    16384, 0x80e2c034
-0,     145272,     145272,     4096,    16384, 0x69a7e254
-0,     149368,     149368,     4096,    16384, 0xb3f5efb9
-0,     153464,     153464,     4096,    16384, 0x3975dea3
-0,     157560,     157560,     4096,    16384, 0x7ff7d2c5
-0,     161656,     161656,     4096,    16384, 0x5476e599
-0,     165752,     165752,     4096,    16384, 0x30e4f37a
-0,     169848,     169848,     4096,    16384, 0x57c1a83c
-0,     173944,     173944,     2456,     9824, 0x498532b3
+0,          0,          0,     4096,    16384, 0x02ebe66b
+0,       4096,       4096,     4096,    16384, 0x35bfe081
+0,       8192,       8192,     4096,    16384, 0x3f90e0a9
+0,      12288,      12288,     4096,    16384, 0xd389dc43
+0,      16384,      16384,     4096,    16384, 0x9d5add49
+0,      20480,      20480,     4096,    16384, 0x378ee333
+0,      24576,      24576,     4096,    16384, 0xabf6df0f
+0,      28672,      28672,     4096,    16384, 0xedefe76f
+0,      32768,      32768,     4096,    16384, 0x02ebe66b
+0,      36864,      36864,     4096,    16384, 0x35bfe081
+0,      40960,      40960,     4096,    16384, 0xdbc2b3b9
+0,      45056,      45056,     4096,    16384, 0xe92bd835
+0,      49152,      49152,     4096,    16384, 0x1126dca3
+0,      53248,      53248,     4096,    16384, 0x9647edcf
+0,      57344,      57344,     4096,    16384, 0x5cc345aa
+0,      61440,      61440,     4096,    16384, 0x19d7bd51
+0,      65536,      65536,     4096,    16384, 0x19eccef7
+0,      69632,      69632,     4096,    16384, 0x4b68eeed
+0,      73728,      73728,     4096,    16384, 0x0b3d1bfc
+0,      77824,      77824,     4096,    16384, 0xe9b2e069
+0,      81920,      81920,     4096,    16384, 0xcaa5590e
+0,      86016,      86016,     4096,    16384, 0x47d0b227
+0,      90112,      90112,     4096,    16384, 0x446ba7a4
+0,      94208,      94208,     4096,    16384, 0x299b2e17
+0,      98304,      98304,     4096,    16384, 0xc51affa2
+0,     102400,     102400,     4096,    16384, 0xb4970fcf
+0,     106496,     106496,     4096,    16384, 0xe48af9fc
+0,     110592,     110592,     4096,    16384, 0xc2beffbb
+0,     114688,     114688,     4096,    16384, 0xb9d99627
+0,     118784,     118784,     4096,    16384, 0xb65a2086
+0,     122880,     122880,     4096,    16384, 0x6386714b
+0,     126976,     126976,     4096,    16384, 0x92a3171e
+0,     131072,     131072,     4096,    16384, 0x78bad1e2
+0,     135168,     135168,     4096,    16384, 0x63301330
+0,     139264,     139264,     4096,    16384, 0xd663b943
+0,     143360,     143360,     4096,    16384, 0xdcafe377
+0,     147456,     147456,     4096,    16384, 0xfb2cd701
+0,     151552,     151552,     4096,    16384, 0x91c30201
+0,     155648,     155648,     4096,    16384, 0xf23da341
+0,     159744,     159744,     4096,    16384, 0xe8d5fa0a
+0,     163840,     163840,     4096,    16384, 0x519bdfef
+0,     167936,     167936,     4096,    16384, 0xf2fcd803
+0,     172032,     172032,     4096,    16384, 0xd5ceccbc
+0,     176128,     176128,      272,     1088, 0xa8bc282b
 0,     176400,     176400,    88200,   352800, 0x4fb492af
 0,     264600,     264600,     1912,     7648, 0xf0c93a5a
 0,     266512,     266512,     4096,    16384, 0x85454449
-- 
2.43.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-07-23 23:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-23 23:35 [FFmpeg-devel] [PATCH 1/4] avfilter/trim: consume all available frames and avoid activate reschedule Marton Balint
2025-07-23 23:35 ` [FFmpeg-devel] [PATCH 2/4] avfilter/af_afade: factorize functions generating frames Marton Balint
2025-07-23 23:35 ` [FFmpeg-devel] [PATCH 3/4] avfilter/af_afade: fix check_input for empty streams Marton Balint
2025-07-23 23:36 ` [FFmpeg-devel] [PATCH 4/4] avfilter/af_afade: rework crossfade activate logic Marton Balint

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git