lavfi/apad: fix logic when whole_len or pad_len options are specified
authorStefano Sabatini <stefasab@gmail.com>
Mon, 18 Aug 2014 12:51:25 +0000 (14:51 +0200)
committerStefano Sabatini <stefasab@gmail.com>
Thu, 21 Aug 2014 14:59:07 +0000 (16:59 +0200)
In particular, allow pad_len and whole_len to have value set to 0, which
means that no padding will be added. Previously a value set to 0 meant
that that the filter had to pad forever.

The new semantics is clearer, also simplifies scripting since the option
value might be automatically computed, so that no checks need to be done
in case it is 0.

The old semantics was never documented and the logic was broken (the
filter was always adding samples indefinitely), so this should not break
backward compatibility.

libavfilter/af_apad.c
libavfilter/version.h

index 6b2c8b1..eafc705 100644 (file)
@@ -39,17 +39,17 @@ typedef struct {
     int64_t next_pts;
 
     int packet_size;
-    int64_t pad_len;
-    int64_t whole_len;
+    int64_t pad_len, pad_len_left;
+    int64_t whole_len, whole_len_left;
 } APadContext;
 
 #define OFFSET(x) offsetof(APadContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
 static const AVOption apad_options[] = {
-    { "packet_size", "set silence packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, { .i64 = 4096 }, 0, INT_MAX, A },
-    { "pad_len",     "number of samples of silence to add",          OFFSET(pad_len),   AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, A },
-    { "whole_len",   "target number of samples in the audio stream", OFFSET(whole_len), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, A },
+    { "packet_size", "set silence packet size",                                  OFFSET(packet_size), AV_OPT_TYPE_INT,   { .i64 = 4096 }, 0, INT_MAX, A },
+    { "pad_len",     "set number of samples of silence to add",                  OFFSET(pad_len),     AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, A },
+    { "whole_len",   "set minimum target number of samples in the audio stream", OFFSET(whole_len),   AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, A },
     { NULL }
 };
 
@@ -60,10 +60,12 @@ static av_cold int init(AVFilterContext *ctx)
     APadContext *apad = ctx->priv;
 
     apad->next_pts = AV_NOPTS_VALUE;
-    if (apad->whole_len && apad->pad_len) {
+    if (apad->whole_len >= 0 && apad->pad_len >= 0) {
         av_log(ctx, AV_LOG_ERROR, "Both whole and pad length are set, this is not possible\n");
         return AVERROR(EINVAL);
     }
+    apad->pad_len_left   = apad->pad_len;
+    apad->whole_len_left = apad->whole_len;
 
     return 0;
 }
@@ -73,8 +75,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
     AVFilterContext *ctx = inlink->dst;
     APadContext *apad = ctx->priv;
 
-    if (apad->whole_len)
-        apad->whole_len -= frame->nb_samples;
+    if (apad->whole_len >= 0) {
+        apad->whole_len_left = FFMAX(apad->whole_len_left - frame->nb_samples, 0);
+        av_log(ctx, AV_LOG_DEBUG,
+               "n_out:%d whole_len_left:%"PRId64"\n", frame->nb_samples, apad->whole_len_left);
+    }
 
     apad->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
     return ff_filter_frame(ctx->outputs[0], frame);
@@ -92,13 +97,14 @@ static int request_frame(AVFilterLink *outlink)
         int n_out = apad->packet_size;
         AVFrame *outsamplesref;
 
-        if (apad->whole_len > 0) {
-            apad->pad_len = apad->whole_len;
-            apad->whole_len = 0;
+        if (apad->whole_len >= 0 && apad->pad_len < 0) {
+            apad->pad_len = apad->pad_len_left = apad->whole_len_left;
         }
-        if (apad->pad_len > 0) {
-            n_out = FFMIN(n_out, apad->pad_len);
-            apad->pad_len -= n_out;
+        if (apad->pad_len >=0 || apad->whole_len >= 0) {
+            n_out = FFMIN(n_out, apad->pad_len_left);
+            apad->pad_len_left -= n_out;
+            av_log(ctx, AV_LOG_DEBUG,
+                   "padding n_out:%d pad_len_left:%"PRId64"\n", n_out, apad->pad_len_left);
         }
 
         if (!n_out)
index 28c510e..eb3c12b 100644 (file)
@@ -31,7 +31,7 @@
 
 #define LIBAVFILTER_VERSION_MAJOR  5
 #define LIBAVFILTER_VERSION_MINOR  0
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MICRO 102
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
                                                LIBAVFILTER_VERSION_MINOR, \