vf_setpts.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Stefano Sabatini
3  * Copyright (c) 2008 Victor Paesa
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
27 /* #define DEBUG */
28 
29 #include "libavutil/eval.h"
30 #include "libavutil/mathematics.h"
31 #include "avfilter.h"
32 
33 static const char *var_names[] = {
34  "E",
35  "INTERLACED",
36  "N",
37  "PHI",
38  "PI",
39  "POS",
40  "PREV_INPTS",
41  "PREV_OUTPTS",
42  "PTS",
43  "STARTPTS",
44  "TB",
45  NULL
46 };
47 
48 enum var_name {
61 };
62 
63 typedef struct {
65  double var_values[VAR_VARS_NB];
67 
68 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
69 {
70  SetPTSContext *setpts = ctx->priv;
71  int ret;
72 
73  if ((ret = av_expr_parse(&setpts->expr, args ? args : "PTS",
74  var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
75  av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
76  return ret;
77  }
78 
79  setpts->var_values[VAR_E ] = M_E;
80  setpts->var_values[VAR_N ] = 0.0;
81  setpts->var_values[VAR_PHI ] = M_PHI;
82  setpts->var_values[VAR_PI ] = M_PI;
83  setpts->var_values[VAR_PREV_INPTS ] = NAN;
84  setpts->var_values[VAR_PREV_OUTPTS] = NAN;
85  setpts->var_values[VAR_STARTPTS ] = NAN;
86  return 0;
87 }
88 
89 static int config_input(AVFilterLink *inlink)
90 {
91  SetPTSContext *setpts = inlink->dst->priv;
92 
93  setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
94 
95  av_log(inlink->src, AV_LOG_INFO, "TB:%f\n", setpts->var_values[VAR_TB]);
96  return 0;
97 }
98 
99 #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
100 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
101 
102 static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
103 {
104  SetPTSContext *setpts = inlink->dst->priv;
105  double d;
106  AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
107 
108  if (isnan(setpts->var_values[VAR_STARTPTS]))
109  setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts);
110 
111  setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced;
112  setpts->var_values[VAR_PTS ] = TS2D(inpicref->pts);
113  setpts->var_values[VAR_POS ] = inpicref->pos == -1 ? NAN : inpicref->pos;
114 
115  d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
116  outpicref->pts = D2TS(d);
117 
118 #ifdef DEBUG
119  av_log(inlink->dst, AV_LOG_DEBUG,
120  "n:%"PRId64" interlaced:%d pos:%"PRId64" pts:%"PRId64" t:%f -> pts:%"PRId64" t:%f\n",
121  (int64_t)setpts->var_values[VAR_N],
122  (int)setpts->var_values[VAR_INTERLACED],
123  inpicref ->pos,
124  inpicref ->pts, inpicref ->pts * av_q2d(inlink->time_base),
125  outpicref->pts, outpicref->pts * av_q2d(inlink->time_base));
126 #endif
127 
128  setpts->var_values[VAR_N] += 1.0;
129  setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
130  setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);
131  avfilter_start_frame(inlink->dst->outputs[0], outpicref);
132 }
133 
134 static av_cold void uninit(AVFilterContext *ctx)
135 {
136  SetPTSContext *setpts = ctx->priv;
137  av_expr_free(setpts->expr);
138  setpts->expr = NULL;
139 }
140 
142  .name = "setpts",
143  .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
144  .init = init,
145  .uninit = uninit,
146 
147  .priv_size = sizeof(SetPTSContext),
148 
149  .inputs = (AVFilterPad[]) {{ .name = "default",
150  .type = AVMEDIA_TYPE_VIDEO,
151  .get_video_buffer = avfilter_null_get_video_buffer,
152  .config_props = config_input,
153  .start_frame = start_frame, },
154  { .name = NULL }},
155  .outputs = (AVFilterPad[]) {{ .name = "default",
156  .type = AVMEDIA_TYPE_VIDEO, },
157  { .name = NULL}},
158 };
AVFilterBufferRefVideoProps * video
video buffer specific properties
Definition: avfilter.h:141
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_setpts.c:134
double var_values[VAR_VARS_NB]
Definition: vf_setpts.c:65
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:465
#define av_cold
Definition: attributes.h:71
Definition: eval.c:119
static double av_q2d(AVRational a)
Convert rational to double.
Definition: rational.h:69
var_name
Definition: vf_boxblur.c:43
int64_t pts
presentation timestamp.
Definition: avfilter.h:135
static int config_input(AVFilterLink *inlink)
Definition: vf_setpts.c:89
A filter pad used for either input or output.
Definition: avfilter.h:312
AVFilter avfilter_vf_setpts
Definition: vf_setpts.c:141
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:191
static const char * var_names[]
Definition: vf_setpts.c:33
void * priv
private data for use by the filter
Definition: avfilter.h:553
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:140
#define NAN
Definition: mathematics.h:54
#define M_E
Definition: ratecontrol.c:39
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
Definition: vf_setpts.c:68
A reference to an AVFilterBuffer.
Definition: avfilter.h:124
NULL
Definition: eval.c:50
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:185
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:111
#define D2TS(d)
Definition: vf_setpts.c:99
Filter definition.
Definition: avfilter.h:497
AVFilterBufferRef * avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
Add a new reference to a buffer.
Definition: avfilter.c:47
void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
Notify the next filter of the start of a frame.
Definition: avfilter.c:400
#define M_PHI
Definition: mathematics.h:42
const char * name
filter name
Definition: avfilter.h:498
AVFilterBufferRef * avfilter_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
get_video_buffer() handler for filters which simply pass video along
Definition: defaults.c:288
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:551
int interlaced
is frame interlaced
Definition: avfilter.h:110
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:125
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
Definition: vf_setpts.c:102
int64_t pos
byte position in stream, -1 if unknown
Definition: avfilter.h:136
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:515
#define TS2D(ts)
Definition: vf_setpts.c:100
An instance of a filter.
Definition: avfilter.h:538
#define AV_LOG_INFO
Definition: log.h:119
AVExpr * expr
Definition: vf_setpts.c:64
#define M_PI
Definition: cos_tablegen.c:28
simple arithmetic expression evaluator