[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