avfilter: add vfrdet filter

Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
Paul B Mahol 2017-12-20 14:15:02 +01:00
parent 8d381b57fd
commit 9e40632668
6 changed files with 126 additions and 1 deletions

View File

@ -53,6 +53,7 @@ version <next>:
- bitstream filter for extracting E-AC-3 core
- Haivision SRT protocol via libsrt
- segafilm muxer
- vfrdet filter
version 3.4:

View File

@ -16248,6 +16248,17 @@ For example, to vertically flip a video with @command{ffmpeg}:
ffmpeg -i in.avi -vf "vflip" out.avi
@end example
@section vfrdet
Detect variable frame rate video.
This filter tries to detect if the input is variable or constant frame rate.
At end it will output number of frames detected as having variable delta pts,
and ones with constant delta pts.
If there was frames with variable delta, than it will also show min and max delta
encountered.
@anchor{vignette}
@section vignette

View File

@ -353,6 +353,7 @@ OBJS-$(CONFIG_USPP_FILTER) += vf_uspp.o
OBJS-$(CONFIG_VAGUEDENOISER_FILTER) += vf_vaguedenoiser.o
OBJS-$(CONFIG_VECTORSCOPE_FILTER) += vf_vectorscope.o
OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o
OBJS-$(CONFIG_VFRDET_FILTER) += vf_vfrdet.o
OBJS-$(CONFIG_VIDSTABDETECT_FILTER) += vidstabutils.o vf_vidstabdetect.o
OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER) += vidstabutils.o vf_vidstabtransform.o
OBJS-$(CONFIG_VIGNETTE_FILTER) += vf_vignette.o

View File

@ -343,6 +343,7 @@ extern AVFilter ff_vf_uspp;
extern AVFilter ff_vf_vaguedenoiser;
extern AVFilter ff_vf_vectorscope;
extern AVFilter ff_vf_vflip;
extern AVFilter ff_vf_vfrdet;
extern AVFilter ff_vf_vidstabdetect;
extern AVFilter ff_vf_vidstabtransform;
extern AVFilter ff_vf_vignette;

View File

@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFILTER_VERSION_MAJOR 7
#define LIBAVFILTER_VERSION_MINOR 14
#define LIBAVFILTER_VERSION_MINOR 15
#define LIBAVFILTER_VERSION_MICRO 100
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \

111
libavfilter/vf_vfrdet.c Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright (C) 2017 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/common.h"
#include "libavutil/opt.h"
#include "internal.h"
typedef struct VFRDETContext {
const AVClass *class;
int64_t prev_pts;
int64_t delta;
int64_t min_delta;
int64_t max_delta;
uint64_t vfr;
uint64_t cfr;
} VFRDETContext;
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
VFRDETContext *s = ctx->priv;
if (s->prev_pts != AV_NOPTS_VALUE) {
int64_t delta = in->pts - s->prev_pts;
if (s->delta == AV_NOPTS_VALUE) {
s->delta = delta;
}
if (s->delta != delta) {
s->vfr++;
s->delta = delta;
s->min_delta = FFMIN(delta, s->min_delta);
s->max_delta = FFMAX(delta, s->max_delta);
} else {
s->cfr++;
}
}
s->prev_pts = in->pts;
return ff_filter_frame(ctx->outputs[0], in);
}
static av_cold int init(AVFilterContext *ctx)
{
VFRDETContext *s = ctx->priv;
s->prev_pts = AV_NOPTS_VALUE;
s->delta = AV_NOPTS_VALUE;
s->min_delta = INT64_MAX;
s->max_delta = INT64_MIN;
return 0;
}
static av_cold void uninit(AVFilterContext *ctx)
{
VFRDETContext *s = ctx->priv;
av_log(ctx, AV_LOG_INFO, "VFR:%f (%"PRIu64"/%"PRIu64")", s->vfr / (float)(s->vfr + s->cfr), s->vfr, s->cfr);
if (s->vfr)
av_log(ctx, AV_LOG_INFO, " min: %"PRId64" max: %"PRId64")", s->min_delta, s->max_delta);
av_log(ctx, AV_LOG_INFO, "\n");
}
static const AVFilterPad vfrdet_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
},
{ NULL }
};
static const AVFilterPad vfrdet_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
},
{ NULL }
};
AVFilter ff_vf_vfrdet = {
.name = "vfrdet",
.description = NULL_IF_CONFIG_SMALL("Variable frame rate detect filter."),
.priv_size = sizeof(VFRDETContext),
.init = init,
.uninit = uninit,
.inputs = vfrdet_inputs,
.outputs = vfrdet_outputs,
};