[FFmpeg-cvslog] avfilter/af_apad: switch to activate

Paul B Mahol git at videolan.org
Sat Jun 17 22:33:50 EEST 2023


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed May 17 09:14:56 2023 +0200| [a756ae41ed745af3ae93a71f3a38f277abba33ef] | committer: Paul B Mahol

avfilter/af_apad: switch to activate

Fixes EOF PTS reporting.
Also allowing previous/next filters in graph to release no longer needed resources.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a756ae41ed745af3ae93a71f3a38f277abba33ef
---

 libavfilter/af_apad.c | 105 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 71 insertions(+), 34 deletions(-)

diff --git a/libavfilter/af_apad.c b/libavfilter/af_apad.c
index df17c9a531..45693a2bd5 100644
--- a/libavfilter/af_apad.c
+++ b/libavfilter/af_apad.c
@@ -32,12 +32,14 @@
 #include "libavutil/avassert.h"
 #include "avfilter.h"
 #include "audio.h"
+#include "filters.h"
 #include "internal.h"
 
 typedef struct APadContext {
     const AVClass *class;
     int64_t next_pts;
 
+    int eof;
     int packet_size;
     int64_t pad_len, pad_len_left;
     int64_t whole_len, whole_len_left;
@@ -87,50 +89,86 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
     return ff_filter_frame(ctx->outputs[0], frame);
 }
 
-static int request_frame(AVFilterLink *outlink)
+static int push_frame(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
     APadContext *s = ctx->priv;
-    int ret;
+    AVFrame *outsamplesref;
+    int n_out;
 
-    ret = ff_request_frame(ctx->inputs[0]);
+    if (ctx->is_disabled)
+        return 0;
+    n_out = s->packet_size;
 
-    if (ret == AVERROR_EOF && !ctx->is_disabled) {
-        int n_out = s->packet_size;
-        AVFrame *outsamplesref;
+    if (s->whole_len >= 0 && s->pad_len < 0) {
+        s->pad_len = s->pad_len_left = s->whole_len_left;
+    }
+    if (s->pad_len >=0 || s->whole_len >= 0) {
+        n_out = FFMIN(n_out, s->pad_len_left);
+        s->pad_len_left -= n_out;
+        av_log(ctx, AV_LOG_DEBUG,
+               "padding n_out:%d pad_len_left:%"PRId64"\n", n_out, s->pad_len_left);
+    }
 
-        if (s->whole_len >= 0 && s->pad_len < 0) {
-            s->pad_len = s->pad_len_left = s->whole_len_left;
-        }
-        if (s->pad_len >=0 || s->whole_len >= 0) {
-            n_out = FFMIN(n_out, s->pad_len_left);
-            s->pad_len_left -= n_out;
-            av_log(ctx, AV_LOG_DEBUG,
-                   "padding n_out:%d pad_len_left:%"PRId64"\n", n_out, s->pad_len_left);
-        }
+    if (!n_out)
+        return AVERROR_EOF;
+
+    outsamplesref = ff_get_audio_buffer(outlink, n_out);
+    if (!outsamplesref)
+        return AVERROR(ENOMEM);
+
+    av_assert0(outsamplesref->sample_rate == outlink->sample_rate);
+    av_assert0(outsamplesref->nb_samples  == n_out);
+
+    av_samples_set_silence(outsamplesref->extended_data, 0,
+                           n_out,
+                           outsamplesref->ch_layout.nb_channels,
+                           outsamplesref->format);
+
+    outsamplesref->pts = s->next_pts;
+    if (s->next_pts != AV_NOPTS_VALUE)
+        s->next_pts += av_rescale_q(n_out, (AVRational){1, outlink->sample_rate}, outlink->time_base);
+
+    return ff_filter_frame(outlink, outsamplesref);
+}
 
-        if (!n_out)
-            return AVERROR_EOF;
+static int activate(AVFilterContext *ctx)
+{
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    APadContext *s = ctx->priv;
+    int64_t pts;
+    int status;
 
-        outsamplesref = ff_get_audio_buffer(outlink, n_out);
-        if (!outsamplesref)
-            return AVERROR(ENOMEM);
+    FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
 
-        av_assert0(outsamplesref->sample_rate == outlink->sample_rate);
-        av_assert0(outsamplesref->nb_samples  == n_out);
+    if (!s->eof && ff_inlink_queued_frames(inlink)) {
+        AVFrame *frame = NULL;
+        int ret;
+
+        ret = ff_inlink_consume_frame(inlink, &frame);
+        if (ret < 0)
+            return ret;
+        if (ret > 0)
+            return filter_frame(inlink, frame);
+    }
 
-        av_samples_set_silence(outsamplesref->extended_data, 0,
-                               n_out,
-                               outsamplesref->ch_layout.nb_channels,
-                               outsamplesref->format);
+    if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts))
+        s->eof = status == AVERROR_EOF;
 
-        outsamplesref->pts = s->next_pts;
-        if (s->next_pts != AV_NOPTS_VALUE)
-            s->next_pts += av_rescale_q(n_out, (AVRational){1, outlink->sample_rate}, outlink->time_base);
+    if (s->eof) {
+        int ret = push_frame(outlink);
 
-        return ff_filter_frame(outlink, outsamplesref);
+        if (ret == AVERROR_EOF) {
+            ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts);
+            return 0;
+        }
+        return ret;
     }
-    return ret;
+
+    FF_FILTER_FORWARD_WANTED(outlink, inlink);
+
+    return FFERROR_NOT_READY;
 }
 
 static int config_output(AVFilterLink *outlink)
@@ -153,16 +191,14 @@ static const AVFilterPad apad_inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
-        .filter_frame = filter_frame,
     },
 };
 
 static const AVFilterPad apad_outputs[] = {
     {
         .name          = "default",
-        .request_frame = request_frame,
-        .config_props  = config_output,
         .type          = AVMEDIA_TYPE_AUDIO,
+        .config_props  = config_output,
     },
 };
 
@@ -170,6 +206,7 @@ const AVFilter ff_af_apad = {
     .name          = "apad",
     .description   = NULL_IF_CONFIG_SMALL("Pad audio with silence."),
     .init          = init,
+    .activate      = activate,
     .priv_size     = sizeof(APadContext),
     FILTER_INPUTS(apad_inputs),
     FILTER_OUTPUTS(apad_outputs),



More information about the ffmpeg-cvslog mailing list