[FFmpeg-cvslog] avfilter/af_dynaudnorm: add slice threading support

Paul B Mahol git at videolan.org
Fri Nov 4 19:28:40 EET 2022


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Fri Nov  4 17:59:28 2022 +0100| [369b7f2654aa200edfac4a4f8a9b4f5d0bfa9517] | committer: Paul B Mahol

avfilter/af_dynaudnorm: add slice threading support

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=369b7f2654aa200edfac4a4f8a9b4f5d0bfa9517
---

 libavfilter/af_dynaudnorm.c | 86 +++++++++++++++++++++++++++++++++------------
 1 file changed, 64 insertions(+), 22 deletions(-)

diff --git a/libavfilter/af_dynaudnorm.c b/libavfilter/af_dynaudnorm.c
index 5aecefff5e..88d1b382f3 100644
--- a/libavfilter/af_dynaudnorm.c
+++ b/libavfilter/af_dynaudnorm.c
@@ -93,6 +93,11 @@ typedef struct DynamicAudioNormalizerContext {
     AVFrame *window;
 } DynamicAudioNormalizerContext;
 
+typedef struct ThreadData {
+    AVFrame *in, *out;
+    int enabled;
+} ThreadData;
+
 #define OFFSET(x) offsetof(DynamicAudioNormalizerContext, x)
 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
 
@@ -521,6 +526,20 @@ static void update_gain_history(DynamicAudioNormalizerContext *s, int channel,
     }
 }
 
+static int update_gain_histories(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    DynamicAudioNormalizerContext *s = ctx->priv;
+    AVFrame *analyze_frame = arg;
+    const int channels = s->channels;
+    const int start = (channels * jobnr) / nb_jobs;
+    const int end = (channels * (jobnr+1)) / nb_jobs;
+
+    for (int c = start; c < end; c++)
+        update_gain_history(s, c, get_max_local_gain(s, analyze_frame, c));
+
+    return 0;
+}
+
 static inline double update_value(double new, double old, double aggressiveness)
 {
     av_assert0((aggressiveness >= 0.0) && (aggressiveness <= 1.0));
@@ -655,8 +674,9 @@ static void perform_compression(DynamicAudioNormalizerContext *s, AVFrame *frame
     }
 }
 
-static int analyze_frame(DynamicAudioNormalizerContext *s, AVFilterLink *outlink, AVFrame **frame)
+static int analyze_frame(AVFilterContext *ctx, AVFilterLink *outlink, AVFrame **frame)
 {
+    DynamicAudioNormalizerContext *s = ctx->priv;
     AVFrame *analyze_frame;
 
     if (s->dc_correction || s->compress_factor > DBL_EPSILON) {
@@ -716,34 +736,49 @@ static int analyze_frame(DynamicAudioNormalizerContext *s, AVFilterLink *outlink
         for (int c = 0; c < s->channels; c++)
             update_gain_history(s, c, gain);
     } else {
-        for (int c = 0; c < s->channels; c++)
-            update_gain_history(s, c, get_max_local_gain(s, analyze_frame, c));
+        ff_filter_execute(ctx, update_gain_histories, analyze_frame, NULL,
+                          FFMIN(s->channels, ff_filter_get_nb_threads(ctx)));
     }
 
     return 0;
 }
 
-static void amplify_frame(DynamicAudioNormalizerContext *s, AVFrame *in,
-                          AVFrame *frame, int enabled)
+static void amplify_channel(DynamicAudioNormalizerContext *s, AVFrame *in,
+                            AVFrame *frame, int enabled, int c)
 {
-    for (int c = 0; c < s->channels; c++) {
-        const int bypass = bypass_channel(s, frame, c);
-        const double *src_ptr = (const double *)in->extended_data[c];
-        double *dst_ptr = (double *)frame->extended_data[c];
-        double current_amplification_factor;
-
-        cqueue_dequeue(s->gain_history_smoothed[c], &current_amplification_factor);
+    const int bypass = bypass_channel(s, frame, c);
+    const double *src_ptr = (const double *)in->extended_data[c];
+    double *dst_ptr = (double *)frame->extended_data[c];
+    double current_amplification_factor;
 
-        for (int i = 0; i < frame->nb_samples && enabled && !bypass; i++) {
-            const double amplification_factor = fade(s->prev_amplification_factor[c],
-                                                     current_amplification_factor, i,
-                                                     frame->nb_samples);
+    cqueue_dequeue(s->gain_history_smoothed[c], &current_amplification_factor);
 
-            dst_ptr[i] = src_ptr[i] * amplification_factor;
-        }
+    for (int i = 0; i < frame->nb_samples && enabled && !bypass; i++) {
+        const double amplification_factor = fade(s->prev_amplification_factor[c],
+                                                 current_amplification_factor, i,
+                                                 frame->nb_samples);
 
-        s->prev_amplification_factor[c] = current_amplification_factor;
+        dst_ptr[i] = src_ptr[i] * amplification_factor;
     }
+
+    s->prev_amplification_factor[c] = current_amplification_factor;
+}
+
+static int amplify_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    DynamicAudioNormalizerContext *s = ctx->priv;
+    ThreadData *td = arg;
+    AVFrame *out = td->out;
+    AVFrame *in = td->in;
+    const int enabled = td->enabled;
+    const int channels = s->channels;
+    const int start = (channels * jobnr) / nb_jobs;
+    const int end = (channels * (jobnr+1)) / nb_jobs;
+
+    for (int ch = start; ch < end; ch++)
+        amplify_channel(s, in, out, enabled, ch);
+
+    return 0;
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
@@ -751,6 +786,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     AVFilterContext *ctx = inlink->dst;
     DynamicAudioNormalizerContext *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
+    ThreadData td;
     int ret;
 
     while (((s->queue.available >= s->filter_size) ||
@@ -773,7 +809,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
             av_frame_copy_props(out, in);
         }
 
-        amplify_frame(s, in, out, is_enabled > 0.);
+        td.in = in;
+        td.out = out;
+        td.enabled = is_enabled > 0.;
+        ff_filter_execute(ctx, amplify_channels, &td, NULL,
+                          FFMIN(s->channels, ff_filter_get_nb_threads(ctx)));
+
         s->pts = out->pts + av_rescale_q(out->nb_samples, av_make_q(1, outlink->sample_rate),
                                          outlink->time_base);
         if (out != in)
@@ -783,7 +824,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
             return ret;
     }
 
-    ret = analyze_frame(s, outlink, &in);
+    ret = analyze_frame(ctx, outlink, &in);
     if (ret < 0)
         return ret;
     if (!s->eof) {
@@ -940,6 +981,7 @@ const AVFilter ff_af_dynaudnorm = {
     FILTER_OUTPUTS(avfilter_af_dynaudnorm_outputs),
     FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_DBLP),
     .priv_class    = &dynaudnorm_class,
-    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
+                     AVFILTER_FLAG_SLICE_THREADS,
     .process_command = process_command,
 };



More information about the ffmpeg-cvslog mailing list