diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-05-01 10:59:21 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-05-01 10:59:21 +0200 |
commit | 1cba7fa364a9c95773d779ff5d5602be8391310e (patch) | |
tree | 0b54487634827c984c861d025798d689e4e5b195 | |
parent | 0061ba044a44517d7291b80427cdebc5a1470c69 (diff) | |
parent | b472938233b98178ed6c1353c37e0dc7ab585902 (diff) | |
download | ffmpeg-1cba7fa364a9c95773d779ff5d5602be8391310e.tar.gz |
Merge commit 'b472938233b98178ed6c1353c37e0dc7ab585902'
* commit 'b472938233b98178ed6c1353c37e0dc7ab585902':
lavfi: add an asetpts filter
Conflicts:
Changelog
doc/filters.texi
libavfilter/Makefile
libavfilter/allfilters.c
libavfilter/f_setpts.c
libavfilter/setpts.c
libavfilter/version.h
libavfilter/vf_setpts.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | doc/filters.texi | 69 | ||||
-rw-r--r-- | libavfilter/Makefile | 4 | ||||
-rw-r--r-- | libavfilter/setpts.c (renamed from libavfilter/f_setpts.c) | 113 | ||||
-rw-r--r-- | libavfilter/version.h | 4 |
4 files changed, 129 insertions, 61 deletions
diff --git a/doc/filters.texi b/doc/filters.texi index 89d3dd7acd..2813ff3d59 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -933,6 +933,75 @@ disable padding for the last frame, use: asetnsamples=n=1234:p=0 @end example +@section asetpts + +Change the PTS (presentation timestamp) of the input audio frames. + +This filter accepts the following options: + +@table @option + +@item expr +The expression which is evaluated for each frame to construct its timestamp. + +@end table + +The expression is evaluated through the eval API and 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 +Number of the audio samples pass through the filter so far, starting at 0. + +@item S +Number of the audio samples in the current frame. + +@item SR +Audio sample rate. + +@item STARTPTS +the PTS of the first frame + +@item PREV_INPTS +previous input PTS + +@item PREV_OUTPTS +previous output PTS + +@item RTCTIME +wallclock (RTC) time in microseconds + +@item RTCSTART +wallclock (RTC) time at the start of the movie in microseconds + +@end table + +Some examples follow: + +@example +# start counting PTS from zero +asetpts=expr=PTS-STARTPTS + +#generate timestamps by counting samples +asetpts=expr=N/SR/TB + +# generate timestamps from a "live source" and rebase onto the current timebase +asetpts='(RTCTIME - RTCSTART) / (TB * 1000000)" +@end example + + @section asetrate Set the sample rate without altering the PCM data. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index d4ecf95b6f..04edff9d81 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -64,7 +64,7 @@ OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o OBJS-$(CONFIG_ASELECT_FILTER) += f_select.o OBJS-$(CONFIG_ASENDCMD_FILTER) += f_sendcmd.o OBJS-$(CONFIG_ASETNSAMPLES_FILTER) += af_asetnsamples.o -OBJS-$(CONFIG_ASETPTS_FILTER) += f_setpts.o +OBJS-$(CONFIG_ASETPTS_FILTER) += setpts.o OBJS-$(CONFIG_ASETRATE_FILTER) += af_asetrate.o OBJS-$(CONFIG_ASETTB_FILTER) += f_settb.o OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o @@ -163,7 +163,7 @@ OBJS-$(CONFIG_SELECT_FILTER) += f_select.o OBJS-$(CONFIG_SENDCMD_FILTER) += f_sendcmd.o OBJS-$(CONFIG_SETDAR_FILTER) += vf_aspect.o OBJS-$(CONFIG_SETFIELD_FILTER) += vf_setfield.o -OBJS-$(CONFIG_SETPTS_FILTER) += f_setpts.o +OBJS-$(CONFIG_SETPTS_FILTER) += setpts.o OBJS-$(CONFIG_SETSAR_FILTER) += vf_aspect.o OBJS-$(CONFIG_SETTB_FILTER) += f_settb.o OBJS-$(CONFIG_SHOWINFO_FILTER) += vf_showinfo.o diff --git a/libavfilter/f_setpts.c b/libavfilter/setpts.c index 648eec0802..97f2621bf3 100644 --- a/libavfilter/f_setpts.c +++ b/libavfilter/setpts.c @@ -29,15 +29,15 @@ #include "libavutil/mathematics.h" #include "libavutil/opt.h" #include "libavutil/time.h" +#include "audio.h" #include "avfilter.h" #include "internal.h" -#include "audio.h" #include "video.h" static const char *const var_names[] = { "FRAME_RATE", ///< defined only for constant frame-rate video "INTERLACED", ///< tell if the current frame is interlaced - "N", ///< frame number (starting at zero) + "N", ///< frame / sample number (starting at zero) "NB_CONSUMED_SAMPLES", ///< number of samples consumed by the filter (only audio) "NB_SAMPLES", ///< number of samples in the current frame (only audio) "POS", ///< original position in the file of the frame @@ -53,6 +53,8 @@ static const char *const var_names[] = { "TB", ///< timebase "RTCTIME", ///< wallclock (RTC) time in micro seconds "RTCSTART", ///< wallclock (RTC) time at the start of the movie in micro seconds + "S", // Number of samples in the current frame + "SR", // Audio sample rate NULL }; @@ -75,6 +77,8 @@ enum var_name { VAR_TB, VAR_RTCTIME, VAR_RTCSTART, + VAR_S, + VAR_SR, VAR_VARS_NB }; @@ -98,6 +102,7 @@ static av_cold int init(AVFilterContext *ctx) } setpts->var_values[VAR_N] = 0.0; + setpts->var_values[VAR_S] = 0.0; setpts->var_values[VAR_PREV_INPTS] = NAN; setpts->var_values[VAR_PREV_INT] = NAN; setpts->var_values[VAR_PREV_OUTPTS] = NAN; @@ -116,6 +121,7 @@ static int config_input(AVFilterLink *inlink) setpts->var_values[VAR_TB] = av_q2d(inlink->time_base); setpts->var_values[VAR_RTCSTART] = av_gettime(); + setpts->var_values[VAR_SR] = setpts->var_values[VAR_SAMPLE_RATE] = setpts->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN; @@ -159,17 +165,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) setpts->var_values[VAR_POS ] = av_frame_get_pkt_pos(frame) == -1 ? NAN : av_frame_get_pkt_pos(frame); setpts->var_values[VAR_RTCTIME ] = av_gettime(); - switch (inlink->type) { - case AVMEDIA_TYPE_VIDEO: + if (inlink->type == AVMEDIA_TYPE_VIDEO) { setpts->var_values[VAR_INTERLACED] = frame->interlaced_frame; - break; - - case AVMEDIA_TYPE_AUDIO: + } else if (inlink->type == AVMEDIA_TYPE_AUDIO) { + setpts->var_values[VAR_S] = frame->nb_samples; setpts->var_values[VAR_NB_SAMPLES] = frame->nb_samples; - break; } d = av_expr_eval(setpts->expr, setpts->var_values, NULL); + frame->pts = D2TS(d); av_log(inlink->dst, AV_LOG_DEBUG, "N:%"PRId64" PTS:%s T:%f POS:%s", @@ -190,13 +194,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) } av_log(inlink->dst, AV_LOG_DEBUG, " -> PTS:%s T:%f\n", d2istr(d), TS2T(d, inlink->time_base)); - frame->pts = D2TS(d); + if (inlink->type == AVMEDIA_TYPE_VIDEO) { + setpts->var_values[VAR_N] += 1.0; + } else { + setpts->var_values[VAR_N] += frame->nb_samples; + } setpts->var_values[VAR_PREV_INPTS ] = TS2D(in_pts); setpts->var_values[VAR_PREV_INT ] = TS2T(in_pts, inlink->time_base); setpts->var_values[VAR_PREV_OUTPTS] = TS2D(frame->pts); setpts->var_values[VAR_PREV_OUTT] = TS2T(frame->pts, inlink->time_base); - setpts->var_values[VAR_N] += 1.0; if (setpts->type == AVMEDIA_TYPE_AUDIO) { setpts->var_values[VAR_NB_CONSUMED_SAMPLES] += frame->nb_samples; } @@ -210,98 +217,90 @@ static av_cold void uninit(AVFilterContext *ctx) setpts->expr = NULL; } -#if CONFIG_ASETPTS_FILTER - #define OFFSET(x) offsetof(SetPTSContext, x) -#define AFLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM -static const AVOption aoptions[] = { - { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = AFLAGS }, +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM +static const AVOption options[] = { + { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = FLAGS }, { NULL }, }; -static const AVClass asetpts_class = { - .class_name = "asetpts", +#if CONFIG_SETPTS_FILTER +static const AVClass setpts_class = { + .class_name = "setpts", .item_name = av_default_item_name, - .option = aoptions, + .option = options, .version = LIBAVUTIL_VERSION_INT, }; -static const AVFilterPad avfilter_af_asetpts_inputs[] = { +static const AVFilterPad avfilter_vf_setpts_inputs[] = { { .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .get_audio_buffer = ff_null_get_audio_buffer, + .type = AVMEDIA_TYPE_VIDEO, + .get_video_buffer = ff_null_get_video_buffer, .config_props = config_input, .filter_frame = filter_frame, }, { NULL } }; -static const AVFilterPad avfilter_af_asetpts_outputs[] = { +static const AVFilterPad avfilter_vf_setpts_outputs[] = { { .name = "default", - .type = AVMEDIA_TYPE_AUDIO, + .type = AVMEDIA_TYPE_VIDEO, }, { NULL } }; -AVFilter avfilter_af_asetpts = { - .name = "asetpts", - .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."), +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), - .priv_class= &asetpts_class, - .inputs = avfilter_af_asetpts_inputs, - .outputs = avfilter_af_asetpts_outputs, -}; -#endif /* CONFIG_ASETPTS_FILTER */ -#if CONFIG_SETPTS_FILTER + .priv_size = sizeof(SetPTSContext), + .priv_class = &setpts_class, -#define OFFSET(x) offsetof(SetPTSContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM -static const AVOption options[] = { - { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = FLAGS }, - { NULL }, + .inputs = avfilter_vf_setpts_inputs, + .outputs = avfilter_vf_setpts_outputs, }; +#endif /* CONFIG_SETPTS_FILTER */ -static const AVClass setpts_class = { - .class_name = "setpts", +#if CONFIG_ASETPTS_FILTER + +static const AVClass asetpts_class = { + .class_name = "asetpts", .item_name = av_default_item_name, .option = options, .version = LIBAVUTIL_VERSION_INT, }; -static const AVFilterPad avfilter_vf_setpts_inputs[] = { +static const AVFilterPad asetpts_inputs[] = { { .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = ff_null_get_video_buffer, + .type = AVMEDIA_TYPE_AUDIO, + .get_audio_buffer = ff_null_get_audio_buffer, .config_props = config_input, .filter_frame = filter_frame, }, { NULL } }; -static const AVFilterPad avfilter_vf_setpts_outputs[] = { +static const AVFilterPad asetpts_outputs[] = { { .name = "default", - .type = AVMEDIA_TYPE_VIDEO, + .type = AVMEDIA_TYPE_AUDIO, }, { 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), - .priv_class = &setpts_class, - - .inputs = avfilter_vf_setpts_inputs, - .outputs = avfilter_vf_setpts_outputs, +AVFilter avfilter_af_asetpts = { + .name = "asetpts", + .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."), + .init = init, + .uninit = uninit, + .priv_size = sizeof(SetPTSContext), + .priv_class = &asetpts_class, + .inputs = asetpts_inputs, + .outputs = asetpts_outputs, }; -#endif /* CONFIG_SETPTS_FILTER */ +#endif /* CONFIG_ASETPTS_FILTER */ diff --git a/libavfilter/version.h b/libavfilter/version.h index e665ed0b09..21f8d5f73a 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -29,8 +29,8 @@ #include "libavutil/avutil.h" #define LIBAVFILTER_VERSION_MAJOR 3 -#define LIBAVFILTER_VERSION_MINOR 61 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MINOR 62 +#define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ |