avfilter: add (a)latency filters

This commit is contained in:
Paul B Mahol 2021-09-08 17:51:17 +02:00
parent 1f447fd954
commit ba63078b0f
6 changed files with 171 additions and 2 deletions

View File

@ -22,6 +22,7 @@ version <next>:
- apsyclip audio filter
- morpho video filter
- amr parser
- (a)latency filters
version 4.4:

View File

@ -25829,6 +25829,15 @@ select='if(gt(random(0), 0.2), 1, 2)':n=2 [tmp], boxblur=2:2, [tmp] interleave
@end example
@end itemize
@section latency, alatency
Measure filtering latency.
Report previous filter filtering latency, delay in number of audio samples for audio filters
or number of video frames for video filters.
On end of input stream, filter will report min and max measured latency for previous running filter
in filtergraph.
@section metadata, ametadata
Manipulate frame metadata.

View File

@ -59,6 +59,7 @@ OBJS-$(CONFIG_AGATE_FILTER) += af_agate.o
OBJS-$(CONFIG_AIIR_FILTER) += af_aiir.o
OBJS-$(CONFIG_AINTEGRAL_FILTER) += af_aderivative.o
OBJS-$(CONFIG_AINTERLEAVE_FILTER) += f_interleave.o
OBJS-$(CONFIG_ALATENCY_FILTER) += f_latency.o
OBJS-$(CONFIG_ALIMITER_FILTER) += af_alimiter.o
OBJS-$(CONFIG_ALLPASS_FILTER) += af_biquads.o
OBJS-$(CONFIG_ALOOP_FILTER) += f_loop.o
@ -317,6 +318,7 @@ OBJS-$(CONFIG_INTERLEAVE_FILTER) += f_interleave.o
OBJS-$(CONFIG_KERNDEINT_FILTER) += vf_kerndeint.o
OBJS-$(CONFIG_KIRSCH_FILTER) += vf_convolution.o
OBJS-$(CONFIG_LAGFUN_FILTER) += vf_lagfun.o
OBJS-$(CONFIG_LATENCY_FILTER) += f_latency.o
OBJS-$(CONFIG_LENSCORRECTION_FILTER) += vf_lenscorrection.o
OBJS-$(CONFIG_LENSFUN_FILTER) += vf_lensfun.o
OBJS-$(CONFIG_LIBVMAF_FILTER) += vf_libvmaf.o framesync.o

View File

@ -52,6 +52,7 @@ extern const AVFilter ff_af_agate;
extern const AVFilter ff_af_aiir;
extern const AVFilter ff_af_aintegral;
extern const AVFilter ff_af_ainterleave;
extern const AVFilter ff_af_alatency;
extern const AVFilter ff_af_alimiter;
extern const AVFilter ff_af_allpass;
extern const AVFilter ff_af_aloop;
@ -302,6 +303,7 @@ extern const AVFilter ff_vf_interleave;
extern const AVFilter ff_vf_kerndeint;
extern const AVFilter ff_vf_kirsch;
extern const AVFilter ff_vf_lagfun;
extern const AVFilter ff_vf_latency;
extern const AVFilter ff_vf_lenscorrection;
extern const AVFilter ff_vf_lensfun;
extern const AVFilter ff_vf_libvmaf;

155
libavfilter/f_latency.c Normal file
View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 2021 Paul B Mahol
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/opt.h"
#include "avfilter.h"
#include "filters.h"
#include "formats.h"
#include "internal.h"
typedef struct LatencyContext {
int64_t min_latency;
int64_t max_latency;
int64_t sum;
} LatencyContext;
static av_cold int init(AVFilterContext *ctx)
{
LatencyContext *s = ctx->priv;
s->min_latency = INT64_MAX;
s->max_latency = INT64_MIN;
return 0;
}
static int activate(AVFilterContext *ctx)
{
LatencyContext *s = ctx->priv;
AVFilterLink *inlink = ctx->inputs[0];
AVFilterLink *outlink = ctx->outputs[0];
FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
if (!ctx->is_disabled && ctx->inputs[0]->src &&
ctx->inputs[0]->src->nb_inputs > 0) {
AVFilterLink *prevlink = ctx->inputs[0]->src->inputs[0];
int64_t delta = 0;
switch (prevlink->type) {
case AVMEDIA_TYPE_AUDIO:
delta = prevlink->sample_count_in - inlink->sample_count_out;
break;
case AVMEDIA_TYPE_VIDEO:
delta = prevlink->frame_count_in - inlink->frame_count_out;
break;
}
if (delta > 0) {
s->min_latency = FFMIN(s->min_latency, delta);
s->max_latency = FFMAX(s->max_latency, delta);
}
}
if (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 ff_filter_frame(outlink, frame);
}
FF_FILTER_FORWARD_STATUS(inlink, outlink);
FF_FILTER_FORWARD_WANTED(outlink, inlink);
return FFERROR_NOT_READY;
}
static av_cold void uninit(AVFilterContext *ctx)
{
LatencyContext *s = ctx->priv;
if (s->min_latency != INT64_MAX)
av_log(ctx, AV_LOG_INFO, "Min latency: %"PRId64"\n", s->min_latency);
if (s->max_latency != INT64_MIN)
av_log(ctx, AV_LOG_INFO, "Max latency: %"PRId64"\n", s->max_latency);
}
#if CONFIG_LATENCY_FILTER
static const AVFilterPad latency_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
},
};
static const AVFilterPad latency_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
},
};
const AVFilter ff_vf_latency = {
.name = "latency",
.description = NULL_IF_CONFIG_SMALL("Report video filtering latency."),
.priv_size = sizeof(LatencyContext),
.init = init,
.uninit = uninit,
.activate = activate,
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
FILTER_INPUTS(latency_inputs),
FILTER_OUTPUTS(latency_outputs),
};
#endif // CONFIG_LATENCY_FILTER
#if CONFIG_ALATENCY_FILTER
static const AVFilterPad alatency_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
},
};
static const AVFilterPad alatency_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_AUDIO,
},
};
const AVFilter ff_af_alatency = {
.name = "alatency",
.description = NULL_IF_CONFIG_SMALL("Report audio filtering latency."),
.priv_size = sizeof(LatencyContext),
.init = init,
.uninit = uninit,
.activate = activate,
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
FILTER_INPUTS(alatency_inputs),
FILTER_OUTPUTS(alatency_outputs),
};
#endif // CONFIG_ALATENCY_FILTER

View File

@ -30,8 +30,8 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 8
#define LIBAVFILTER_VERSION_MINOR 10
#define LIBAVFILTER_VERSION_MICRO 101
#define LIBAVFILTER_VERSION_MINOR 11
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \