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 (!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 (s->whole_len >= 0 && s->pad_len < 0) { + s->pad_len = s->pad_len_left = s->whole_len_left; } - return ret; + 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); +} + +static int activate(AVFilterContext *ctx) +{ + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + APadContext *s = ctx->priv; + int64_t pts; + int status; + + 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); + if (ret < 0) + return ret; + if (ret > 0) + return filter_frame(inlink, frame); + } + + if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) + s->eof = status == AVERROR_EOF; + + if (s->eof) { + int ret = push_frame(outlink); + + if (ret == AVERROR_EOF) { + ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts); + return 0; + } + 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),