Skip to content
Snippets Groups Projects
Commit a532bb39 authored by Stefano Sabatini's avatar Stefano Sabatini
Browse files

Add setpts filter, ported from the libavfilter soc repo.

Originally committed as revision 25655 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 6f84cd12
No related branches found
No related tags found
No related merge requests found
......@@ -51,6 +51,7 @@ version <next>:
- ffmpeg -force_key_frames option added
- demuxer for receiving raw rtp:// URLs without an SDP description
- single stream LATM/LOAS decoder
- setpts filter added
version 0.6:
......
......@@ -502,6 +502,66 @@ settb=2*intb
settb=AVTB
@end example
@section setpts
Change the PTS (presentation timestamp) of the input video frames.
Accept in input an expression evaluated through the eval API, which
can contain the following constants:
@table @option
@item PTS
the presentation timestamp in input
@item PI
Greek PI
@item PHI
golden ratio
@item E
Euler number
@item N
the count of the input frame, starting from 0.
@item STARTPTS
the PTS of the first video frame
@item INTERLACED
tell if the current frame is interlaced
@item POS
original position in the file of the frame, or undefined if undefined
for the current frame
@item PREV_INPTS
previous input PTS
@item PREV_OUTPTS
previous output PTS
@end table
Some examples follow:
@example
# start counting PTS from zero
setpts=PTS-STARTPTS
# fast motion
setpts=0.5*PTS
# slow motion
setpts=2.0*PTS
# fixed rate 25 fps
setpts=N/(25*TB)
# fixed rate 25 fps with some jitter
setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'
@end example
@section slicify
Pass the images of input video on to next video filter as multiple
......
......@@ -37,6 +37,7 @@ OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o
OBJS-$(CONFIG_PIXELASPECT_FILTER) += vf_aspect.o
OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o
OBJS-$(CONFIG_SETTB_FILTER) += vf_settb.o
OBJS-$(CONFIG_SETPTS_FILTER) += vf_setpts.o
OBJS-$(CONFIG_SLICIFY_FILTER) += vf_slicify.o
OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o
OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o
......
......@@ -57,6 +57,7 @@ void avfilter_register_all(void)
REGISTER_FILTER (PIXELASPECT, pixelaspect, vf);
REGISTER_FILTER (SCALE, scale, vf);
REGISTER_FILTER (SETTB, settb, vf);
REGISTER_FILTER (SETPTS, setpts, vf);
REGISTER_FILTER (SLICIFY, slicify, vf);
REGISTER_FILTER (TRANSPOSE, transpose, vf);
REGISTER_FILTER (UNSHARP, unsharp, vf);
......
......@@ -25,7 +25,7 @@
#include "libavutil/avutil.h"
#define LIBAVFILTER_VERSION_MAJOR 1
#define LIBAVFILTER_VERSION_MINOR 53
#define LIBAVFILTER_VERSION_MINOR 54
#define LIBAVFILTER_VERSION_MICRO 0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
......
/*
* Copyright (c) 2010 Stefano Sabatini
* Copyright (c) 2008 Victor Paesa
*
* 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
*/
/**
* @file
* video presentation timestamp (PTS) modification filter
*/
/* #define DEBUG */
#include "libavutil/eval.h"
#include "avfilter.h"
static const char *var_names[] = {
"E", ///< Euler number
"INTERLACED", ///< tell if the current frame is interlaced
"N", ///< frame number (starting at zero)
"PHI", ///< golden ratio
"PI", ///< greek pi
"POS", ///< original position in the file of the frame
"PREV_INPTS", ///< previous input PTS
"PREV_OUTPTS", ///< previous output PTS
"PTS", ///< original pts in the file of the frame
"STARTPTS", ///< PTS at start of movie
"TB", ///< timebase
NULL
};
enum var_name {
VAR_E,
VAR_INTERLACED,
VAR_N,
VAR_PHI,
VAR_PI,
VAR_POS,
VAR_PREV_INPTS,
VAR_PREV_OUTPTS,
VAR_PTS,
VAR_STARTPTS,
VAR_TB,
VAR_VARS_NB
};
typedef struct {
AVExpr *expr;
double var_values[VAR_VARS_NB];
} SetPTSContext;
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{
SetPTSContext *setpts = ctx->priv;
int ret;
if ((ret = av_parse_expr(&setpts->expr, args ? args : "PTS",
var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
return ret;
}
setpts->var_values[VAR_E ] = M_E;
setpts->var_values[VAR_N ] = 0.0;
setpts->var_values[VAR_PHI ] = M_PHI;
setpts->var_values[VAR_PI ] = M_PI;
setpts->var_values[VAR_PREV_INPTS ] = NAN;
setpts->var_values[VAR_PREV_OUTPTS] = NAN;
setpts->var_values[VAR_STARTPTS ] = NAN;
return 0;
}
static int config_input(AVFilterLink *inlink)
{
SetPTSContext *setpts = inlink->dst->priv;
setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
av_log(inlink->src, AV_LOG_INFO, "TB:%f\n", setpts->var_values[VAR_TB]);
return 0;
}
#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{
SetPTSContext *setpts = inlink->dst->priv;
double d;
AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
if (isnan(setpts->var_values[VAR_STARTPTS]))
setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts);
setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced;
setpts->var_values[VAR_PTS ] = TS2D(inpicref->pts);
setpts->var_values[VAR_POS ] = inpicref->pos == -1 ? NAN : inpicref->pos;
d = av_eval_expr(setpts->expr, setpts->var_values, NULL);
outpicref->pts = D2TS(d);
#ifdef DEBUG
av_log(inlink->dst, AV_LOG_DEBUG,
"n:%"PRId64" interlaced:%d pos:%d pts:%"PRId64" t:%f -> pts:%"PRId64" t:%f\n",
(int64_t)setpts->var_values[VAR_N],
(int)setpts->var_values[VAR_INTERLACED],
(int)setpts->var_values[VAR_POS],
inpicref ->pts, inpicref ->pts * av_q2d(inlink->time_base),
outpicref->pts, outpicref->pts * av_q2d(inlink->time_base));
#endif
setpts->var_values[VAR_N] += 1.0;
setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);
avfilter_start_frame(inlink->dst->outputs[0], outpicref);
}
static av_cold void uninit(AVFilterContext *ctx)
{
SetPTSContext *setpts = ctx->priv;
av_free_expr(setpts->expr);
setpts->expr = NULL;
}
AVFilter avfilter_vf_setpts = {
.name = "setpts",
.description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
.init = init,
.uninit = uninit,
.priv_size = sizeof(SetPTSContext),
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer = avfilter_null_get_video_buffer,
.config_props = config_input,
.start_frame = start_frame, },
{ .name = NULL }},
.outputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, },
{ .name = NULL}},
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment