]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/af_headphone.c
avdevice/avdevice: Constify avdevice_list_input_sources/output_sinks
[ffmpeg] / libavfilter / af_headphone.c
index d57ecb1f50b7ffa8edecebc8d4c53107aad1b77f..edf8e773d79d2679487be6b883f5bfd385b62f8c 100644 (file)
@@ -52,7 +52,7 @@ typedef struct HeadphoneContext {
     int ir_len;
     int air_len;
 
-    int nb_inputs;
+    int nb_hrir_inputs;
 
     int nb_irs;
 
@@ -75,12 +75,11 @@ typedef struct HeadphoneContext {
     FFTContext *fft[2], *ifft[2];
     FFTComplex *data_hrtf[2];
 
-    AVFloatDSPContext *fdsp;
-    struct headphone_inputs {
-        AVFrame     *frame;
+    float (*scalarproduct_float)(const float *v1, const float *v2, int len);
+    struct hrir_inputs {
         int          ir_len;
         int          eof;
-    } *in;
+    } hrir_in[64];
     uint64_t mapping[64];
 } HeadphoneContext;
 
@@ -100,8 +99,6 @@ static void parse_map(AVFilterContext *ctx)
     char *arg, *tokenizer, *p;
     uint64_t used_channels = 0;
 
-    s->nb_inputs = 1;
-
     p = s->map;
     while ((arg = av_strtok(p, "|", &tokenizer))) {
         uint64_t out_channel;
@@ -121,9 +118,9 @@ static void parse_map(AVFilterContext *ctx)
     }
 
     if (s->hrir_fmt == HRIR_MULTI)
-        s->nb_inputs = 2;
+        s->nb_hrir_inputs = 1;
     else
-        s->nb_inputs = s->nb_irs + 1;
+        s->nb_hrir_inputs = s->nb_irs;
 }
 
 typedef struct ThreadData {
@@ -166,23 +163,22 @@ static int headphone_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n
     }
 
     for (i = 0; i < in->nb_samples; i++) {
-        const float *temp_ir = ir;
+        const float *cur_ir = ir;
 
         *dst = 0;
         for (l = 0; l < in_channels; l++) {
             *(buffer[l] + wr) = src[l];
         }
 
-        for (l = 0; l < in_channels; l++) {
+        for (l = 0; l < in_channels; cur_ir += air_len, l++) {
             const float *const bptr = buffer[l];
 
             if (l == s->lfe_channel) {
                 *dst += *(buffer[s->lfe_channel] + wr) * s->gain_lfe;
-                temp_ir += air_len;
                 continue;
             }
 
-            read = (wr - (ir_len - 1) + buffer_length) & modulo;
+            read = (wr - (ir_len - 1)) & modulo;
 
             if (read + ir_len < buffer_length) {
                 memcpy(temp_src, bptr + read, ir_len * sizeof(*temp_src));
@@ -193,8 +189,7 @@ static int headphone_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n
                 memcpy(temp_src + len, bptr, (air_len - len) * sizeof(*temp_src));
             }
 
-            dst[0] += s->fdsp->scalarproduct_float(temp_ir, temp_src, FFALIGN(ir_len, 32));
-            temp_ir += air_len;
+            dst[0] += s->scalarproduct_float(cur_ir, temp_src, FFALIGN(ir_len, 32));
         }
 
         if (fabsf(dst[0]) > 1)
@@ -286,6 +281,8 @@ static int headphone_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
 
     for (j = 0; j < in->nb_samples; j++) {
         dst[2 * j] += fft_acc[j].re * fft_scale;
+        if (fabsf(dst[2 * j]) > 1)
+            n_clippings[0]++;
     }
 
     for (j = 0; j < ir_len - 1; j++) {
@@ -294,14 +291,6 @@ static int headphone_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
         *(ringbuffer + write_pos) += fft_acc[in->nb_samples + j].re * fft_scale;
     }
 
-    for (i = 0; i < out->nb_samples; i++) {
-        if (fabsf(dst[0]) > 1) {
-            n_clippings[0]++;
-        }
-
-        dst += 2;
-    }
-
     *write = wr;
 
     return 0;
@@ -319,7 +308,7 @@ static int check_ir(AVFilterLink *inlink, int input_number)
         av_log(ctx, AV_LOG_ERROR, "Too big length of IRs: %d > %d.\n", ir_len, max_ir_len);
         return AVERROR(EINVAL);
     }
-    s->in[input_number].ir_len = ir_len;
+    s->hrir_in[input_number].ir_len = ir_len;
     s->ir_len = FFMAX(ir_len, s->ir_len);
 
     return 0;
@@ -367,6 +356,7 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink)
     const int ir_len = s->ir_len;
     int nb_input_channels = ctx->inputs[0]->channels;
     float gain_lin = expf((s->gain - 3 * nb_input_channels) / 20 * M_LN10);
+    AVFrame *frame;
     int ret = 0;
     int n_fft;
     int i, j, k;
@@ -432,14 +422,14 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink)
         }
     }
 
-    for (i = 0; i < s->nb_inputs - 1; i++) {
-        int len = s->in[i + 1].ir_len;
+    for (i = 0; i < s->nb_hrir_inputs; av_frame_free(&frame), i++) {
+        int len = s->hrir_in[i].ir_len;
         float *ptr;
 
-        ret = ff_inlink_consume_samples(ctx->inputs[i + 1], len, len, &s->in[i + 1].frame);
+        ret = ff_inlink_consume_samples(ctx->inputs[i + 1], len, len, &frame);
         if (ret < 0)
             goto fail;
-        ptr = (float *)s->in[i + 1].frame->extended_data[0];
+        ptr = (float *)frame->extended_data[0];
 
         if (s->hrir_fmt == HRIR_STEREO) {
             int idx = av_get_channel_layout_channel_index(inlink->channel_layout,
@@ -502,17 +492,11 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink)
                 }
             }
         }
-
-        av_frame_free(&s->in[i + 1].frame);
     }
 
     s->have_hrirs = 1;
 
 fail:
-
-    for (i = 0; i < s->nb_inputs - 1; i++)
-        av_frame_free(&s->in[i + 1].frame);
-
     return ret;
 }
 
@@ -527,23 +511,25 @@ static int activate(AVFilterContext *ctx)
     FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx);
     if (!s->eof_hrirs) {
         int eof = 1;
-        for (i = 1; i < s->nb_inputs; i++) {
-            if (s->in[i].eof)
+        for (i = 0; i < s->nb_hrir_inputs; i++) {
+            AVFilterLink *input = ctx->inputs[i + 1];
+
+            if (s->hrir_in[i].eof)
                 continue;
 
-            if ((ret = check_ir(ctx->inputs[i], i)) < 0)
+            if ((ret = check_ir(input, i)) < 0)
                 return ret;
 
-            if (ff_outlink_get_status(ctx->inputs[i]) == AVERROR_EOF) {
-                if (!ff_inlink_queued_samples(ctx->inputs[i])) {
+            if (ff_outlink_get_status(input) == AVERROR_EOF) {
+                if (!ff_inlink_queued_samples(input)) {
                     av_log(ctx, AV_LOG_ERROR, "No samples provided for "
-                           "HRIR stream %d.\n", i - 1);
+                           "HRIR stream %d.\n", i);
                     return AVERROR_INVALIDDATA;
                 }
-                    s->in[i].eof = 1;
+                s->hrir_in[i].eof = 1;
             } else {
                 if (ff_outlink_frame_wanted(ctx->outputs[0]))
-                    ff_inlink_request_frame(ctx->inputs[i]);
+                    ff_inlink_request_frame(input);
                 eof = 0;
             }
         }
@@ -612,7 +598,7 @@ static int query_formats(AVFilterContext *ctx)
         if (ret)
             return ret;
     } else {
-        for (i = 1; i < s->nb_inputs; i++) {
+        for (i = 1; i <= s->nb_hrir_inputs; i++) {
             ret = ff_channel_layouts_ref(stereo_layout, &ctx->inputs[i]->outcfg.channel_layouts);
             if (ret)
                 return ret;
@@ -660,27 +646,27 @@ static av_cold int init(AVFilterContext *ctx)
 
     parse_map(ctx);
 
-    s->in = av_calloc(s->nb_inputs, sizeof(*s->in));
-    if (!s->in)
-        return AVERROR(ENOMEM);
-
-    for (i = 1; i < s->nb_inputs; i++) {
-        char *name = av_asprintf("hrir%d", i - 1);
+    for (i = 0; i < s->nb_hrir_inputs; i++) {
+        char *name = av_asprintf("hrir%d", i);
         AVFilterPad pad = {
             .name         = name,
             .type         = AVMEDIA_TYPE_AUDIO,
         };
         if (!name)
             return AVERROR(ENOMEM);
-        if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) {
+        if ((ret = ff_insert_inpad(ctx, i + 1, &pad)) < 0) {
             av_freep(&pad.name);
             return ret;
         }
     }
 
-    s->fdsp = avpriv_float_dsp_alloc(0);
-    if (!s->fdsp)
-        return AVERROR(ENOMEM);
+    if (s->type == TIME_DOMAIN) {
+        AVFloatDSPContext *fdsp = avpriv_float_dsp_alloc(0);
+        if (!fdsp)
+            return AVERROR(ENOMEM);
+        s->scalarproduct_float = fdsp->scalarproduct_float;
+        av_free(fdsp);
+    }
 
     return 0;
 }
@@ -725,9 +711,7 @@ static av_cold void uninit(AVFilterContext *ctx)
     av_freep(&s->temp_afft[1]);
     av_freep(&s->data_hrtf[0]);
     av_freep(&s->data_hrtf[1]);
-    av_freep(&s->fdsp);
 
-    av_freep(&s->in);
     for (unsigned i = 1; i < ctx->nb_inputs; i++)
         av_freep(&ctx->input_pads[i].name);
 }