]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/af_atempo.c
avfilter: Constify all AVFilters
[ffmpeg] / libavfilter / af_atempo.c
index bfdad7d76bc296ee473eefa86bca2a8b14afab74..80a33c43ede29034d52a0babca9bbd665766dd8c 100644 (file)
@@ -103,6 +103,9 @@ typedef struct ATempoContext {
     // 1: output sample position
     int64_t position[2];
 
+    // first input timestamp, all other timestamps are offset by this one
+    int64_t start_pts;
+
     // sample format:
     enum AVSampleFormat format;
 
@@ -159,7 +162,7 @@ static const AVOption atempo_options[] = {
       OFFSET(tempo), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 },
       YAE_ATEMPO_MIN,
       YAE_ATEMPO_MAX,
-      AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM },
+      AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM },
     { NULL }
 };
 
@@ -186,6 +189,7 @@ static void yae_clear(ATempoContext *atempo)
 
     atempo->nfrag = 0;
     atempo->state = YAE_LOAD_FRAGMENT;
+    atempo->start_pts = AV_NOPTS_VALUE;
 
     atempo->position[0] = 0;
     atempo->position[1] = 0;
@@ -324,28 +328,14 @@ static int yae_reset(ATempoContext *atempo,
     return 0;
 }
 
-static int yae_set_tempo(AVFilterContext *ctx, const char *arg_tempo)
+static int yae_update(AVFilterContext *ctx)
 {
     const AudioFragment *prev;
     ATempoContext *atempo = ctx->priv;
-    char   *tail = NULL;
-    double tempo = av_strtod(arg_tempo, &tail);
-
-    if (tail && *tail) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid tempo value '%s'\n", arg_tempo);
-        return AVERROR(EINVAL);
-    }
-
-    if (tempo < YAE_ATEMPO_MIN || tempo > YAE_ATEMPO_MAX) {
-        av_log(ctx, AV_LOG_ERROR, "Tempo value %f exceeds [%f, %f] range\n",
-               tempo, YAE_ATEMPO_MIN, YAE_ATEMPO_MAX);
-        return AVERROR(EINVAL);
-    }
 
     prev = yae_prev_frag(atempo);
     atempo->origin[0] = prev->position[0] + atempo->window / 2;
     atempo->origin[1] = prev->position[1] + atempo->window / 2;
-    atempo->tempo = tempo;
     return 0;
 }
 
@@ -1068,7 +1058,7 @@ static int push_samples(ATempoContext *atempo,
     atempo->dst_buffer->nb_samples  = n_out;
 
     // adjust the PTS:
-    atempo->dst_buffer->pts =
+    atempo->dst_buffer->pts = atempo->start_pts +
         av_rescale_q(atempo->nsamples_out,
                      (AVRational){ 1, outlink->sample_rate },
                      outlink->time_base);
@@ -1097,6 +1087,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *src_buffer)
     const uint8_t *src = src_buffer->data[0];
     const uint8_t *src_end = src + n_in * atempo->stride;
 
+    if (atempo->start_pts == AV_NOPTS_VALUE)
+        atempo->start_pts = av_rescale_q(src_buffer->pts,
+                                         inlink->time_base,
+                                         outlink->time_base);
+
     while (src < src_end) {
         if (!atempo->dst_buffer) {
             atempo->dst_buffer = ff_get_audio_buffer(outlink, n_out);
@@ -1180,7 +1175,12 @@ static int process_command(AVFilterContext *ctx,
                            int res_len,
                            int flags)
 {
-    return !strcmp(cmd, "tempo") ? yae_set_tempo(ctx, arg) : AVERROR(ENOSYS);
+    int ret = ff_filter_process_command(ctx, cmd, arg, res, res_len, flags);
+
+    if (ret < 0)
+        return ret;
+
+    return yae_update(ctx);
 }
 
 static const AVFilterPad atempo_inputs[] = {
@@ -1202,7 +1202,7 @@ static const AVFilterPad atempo_outputs[] = {
     { NULL }
 };
 
-AVFilter ff_af_atempo = {
+const AVFilter ff_af_atempo = {
     .name            = "atempo",
     .description     = NULL_IF_CONFIG_SMALL("Adjust audio tempo."),
     .init            = init,