diff options
Diffstat (limited to 'libavfilter/vf_setpts.c')
-rw-r--r-- | libavfilter/vf_setpts.c | 97 |
1 files changed, 75 insertions, 22 deletions
diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c index e347716dff..62ac9ab87c 100644 --- a/libavfilter/vf_setpts.c +++ b/libavfilter/vf_setpts.c @@ -2,20 +2,20 @@ * Copyright (c) 2010 Stefano Sabatini * Copyright (c) 2008 Victor Paesa * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -31,33 +31,34 @@ #include "libavutil/mathematics.h" #include "avfilter.h" #include "internal.h" +#include "audio.h" #include "video.h" static const char *const var_names[] = { - "E", ///< Euler number "INTERLACED", ///< tell if the current frame is interlaced "N", ///< frame number (starting at zero) - "PHI", ///< golden ratio - "PI", ///< greek pi + "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 "PREV_INPTS", ///< previous input PTS "PREV_OUTPTS", ///< previous output PTS "PTS", ///< original pts in the file of the frame - "STARTPTS", ///< PTS at start of movie + "SAMPLE_RATE", ///< sample rate (only audio) + "STARTPTS", ///< PTS at start of movie "TB", ///< timebase NULL }; enum var_name { - VAR_E, VAR_INTERLACED, VAR_N, - VAR_PHI, - VAR_PI, + VAR_NB_CONSUMED_SAMPLES, + VAR_NB_SAMPLES, VAR_POS, VAR_PREV_INPTS, VAR_PREV_OUTPTS, VAR_PTS, + VAR_SAMPLE_RATE, VAR_STARTPTS, VAR_TB, VAR_VARS_NB @@ -66,6 +67,7 @@ enum var_name { typedef struct { AVExpr *expr; double var_values[VAR_VARS_NB]; + enum AVMediaType type; } SetPTSContext; static av_cold int init(AVFilterContext *ctx, const char *args) @@ -79,10 +81,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args) return ret; } - setpts->var_values[VAR_E ] = M_E; setpts->var_values[VAR_N ] = 0.0; - setpts->var_values[VAR_PHI ] = M_PHI; - setpts->var_values[VAR_PI ] = M_PI; setpts->var_values[VAR_PREV_INPTS ] = NAN; setpts->var_values[VAR_PREV_OUTPTS] = NAN; setpts->var_values[VAR_STARTPTS ] = NAN; @@ -91,18 +90,24 @@ static av_cold int init(AVFilterContext *ctx, const char *args) static int config_input(AVFilterLink *inlink) { - SetPTSContext *setpts = inlink->dst->priv; + AVFilterContext *ctx = inlink->dst; + SetPTSContext *setpts = ctx->priv; + setpts->type = inlink->type; setpts->var_values[VAR_TB] = av_q2d(inlink->time_base); - av_log(inlink->src, AV_LOG_VERBOSE, "TB:%f\n", setpts->var_values[VAR_TB]); + if (setpts->type == AVMEDIA_TYPE_AUDIO) + setpts->var_values[VAR_SAMPLE_RATE] = inlink->sample_rate; + + av_log(inlink->src, AV_LOG_VERBOSE, "TB:%f SAMPLE_RATE:%f\n", + setpts->var_values[VAR_TB], setpts->var_values[VAR_SAMPLE_RATE]); return 0; } #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { SetPTSContext *setpts = inlink->dst->priv; double d; @@ -113,28 +118,45 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) if (isnan(setpts->var_values[VAR_STARTPTS])) setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts); - - setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced; setpts->var_values[VAR_PTS ] = TS2D(inpicref->pts); setpts->var_values[VAR_POS ] = inpicref->pos == -1 ? NAN : inpicref->pos; + switch (inlink->type) { + case AVMEDIA_TYPE_VIDEO: + setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced; + break; + + case AVMEDIA_TYPE_AUDIO: + setpts->var_values[VAR_NB_SAMPLES] = inpicref->audio->nb_samples; + break; + } + d = av_expr_eval(setpts->expr, setpts->var_values, NULL); outpicref->pts = D2TS(d); #ifdef DEBUG av_log(inlink->dst, AV_LOG_DEBUG, - "n:%"PRId64" interlaced:%d pos:%"PRId64" pts:%"PRId64" t:%f -> pts:%"PRId64" t:%f\n", + "n:%"PRId64" interlaced:%d nb_samples:%d nb_consumed_samples:%d " + "pos:%"PRId64" pts:%"PRId64" t:%f -> pts:%"PRId64" t:%f\n", (int64_t)setpts->var_values[VAR_N], (int)setpts->var_values[VAR_INTERLACED], + (int)setpts->var_values[VAR_NB_SAMPLES], + (int)setpts->var_values[VAR_NB_CONSUMED_SAMPLES], inpicref ->pos, inpicref ->pts, inpicref ->pts * av_q2d(inlink->time_base), outpicref->pts, outpicref->pts * av_q2d(inlink->time_base)); + #endif setpts->var_values[VAR_N] += 1.0; setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts); setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts); - return ff_start_frame(inlink->dst->outputs[0], outpicref); + + if (setpts->type == AVMEDIA_TYPE_AUDIO) { + setpts->var_values[VAR_NB_CONSUMED_SAMPLES] += inpicref->audio->nb_samples; + return ff_filter_samples(inlink->dst->outputs[0], outpicref); + } else + return ff_start_frame (inlink->dst->outputs[0], outpicref); } static av_cold void uninit(AVFilterContext *ctx) @@ -144,6 +166,36 @@ static av_cold void uninit(AVFilterContext *ctx) setpts->expr = NULL; } +#if CONFIG_ASETPTS_FILTER +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), + + .inputs = (const AVFilterPad[]) { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .get_audio_buffer = ff_null_get_audio_buffer, + .config_props = config_input, + .filter_samples = filter_frame, + }, + { .name = NULL } + }, + .outputs = (const AVFilterPad[]) { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + }, + { .name = NULL } + }, +}; +#endif /* CONFIG_ASETPTS_FILTER */ + +#if CONFIG_SETPTS_FILTER AVFilter avfilter_vf_setpts = { .name = "setpts", .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."), @@ -156,9 +208,10 @@ AVFilter avfilter_vf_setpts = { .type = AVMEDIA_TYPE_VIDEO, .get_video_buffer = ff_null_get_video_buffer, .config_props = config_input, - .start_frame = start_frame, }, + .start_frame = filter_frame, }, { .name = NULL }}, .outputs = (const AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, }, { .name = NULL}}, }; +#endif /* CONFIG_SETPTS_FILTER */ |