[FFmpeg-cvslog] avfilter/af_headphone: improve stereo hrir support

Paul B Mahol git at videolan.org
Sat Feb 19 14:45:02 EET 2022


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sat Feb 19 13:38:56 2022 +0100| [c439c6b191f731e28e5374ecc720a86af1e14308] | committer: Paul B Mahol

avfilter/af_headphone: improve stereo hrir support

Until now, in some cases produced output would be wrong.

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

 libavfilter/af_headphone.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c
index b2030dbbbb..aea861aa04 100644
--- a/libavfilter/af_headphone.c
+++ b/libavfilter/af_headphone.c
@@ -82,7 +82,9 @@ typedef struct HeadphoneContext {
         int          ir_len;
         int          eof;
     } hrir_in[64];
+    uint64_t map_channel_layout;
     uint64_t mapping[64];
+    uint8_t  hrir_map[64];
 } HeadphoneContext;
 
 static int parse_channel_name(const char *arg, uint64_t *rchannel)
@@ -118,6 +120,7 @@ static void parse_map(AVFilterContext *ctx)
         s->mapping[s->nb_irs] = out_channel;
         s->nb_irs++;
     }
+    s->map_channel_layout = used_channels;
 
     if (s->hrir_fmt == HRIR_MULTI)
         s->nb_hrir_inputs = 1;
@@ -262,7 +265,7 @@ static int headphone_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
         }
 
         offset = i * n_fft;
-        hrtf_offset = hrtf + offset;
+        hrtf_offset = hrtf + s->hrir_map[i] * n_fft;
 
         memset(fft_in, 0, sizeof(AVComplexFloat) * n_fft);
 
@@ -361,6 +364,7 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink)
     struct HeadphoneContext *s = ctx->priv;
     const int ir_len = s->ir_len;
     int nb_input_channels = ctx->inputs[0]->channels;
+    const int nb_hrir_channels = s->nb_hrir_inputs == 1 ? ctx->inputs[1]->channels : s->nb_hrir_inputs * 2;
     float gain_lin = expf((s->gain - 3 * nb_input_channels) / 20 * M_LN10);
     AVFrame *frame;
     int ret = 0;
@@ -426,15 +430,15 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink)
         s->temp_src[0] = av_calloc(s->air_len, sizeof(float));
         s->temp_src[1] = av_calloc(s->air_len, sizeof(float));
 
-        s->data_ir[0] = av_calloc(nb_input_channels * s->air_len, sizeof(*s->data_ir[0]));
-        s->data_ir[1] = av_calloc(nb_input_channels * s->air_len, sizeof(*s->data_ir[1]));
+        s->data_ir[0] = av_calloc(nb_hrir_channels * s->air_len, sizeof(*s->data_ir[0]));
+        s->data_ir[1] = av_calloc(nb_hrir_channels * s->air_len, sizeof(*s->data_ir[1]));
         if (!s->data_ir[0] || !s->data_ir[1] || !s->temp_src[0] || !s->temp_src[1]) {
             ret = AVERROR(ENOMEM);
             goto fail;
         }
     } else {
-        s->data_hrtf[0] = av_calloc(n_fft, sizeof(*s->data_hrtf[0]) * nb_input_channels);
-        s->data_hrtf[1] = av_calloc(n_fft, sizeof(*s->data_hrtf[1]) * nb_input_channels);
+        s->data_hrtf[0] = av_calloc(n_fft, sizeof(*s->data_hrtf[0]) * nb_hrir_channels);
+        s->data_hrtf[1] = av_calloc(n_fft, sizeof(*s->data_hrtf[1]) * nb_hrir_channels);
         if (!s->data_hrtf[0] || !s->data_hrtf[1]) {
             ret = AVERROR(ENOMEM);
             goto fail;
@@ -451,10 +455,12 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink)
         ptr = (float *)frame->extended_data[0];
 
         if (s->hrir_fmt == HRIR_STEREO) {
-            int idx = av_get_channel_layout_channel_index(inlink->channel_layout,
+            int idx = av_get_channel_layout_channel_index(s->map_channel_layout,
                                                           s->mapping[i]);
             if (idx < 0)
                 continue;
+
+            s->hrir_map[i] = idx;
             if (s->type == TIME_DOMAIN) {
                 float *data_ir_l = s->data_ir[0] + idx * s->air_len;
                 float *data_ir_r = s->data_ir[1] + idx * s->air_len;
@@ -486,6 +492,7 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink)
                 if (idx < 0)
                     continue;
 
+                s->hrir_map[k] = idx;
                 I = k * 2;
                 if (s->type == TIME_DOMAIN) {
                     float *data_ir_l = s->data_ir[0] + idx * s->air_len;



More information about the ffmpeg-cvslog mailing list