History

lavfi: add asetpts audio filter

Based on an idea by Andrey Utkin <andrey.krieger.utkin@gmail.com>.

Stefano Sabatini committed 14 years ago

Commit f6580b51 parent 11a10336 files · +92 −12Browse files

Unified · Split

6 files
  1. Changelog +1 −0
  2. doc/filters.texi +17 −2
  3. libavfilter/Makefile +1 −0
  4. libavfilter/allfilters.c +1 −0
  5. libavfilter/version.h +1 −1
  6. libavfilter/vf_setpts.c +71 −9
Changelog+1−0
@@ -43,6 +43,7 @@ version next: · 42 unmodified lines
43- MP2 encoding via TwoLAME43- MP2 encoding via TwoLAME
44- bmp parser44- bmp parser
45- smptebars source45- smptebars source
46- asetpts filter
46 47
47 48
48version 0.11:49version 0.11:
doc/filters.texi+17−2
@@ -3032,9 +3032,11 @@ Mark the frame as top-field-first. · 3031 unmodified lines
3032Mark the frame as progressive.3032Mark the frame as progressive.
3033@end table3033@end table
3034 3034
3035@section setpts3035@section asetpts, setpts
3036 3036
3037Change the PTS (presentation timestamp) of the input video frames.3037Change the PTS (presentation timestamp) of the input frames.
3038
3039@code{asetpts} works on audio frames, @code{setpts} on video frames.
3038 3040
3039Accept in input an expression evaluated through the eval API, which3041Accept in input an expression evaluated through the eval API, which
3040can contain the following constants:3042can contain the following constants:
@@ -3046,6 +3048,16 @@ the presentation timestamp in input · 5 unmodified lines
3046@item N3048@item N
3047the count of the input frame, starting from 0.3049the count of the input frame, starting from 0.
3048 3050
3051@item NB_CONSUMED_SAMPLES
3052the number of consumed samples, not including the current frame (only
3053audio)
3054
3055@item NB_SAMPLES
3056the number of samples in the current frame (only audio)
3057
3058@item SAMPLE_RATE
3059audio sample rate
3060
3049@item STARTPTS3061@item STARTPTS
3050the PTS of the first video frame3062the PTS of the first video frame
3051 3063
@@ -3084,6 +3096,9 @@ setpts=N/(25*TB) · 32 unmodified lines
3084 3096
3085# fixed rate 25 fps with some jitter3097# fixed rate 25 fps with some jitter
3086setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'3098setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'
3099
3100# apply an offset of 10 seconds to the input PTS
3101setpts=PTS+10/TB
3087@end example3102@end example
3088 3103
3089@section settb, asettb3104@section settb, asettb
libavfilter/Makefile+1−0
@@ -52,6 +52,7 @@ OBJS-$(CONFIG_AMIX_FILTER) += af_amix.o · 51 unmodified lines
52OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o52OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o
53OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o53OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o
54OBJS-$(CONFIG_ASETNSAMPLES_FILTER) += af_asetnsamples.o54OBJS-$(CONFIG_ASETNSAMPLES_FILTER) += af_asetnsamples.o
55OBJS-$(CONFIG_ASETPTS_FILTER) += vf_setpts.o
55OBJS-$(CONFIG_ASETTB_FILTER) += f_settb.o56OBJS-$(CONFIG_ASETTB_FILTER) += f_settb.o
56OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o57OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o
57OBJS-$(CONFIG_ASPLIT_FILTER) += split.o58OBJS-$(CONFIG_ASPLIT_FILTER) += split.o
libavfilter/allfilters.c+1−0
@@ -42,6 +42,7 @@ void avfilter_register_all(void) · 41 unmodified lines
42 REGISTER_FILTER (ANULL, anull, af);42 REGISTER_FILTER (ANULL, anull, af);
43 REGISTER_FILTER (ARESAMPLE, aresample, af);43 REGISTER_FILTER (ARESAMPLE, aresample, af);
44 REGISTER_FILTER (ASETNSAMPLES, asetnsamples, af);44 REGISTER_FILTER (ASETNSAMPLES, asetnsamples, af);
45 REGISTER_FILTER (ASETPTS, asetpts, af);
45 REGISTER_FILTER (ASETTB, asettb, af);46 REGISTER_FILTER (ASETTB, asettb, af);
46 REGISTER_FILTER (ASHOWINFO, ashowinfo, af);47 REGISTER_FILTER (ASHOWINFO, ashowinfo, af);
47 REGISTER_FILTER (ASPLIT, asplit, af);48 REGISTER_FILTER (ASPLIT, asplit, af);
libavfilter/version.h+1−1
@@ -29,7 +29,7 @@ · 28 unmodified lines
29#include "libavutil/avutil.h"29#include "libavutil/avutil.h"
30 30
31#define LIBAVFILTER_VERSION_MAJOR 331#define LIBAVFILTER_VERSION_MAJOR 3
32#define LIBAVFILTER_VERSION_MINOR 632#define LIBAVFILTER_VERSION_MINOR 7
33#define LIBAVFILTER_VERSION_MICRO 10033#define LIBAVFILTER_VERSION_MICRO 100
34 34
35#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \35#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
libavfilter/vf_setpts.c+71−9
@@ -30,16 +30,20 @@ · 29 unmodified lines
30#include "libavutil/mathematics.h"30#include "libavutil/mathematics.h"
31#include "avfilter.h"31#include "avfilter.h"
32#include "internal.h"32#include "internal.h"
33#include "audio.h"
33#include "video.h"34#include "video.h"
34 35
35static const char *const var_names[] = {36static const char *const var_names[] = {
36 "INTERLACED", ///< tell if the current frame is interlaced37 "INTERLACED", ///< tell if the current frame is interlaced
37 "N", ///< frame number (starting at zero)38 "N", ///< frame number (starting at zero)
39 "NB_CONSUMED_SAMPLES", ///< number of samples consumed by the filter (only audio)
40 "NB_SAMPLES", ///< number of samples in the current frame (only audio)
38 "POS", ///< original position in the file of the frame41 "POS", ///< original position in the file of the frame
39 "PREV_INPTS", ///< previous input PTS42 "PREV_INPTS", ///< previous input PTS
40 "PREV_OUTPTS", ///< previous output PTS43 "PREV_OUTPTS", ///< previous output PTS
41 "PTS", ///< original pts in the file of the frame44 "PTS", ///< original pts in the file of the frame
42 "STARTPTS", ///< PTS at start of movie45 "SAMPLE_RATE", ///< sample rate (only audio)
46 "STARTPTS", ///< PTS at start of movie
43 "TB", ///< timebase47 "TB", ///< timebase
44 NULL48 NULL
45};49};
@@ -47,10 +51,13 @@ static const char *const var_names[] = { · 1 unmodified line
47enum var_name {51enum var_name {
48 VAR_INTERLACED,52 VAR_INTERLACED,
49 VAR_N,53 VAR_N,
54 VAR_NB_CONSUMED_SAMPLES,
55 VAR_NB_SAMPLES,
50 VAR_POS,56 VAR_POS,
51 VAR_PREV_INPTS,57 VAR_PREV_INPTS,
52 VAR_PREV_OUTPTS,58 VAR_PREV_OUTPTS,
53 VAR_PTS,59 VAR_PTS,
60 VAR_SAMPLE_RATE,
54 VAR_STARTPTS,61 VAR_STARTPTS,
55 VAR_TB,62 VAR_TB,
56 VAR_VARS_NB63 VAR_VARS_NB
@@ -59,6 +66,7 @@ enum var_name { · 2 unmodified lines
59typedef struct {66typedef struct {
60 AVExpr *expr;67 AVExpr *expr;
61 double var_values[VAR_VARS_NB];68 double var_values[VAR_VARS_NB];
69 enum AVMediaType type;
62} SetPTSContext;70} SetPTSContext;
63 71
64static av_cold int init(AVFilterContext *ctx, const char *args)72static av_cold int init(AVFilterContext *ctx, const char *args)
@@ -81,18 +89,24 @@ static av_cold int init(AVFilterContext *ctx, const char *args) · 16 unmodified lines
81 89
82static int config_input(AVFilterLink *inlink)90static int config_input(AVFilterLink *inlink)
83{91{
84 SetPTSContext *setpts = inlink->dst->priv;92 AVFilterContext *ctx = inlink->dst;
93 SetPTSContext *setpts = ctx->priv;
85 94
95 setpts->type = inlink->type;
86 setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);96 setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
87 97
88 av_log(inlink->src, AV_LOG_VERBOSE, "TB:%f\n", setpts->var_values[VAR_TB]);98 if (setpts->type == AVMEDIA_TYPE_AUDIO)
99 setpts->var_values[VAR_SAMPLE_RATE] = inlink->sample_rate;
100
101 av_log(inlink->src, AV_LOG_VERBOSE, "TB:%f SAMPLE_RATE:%f\n",
102 setpts->var_values[VAR_TB], setpts->var_values[VAR_SAMPLE_RATE]);
89 return 0;103 return 0;
90}104}
91 105
92#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))106#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
93#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))107#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
94 108
95static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)109static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
96{110{
97 SetPTSContext *setpts = inlink->dst->priv;111 SetPTSContext *setpts = inlink->dst->priv;
98 double d;112 double d;
@@ -103,28 +117,45 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) · 4 unmodified lines
103 117
104 if (isnan(setpts->var_values[VAR_STARTPTS]))118 if (isnan(setpts->var_values[VAR_STARTPTS]))
105 setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts);119 setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts);
106
107 setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced;
108 setpts->var_values[VAR_PTS ] = TS2D(inpicref->pts);120 setpts->var_values[VAR_PTS ] = TS2D(inpicref->pts);
109 setpts->var_values[VAR_POS ] = inpicref->pos == -1 ? NAN : inpicref->pos;121 setpts->var_values[VAR_POS ] = inpicref->pos == -1 ? NAN : inpicref->pos;
110 122
123 switch (inlink->type) {
124 case AVMEDIA_TYPE_VIDEO:
125 setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced;
126 break;
127
128 case AVMEDIA_TYPE_AUDIO:
129 setpts->var_values[VAR_NB_SAMPLES] = inpicref->audio->nb_samples;
130 break;
131 }
132
111 d = av_expr_eval(setpts->expr, setpts->var_values, NULL);133 d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
112 outpicref->pts = D2TS(d);134 outpicref->pts = D2TS(d);
113 135
114#ifdef DEBUG136#ifdef DEBUG
115 av_log(inlink->dst, AV_LOG_DEBUG,137 av_log(inlink->dst, AV_LOG_DEBUG,
116 "n:%"PRId64" interlaced:%d pos:%"PRId64" pts:%"PRId64" t:%f -> pts:%"PRId64" t:%f\n",138 "n:%"PRId64" interlaced:%d nb_samples:%d nb_consumed_samples:%d "
139 "pos:%"PRId64" pts:%"PRId64" t:%f -> pts:%"PRId64" t:%f\n",
117 (int64_t)setpts->var_values[VAR_N],140 (int64_t)setpts->var_values[VAR_N],
118 (int)setpts->var_values[VAR_INTERLACED],141 (int)setpts->var_values[VAR_INTERLACED],
142 (int)setpts->var_values[VAR_NB_SAMPLES],
143 (int)setpts->var_values[VAR_NB_CONSUMED_SAMPLES],
119 inpicref ->pos,144 inpicref ->pos,
120 inpicref ->pts, inpicref ->pts * av_q2d(inlink->time_base),145 inpicref ->pts, inpicref ->pts * av_q2d(inlink->time_base),
121 outpicref->pts, outpicref->pts * av_q2d(inlink->time_base));146 outpicref->pts, outpicref->pts * av_q2d(inlink->time_base));
147
122#endif148#endif
123 149
124 setpts->var_values[VAR_N] += 1.0;150 setpts->var_values[VAR_N] += 1.0;
125 setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);151 setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
126 setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);152 setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);
127 return ff_start_frame(inlink->dst->outputs[0], outpicref);153
154 if (setpts->type == AVMEDIA_TYPE_AUDIO) {
155 setpts->var_values[VAR_NB_CONSUMED_SAMPLES] += inpicref->audio->nb_samples;
156 return ff_filter_samples(inlink->dst->outputs[0], outpicref);
157 } else
158 return ff_start_frame (inlink->dst->outputs[0], outpicref);
128}159}
129 160
130static av_cold void uninit(AVFilterContext *ctx)161static av_cold void uninit(AVFilterContext *ctx)
@@ -134,6 +165,36 @@ static av_cold void uninit(AVFilterContext *ctx) · 3 unmodified lines
134 setpts->expr = NULL;165 setpts->expr = NULL;
135}166}
136 167
168#if CONFIG_ASETPTS_FILTER
169AVFilter avfilter_af_asetpts = {
170 .name = "asetpts",
171 .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
172 .init = init,
173 .uninit = uninit,
174
175 .priv_size = sizeof(SetPTSContext),
176
177 .inputs = (const AVFilterPad[]) {
178 {
179 .name = "default",
180 .type = AVMEDIA_TYPE_AUDIO,
181 .get_audio_buffer = ff_null_get_audio_buffer,
182 .config_props = config_input,
183 .filter_samples = filter_frame,
184 },
185 { .name = NULL }
186 },
187 .outputs = (const AVFilterPad[]) {
188 {
189 .name = "default",
190 .type = AVMEDIA_TYPE_AUDIO,
191 },
192 { .name = NULL }
193 },
194};
195#endif /* CONFIG_ASETPTS_FILTER */
196
197#if CONFIG_SETPTS_FILTER
137AVFilter avfilter_vf_setpts = {198AVFilter avfilter_vf_setpts = {
138 .name = "setpts",199 .name = "setpts",
139 .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),200 .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
@@ -146,9 +207,10 @@ AVFilter avfilter_vf_setpts = { · 6 unmodified lines
146 .type = AVMEDIA_TYPE_VIDEO,207 .type = AVMEDIA_TYPE_VIDEO,
147 .get_video_buffer = ff_null_get_video_buffer,208 .get_video_buffer = ff_null_get_video_buffer,
148 .config_props = config_input,209 .config_props = config_input,
149 .start_frame = start_frame, },210 .start_frame = filter_frame, },
150 { .name = NULL }},211 { .name = NULL }},
151 .outputs = (const AVFilterPad[]) {{ .name = "default",212 .outputs = (const AVFilterPad[]) {{ .name = "default",
152 .type = AVMEDIA_TYPE_VIDEO, },213 .type = AVMEDIA_TYPE_VIDEO, },
153 { .name = NULL}},214 { .name = NULL}},
154};215};
216#endif /* CONFIG_SETPTS_FILTER */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t