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
4343 - MP2 encoding via TwoLAME
4444 - bmp parser
4545 - smptebars source
46+- asetpts filter
4647
4748
4849 version 0.11:
doc/filters.texi+17−2
@@ -3032,9 +3032,11 @@ Mark the frame as top-field-first. · 3031 unmodified lines
30323032 Mark the frame as progressive.
30333033 @end table
30343034
3035−@section setpts
3035+@section asetpts, setpts
30363036
3037−Change the PTS (presentation timestamp) of the input video frames.
3037+Change the PTS (presentation timestamp) of the input frames.
3038+
3039+@code{asetpts} works on audio frames, @code{setpts} on video frames.
30383040
30393041 Accept in input an expression evaluated through the eval API, which
30403042 can contain the following constants:
@@ -3046,6 +3048,16 @@ the presentation timestamp in input · 5 unmodified lines
30463048 @item N
30473049 the count of the input frame, starting from 0.
30483050
3051+@item NB_CONSUMED_SAMPLES
3052+the number of consumed samples, not including the current frame (only
3053+audio)
3054+
3055+@item NB_SAMPLES
3056+the number of samples in the current frame (only audio)
3057+
3058+@item SAMPLE_RATE
3059+audio sample rate
3060+
30493061 @item STARTPTS
30503062 the PTS of the first video frame
30513063
@@ -3084,6 +3096,9 @@ setpts=N/(25*TB) · 32 unmodified lines
30843096
30853097 # fixed rate 25 fps with some jitter
30863098 setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'
3099+
3100+# apply an offset of 10 seconds to the input PTS
3101+setpts=PTS+10/TB
30873102 @end example
30883103
30893104 @section settb, asettb
libavfilter/Makefile+1−0
@@ -52,6 +52,7 @@ OBJS-$(CONFIG_AMIX_FILTER) += af_amix.o · 51 unmodified lines
5252 OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o
5353 OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o
5454 OBJS-$(CONFIG_ASETNSAMPLES_FILTER) += af_asetnsamples.o
55+OBJS-$(CONFIG_ASETPTS_FILTER) += vf_setpts.o
5556 OBJS-$(CONFIG_ASETTB_FILTER) += f_settb.o
5657 OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o
5758 OBJS-$(CONFIG_ASPLIT_FILTER) += split.o
libavfilter/allfilters.c+1−0
@@ -42,6 +42,7 @@ void avfilter_register_all(void) · 41 unmodified lines
4242 REGISTER_FILTER (ANULL, anull, af);
4343 REGISTER_FILTER (ARESAMPLE, aresample, af);
4444 REGISTER_FILTER (ASETNSAMPLES, asetnsamples, af);
45+ REGISTER_FILTER (ASETPTS, asetpts, af);
4546 REGISTER_FILTER (ASETTB, asettb, af);
4647 REGISTER_FILTER (ASHOWINFO, ashowinfo, af);
4748 REGISTER_FILTER (ASPLIT, asplit, af);
libavfilter/version.h+1−1
@@ -29,7 +29,7 @@ · 28 unmodified lines
2929 #include "libavutil/avutil.h"
3030
3131 #define LIBAVFILTER_VERSION_MAJOR 3
32−#define LIBAVFILTER_VERSION_MINOR 6
32+#define LIBAVFILTER_VERSION_MINOR 7
3333 #define LIBAVFILTER_VERSION_MICRO 100
3434
3535 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
libavfilter/vf_setpts.c+71−9
@@ -30,16 +30,20 @@ · 29 unmodified lines
3030 #include "libavutil/mathematics.h"
3131 #include "avfilter.h"
3232 #include "internal.h"
33+#include "audio.h"
3334 #include "video.h"
3435
3536 static const char *const var_names[] = {
3637 "INTERLACED", ///< tell if the current frame is interlaced
3738 "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)
3841 "POS", ///< original position in the file of the frame
3942 "PREV_INPTS", ///< previous input PTS
4043 "PREV_OUTPTS", ///< previous output PTS
4144 "PTS", ///< original pts in the file of the frame
42− "STARTPTS", ///< PTS at start of movie
45+ "SAMPLE_RATE", ///< sample rate (only audio)
46+ "STARTPTS", ///< PTS at start of movie
4347 "TB", ///< timebase
4448 NULL
4549 };
@@ -47,10 +51,13 @@ static const char *const var_names[] = { · 1 unmodified line
4751 enum var_name {
4852 VAR_INTERLACED,
4953 VAR_N,
54+ VAR_NB_CONSUMED_SAMPLES,
55+ VAR_NB_SAMPLES,
5056 VAR_POS,
5157 VAR_PREV_INPTS,
5258 VAR_PREV_OUTPTS,
5359 VAR_PTS,
60+ VAR_SAMPLE_RATE,
5461 VAR_STARTPTS,
5562 VAR_TB,
5663 VAR_VARS_NB
@@ -59,6 +66,7 @@ enum var_name { · 2 unmodified lines
5966 typedef struct {
6067 AVExpr *expr;
6168 double var_values[VAR_VARS_NB];
69+ enum AVMediaType type;
6270 } SetPTSContext;
6371
6472 static 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
8189
8290 static int config_input(AVFilterLink *inlink)
8391 {
84− SetPTSContext *setpts = inlink->dst->priv;
92+ AVFilterContext *ctx = inlink->dst;
93+ SetPTSContext *setpts = ctx->priv;
8594
95+ setpts->type = inlink->type;
8696 setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
8797
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]);
89103 return 0;
90104 }
91105
92106 #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
93107 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
94108
95−static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
109+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
96110 {
97111 SetPTSContext *setpts = inlink->dst->priv;
98112 double d;
@@ -103,28 +117,45 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) · 4 unmodified lines
103117
104118 if (isnan(setpts->var_values[VAR_STARTPTS]))
105119 setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts);
106−
107− setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced;
108120 setpts->var_values[VAR_PTS ] = TS2D(inpicref->pts);
109121 setpts->var_values[VAR_POS ] = inpicref->pos == -1 ? NAN : inpicref->pos;
110122
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+
111133 d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
112134 outpicref->pts = D2TS(d);
113135
114136 #ifdef DEBUG
115137 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",
117140 (int64_t)setpts->var_values[VAR_N],
118141 (int)setpts->var_values[VAR_INTERLACED],
142+ (int)setpts->var_values[VAR_NB_SAMPLES],
143+ (int)setpts->var_values[VAR_NB_CONSUMED_SAMPLES],
119144 inpicref ->pos,
120145 inpicref ->pts, inpicref ->pts * av_q2d(inlink->time_base),
121146 outpicref->pts, outpicref->pts * av_q2d(inlink->time_base));
147+
122148 #endif
123149
124150 setpts->var_values[VAR_N] += 1.0;
125151 setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
126152 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);
128159 }
129160
130161 static av_cold void uninit(AVFilterContext *ctx)
@@ -134,6 +165,36 @@ static av_cold void uninit(AVFilterContext *ctx) · 3 unmodified lines
134165 setpts->expr = NULL;
135166 }
136167
168+#if CONFIG_ASETPTS_FILTER
169+AVFilter 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
137198 AVFilter avfilter_vf_setpts = {
138199 .name = "setpts",
139200 .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
@@ -146,9 +207,10 @@ AVFilter avfilter_vf_setpts = { · 6 unmodified lines
146207 .type = AVMEDIA_TYPE_VIDEO,
147208 .get_video_buffer = ff_null_get_video_buffer,
148209 .config_props = config_input,
149− .start_frame = start_frame, },
210+ .start_frame = filter_frame, },
150211 { .name = NULL }},
151212 .outputs = (const AVFilterPad[]) {{ .name = "default",
152213 .type = AVMEDIA_TYPE_VIDEO, },
153214 { .name = NULL}},
154215 };
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