]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/af_amix.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavfilter / af_amix.c
index ce77692871ba89eba0cff7e4225ca75fc49bc190..6c7357f14198c717fa1500faf45987a4d6da6b43 100644 (file)
@@ -32,6 +32,7 @@
 #include "libavutil/audio_fifo.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
+#include "libavutil/common.h"
 #include "libavutil/float_dsp.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
@@ -173,17 +174,18 @@ typedef struct MixContext {
 
 #define OFFSET(x) offsetof(MixContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
+#define F AV_OPT_FLAG_FILTERING_PARAM
 static const AVOption amix_options[] = {
     { "inputs", "Number of inputs.",
-            OFFSET(nb_inputs), AV_OPT_TYPE_INT, { 2 }, 1, 32, A },
+            OFFSET(nb_inputs), AV_OPT_TYPE_INT, { 2 }, 1, 32, A|F },
     { "duration", "How to determine the end-of-stream.",
-            OFFSET(duration_mode), AV_OPT_TYPE_INT, { DURATION_LONGEST }, 0,  2, A, "duration" },
-        { "longest",  "Duration of longest input.",  0, AV_OPT_TYPE_CONST, { DURATION_LONGEST  }, INT_MIN, INT_MAX, A, "duration" },
-        { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { DURATION_SHORTEST }, INT_MIN, INT_MAX, A, "duration" },
-        { "first",    "Duration of first input.",    0, AV_OPT_TYPE_CONST, { DURATION_FIRST    }, INT_MIN, INT_MAX, A, "duration" },
+            OFFSET(duration_mode), AV_OPT_TYPE_INT, { DURATION_LONGEST }, 0,  2, A|F, "duration" },
+        { "longest",  "Duration of longest input.",  0, AV_OPT_TYPE_CONST, { DURATION_LONGEST  }, INT_MIN, INT_MAX, A|F, "duration" },
+        { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { DURATION_SHORTEST }, INT_MIN, INT_MAX, A|F, "duration" },
+        { "first",    "Duration of first input.",    0, AV_OPT_TYPE_CONST, { DURATION_FIRST    }, INT_MIN, INT_MAX, A|F, "duration" },
     { "dropout_transition", "Transition time, in seconds, for volume "
                             "renormalization when an input stream ends.",
-            OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { 2.0 }, 0, INT_MAX, A },
+            OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { 2.0 }, 0, INT_MAX, A|F },
     { NULL },
 };
 
@@ -255,7 +257,7 @@ static int config_output(AVFilterLink *outlink)
     av_get_channel_layout_string(buf, sizeof(buf), -1, outlink->channel_layout);
 
     av_log(ctx, AV_LOG_VERBOSE,
-           "inputs:%d fmt:%s srate:%"PRId64" cl:%s\n", s->nb_inputs,
+           "inputs:%d fmt:%s srate:%d cl:%s\n", s->nb_inputs,
            av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf);
 
     return 0;
@@ -305,9 +307,7 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
     if (s->next_pts != AV_NOPTS_VALUE)
         s->next_pts += nb_samples;
 
-    ff_filter_samples(outlink, out_buf);
-
-    return 0;
+    return ff_filter_samples(outlink, out_buf);
 }
 
 /**
@@ -354,7 +354,7 @@ static int request_samples(AVFilterContext *ctx, int min_samples)
                 s->input_state[i] = INPUT_OFF;
                 continue;
             }
-        } else if (ret)
+        } else if (ret < 0)
             return ret;
     }
     return 0;
@@ -403,7 +403,7 @@ static int request_frame(AVFilterLink *outlink)
 
         available_samples = get_available_samples(s);
         if (!available_samples)
-            return 0;
+            return AVERROR(EAGAIN);
 
         return output_frame(outlink, available_samples);
     }
@@ -416,7 +416,7 @@ static int request_frame(AVFilterLink *outlink)
                 return AVERROR_EOF;
             else
                 return AVERROR(EAGAIN);
-        } else if (ret)
+        } else if (ret < 0)
             return ret;
     }
     av_assert0(s->frame_list->nb_frames > 0);
@@ -431,10 +431,12 @@ static int request_frame(AVFilterLink *outlink)
         ret = calc_active_inputs(s);
         if (ret < 0)
             return ret;
+    }
 
+    if (s->active_inputs > 1) {
         available_samples = get_available_samples(s);
         if (!available_samples)
-            return 0;
+            return AVERROR(EAGAIN);
         available_samples = FFMIN(available_samples, wanted_samples);
     } else {
         available_samples = wanted_samples;
@@ -446,31 +448,37 @@ static int request_frame(AVFilterLink *outlink)
     return output_frame(outlink, available_samples);
 }
 
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
 {
     AVFilterContext  *ctx = inlink->dst;
     MixContext       *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    int i;
+    int i, ret = 0;
 
     for (i = 0; i < ctx->nb_inputs; i++)
         if (ctx->inputs[i] == inlink)
             break;
     if (i >= ctx->nb_inputs) {
         av_log(ctx, AV_LOG_ERROR, "unknown input link\n");
-        return;
+        ret = AVERROR(EINVAL);
+        goto fail;
     }
 
     if (i == 0) {
         int64_t pts = av_rescale_q(buf->pts, inlink->time_base,
                                    outlink->time_base);
-        frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
+        ret = frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
+        if (ret < 0)
+            goto fail;
     }
 
-    av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
-                        buf->audio->nb_samples);
+    ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
+                              buf->audio->nb_samples);
 
+fail:
     avfilter_unref_buffer(buf);
+
+    return ret;
 }
 
 static int init(AVFilterContext *ctx, const char *args)
@@ -481,10 +489,8 @@ static int init(AVFilterContext *ctx, const char *args)
     s->class = &amix_class;
     av_opt_set_defaults(s);
 
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+    if ((ret = av_set_options_string(s, args, "=", ":")) < 0)
         return ret;
-    }
     av_opt_free(s);
 
     for (i = 0; i < s->nb_inputs; i++) {
@@ -549,4 +555,5 @@ AVFilter avfilter_af_amix = {
                                           .config_props  = config_output,
                                           .request_frame = request_frame },
                                         { .name = NULL}},
+    .priv_class = &amix_class,
 };