On date Tuesday 2014-08-19 01:29:42 +0200, Michael Niedermayer encoded:
> On Mon, Aug 18, 2014 at 02:53:45PM +0200, Stefano Sabatini wrote:
> > ---
> >  libavfilter/af_apad.c | 29 +++++++++++++++++------------
> >  1 file changed, 17 insertions(+), 12 deletions(-)
> 
> probably ok

With more changes.
-- 
FFmpeg = Fundamental Foolish Magnificient Portable Exxagerate God
>From e81a186aee715c0481df21cf982121736c67e75f Mon Sep 17 00:00:00 2001
From: Stefano Sabatini <stefa...@gmail.com>
Date: Mon, 18 Aug 2014 14:51:25 +0200
Subject: [PATCH] lavfi/apad: fix logic when whole_len or pad_len options are
 specified

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.

TODO: bump micro version
---
 libavfilter/af_apad.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/libavfilter/af_apad.c b/libavfilter/af_apad.c
index 6b2c8b1..eafc705 100644
--- a/libavfilter/af_apad.c
+++ b/libavfilter/af_apad.c
@@ -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)
-- 
1.8.3.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to