Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavfilter
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/internal.h
"
31
#include "
libavutil/mathematics.h
"
32
#include "
avfilter.h
"
33
#include "
internal.h
"
34
#include "
video.h
"
35
36
static
const
char
*
const
var_names
[] = {
37
"E"
,
38
"INTERLACED"
,
39
"N"
,
40
"PHI"
,
41
"PI"
,
42
"POS"
,
43
"PREV_INPTS"
,
44
"PREV_OUTPTS"
,
45
"PTS"
,
46
"STARTPTS"
,
47
"TB"
,
48
NULL
49
};
50
51
enum
var_name
{
52
VAR_E
,
53
VAR_INTERLACED
,
54
VAR_N
,
55
VAR_PHI
,
56
VAR_PI
,
57
VAR_POS
,
58
VAR_PREV_INPTS
,
59
VAR_PREV_OUTPTS
,
60
VAR_PTS
,
61
VAR_STARTPTS
,
62
VAR_TB
,
63
VAR_VARS_NB
64
};
65
66
typedef
struct
{
67
AVExpr
*
expr
;
68
double
var_values[
VAR_VARS_NB
];
69
}
SetPTSContext
;
70
71
static
av_cold
int
init
(
AVFilterContext
*ctx,
const
char
*args)
72
{
73
SetPTSContext
*setpts = ctx->
priv
;
74
int
ret;
75
76
if
((ret =
av_expr_parse
(&setpts->
expr
, args ? args :
"PTS"
,
77
var_names
,
NULL
,
NULL
,
NULL
,
NULL
, 0, ctx)) < 0) {
78
av_log
(ctx,
AV_LOG_ERROR
,
"Error while parsing expression '%s'\n"
, args);
79
return
ret;
80
}
81
82
setpts->
var_values
[
VAR_E
] =
M_E
;
83
setpts->
var_values
[
VAR_N
] = 0.0;
84
setpts->
var_values
[
VAR_PHI
] =
M_PHI
;
85
setpts->
var_values
[
VAR_PI
] = M_PI;
86
setpts->
var_values
[
VAR_PREV_INPTS
] =
NAN
;
87
setpts->
var_values
[
VAR_PREV_OUTPTS
] =
NAN
;
88
setpts->
var_values
[
VAR_STARTPTS
] =
NAN
;
89
return
0;
90
}
91
92
static
int
config_input
(
AVFilterLink
*inlink)
93
{
94
SetPTSContext
*setpts = inlink->
dst
->
priv
;
95
96
setpts->
var_values
[
VAR_TB
] =
av_q2d
(inlink->
time_base
);
97
98
av_log
(inlink->
src
,
AV_LOG_VERBOSE
,
"TB:%f\n"
, setpts->
var_values
[
VAR_TB
]);
99
return
0;
100
}
101
102
#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
103
#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
104
105
static
int
filter_frame
(
AVFilterLink
*inlink,
AVFilterBufferRef
*frame)
106
{
107
SetPTSContext
*setpts = inlink->
dst
->
priv
;
108
int64_t in_pts = frame->
pts
;
109
double
d;
110
111
if
(
isnan
(setpts->
var_values
[
VAR_STARTPTS
]))
112
setpts->
var_values
[
VAR_STARTPTS
] =
TS2D
(frame->
pts
);
113
114
setpts->
var_values
[
VAR_INTERLACED
] = frame->
video
->
interlaced
;
115
setpts->
var_values
[
VAR_PTS
] =
TS2D
(frame->
pts
);
116
setpts->
var_values
[
VAR_POS
] = frame->
pos
== -1 ?
NAN
: frame->
pos
;
117
118
d =
av_expr_eval
(setpts->
expr
, setpts->
var_values
,
NULL
);
119
frame->
pts
=
D2TS
(d);
120
121
#ifdef DEBUG
122
av_log
(inlink->
dst
,
AV_LOG_DEBUG
,
123
"n:%"
PRId64
" interlaced:%d pos:%"
PRId64
" pts:%"
PRId64
" t:%f -> pts:%"
PRId64
" t:%f\n"
,
124
(int64_t)setpts->
var_values
[
VAR_N
],
125
(
int
)setpts->
var_values
[
VAR_INTERLACED
],
126
frame->
pos
, in_pts, in_pts *
av_q2d
(inlink->
time_base
),
127
frame->
pts
, frame->
pts
*
av_q2d
(inlink->
time_base
));
128
#endif
129
130
131
setpts->
var_values
[
VAR_N
] += 1.0;
132
setpts->
var_values
[
VAR_PREV_INPTS
] =
TS2D
(in_pts);
133
setpts->
var_values
[
VAR_PREV_OUTPTS
] =
TS2D
(frame->
pts
);
134
return
ff_filter_frame
(inlink->
dst
->
outputs
[0], frame);
135
}
136
137
static
av_cold
void
uninit
(
AVFilterContext
*ctx)
138
{
139
SetPTSContext
*setpts = ctx->
priv
;
140
av_expr_free
(setpts->
expr
);
141
setpts->
expr
=
NULL
;
142
}
143
144
static
const
AVFilterPad
avfilter_vf_setpts_inputs
[] = {
145
{
146
.
name
=
"default"
,
147
.type =
AVMEDIA_TYPE_VIDEO
,
148
.get_video_buffer =
ff_null_get_video_buffer
,
149
.config_props =
config_input
,
150
.filter_frame =
filter_frame
,
151
},
152
{
NULL
}
153
};
154
155
static
const
AVFilterPad
avfilter_vf_setpts_outputs
[] = {
156
{
157
.
name
=
"default"
,
158
.type =
AVMEDIA_TYPE_VIDEO
,
159
},
160
{
NULL
}
161
};
162
163
AVFilter
avfilter_vf_setpts
= {
164
.
name
=
"setpts"
,
165
.description =
NULL_IF_CONFIG_SMALL
(
"Set PTS for the output video frame."
),
166
.init =
init
,
167
.uninit =
uninit
,
168
169
.priv_size =
sizeof
(
SetPTSContext
),
170
171
.
inputs
= avfilter_vf_setpts_inputs,
172
.
outputs
= avfilter_vf_setpts_outputs,
173
};