]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/af_adelay.c
avcodec: Constify all the AVCodecParsers
[ffmpeg] / libavfilter / af_adelay.c
index 7bc731d48a363f3f180eaad6bd6a8cc57df233b1..81ff7947f553457b1e9584124ebd94f04fe07a48 100644 (file)
 #include "internal.h"
 
 typedef struct ChanDelay {
-    int delay;
-    unsigned delay_index;
-    unsigned index;
+    int64_t delay;
+    size_t delay_index;
+    size_t index;
     uint8_t *samples;
 } ChanDelay;
 
 typedef struct AudioDelayContext {
     const AVClass *class;
+    int all;
     char *delays;
     ChanDelay *chandelay;
     int nb_delays;
@@ -54,6 +55,7 @@ typedef struct AudioDelayContext {
 
 static const AVOption adelay_options[] = {
     { "delays", "set list of delays for each channel", OFFSET(delays), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
+    { "all",    "use last available delay for remained channels", OFFSET(all), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A },
     { NULL }
 };
 
@@ -141,7 +143,7 @@ static int config_input(AVFilterLink *inlink)
     p = s->delays;
     for (i = 0; i < s->nb_delays; i++) {
         ChanDelay *d = &s->chandelay[i];
-        float delay;
+        float delay, div;
         char type = 0;
         int ret;
 
@@ -150,10 +152,14 @@ static int config_input(AVFilterLink *inlink)
 
         p = NULL;
 
-        ret = av_sscanf(arg, "%d%c", &d->delay, &type);
+        ret = av_sscanf(arg, "%"SCNd64"%c", &d->delay, &type);
         if (ret != 2 || type != 'S') {
-            av_sscanf(arg, "%f", &delay);
-            d->delay = delay * inlink->sample_rate / 1000.0;
+            div = type == 's' ? 1.0 : 1000.0;
+            if (av_sscanf(arg, "%f", &delay) != 1) {
+                av_log(ctx, AV_LOG_ERROR, "Invalid syntax for delay.\n");
+                return AVERROR(EINVAL);
+            }
+            d->delay = delay * inlink->sample_rate / div;
         }
 
         if (d->delay < 0) {
@@ -162,6 +168,11 @@ static int config_input(AVFilterLink *inlink)
         }
     }
 
+    if (s->all && i) {
+        for (int j = i; j < s->nb_delays; j++)
+            s->chandelay[j].delay = s->chandelay[i-1].delay;
+    }
+
     s->padding = s->chandelay[0].delay;
     for (i = 1; i < s->nb_delays; i++) {
         ChanDelay *d = &s->chandelay[i];
@@ -183,6 +194,11 @@ static int config_input(AVFilterLink *inlink)
         if (!d->delay)
             continue;
 
+        if (d->delay > SIZE_MAX) {
+            av_log(ctx, AV_LOG_ERROR, "Requested delay is too big.\n");
+            return AVERROR(EINVAL);
+        }
+
         d->samples = av_malloc_array(d->delay, s->block_align);
         if (!d->samples)
             return AVERROR(ENOMEM);