diff options
Diffstat (limited to 'audio/filter/af_lavrresample.c')
-rw-r--r-- | audio/filter/af_lavrresample.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/audio/filter/af_lavrresample.c b/audio/filter/af_lavrresample.c index f7f448cad0..6fbb445563 100644 --- a/audio/filter/af_lavrresample.c +++ b/audio/filter/af_lavrresample.c @@ -179,6 +179,37 @@ bool af_lavrresample_test_conversion(int src_format, int dst_format) check_output_conversion(dst_format) != AV_SAMPLE_FMT_NONE; } +static struct mp_chmap fudge_pairs[][2] = { + {MP_CHMAP2(BL, BR), MP_CHMAP2(SL, SR)}, + {MP_CHMAP2(SL, SR), MP_CHMAP2(BL, BR)}, + {MP_CHMAP2(SDL, SDR), MP_CHMAP2(SL, SR)}, + {MP_CHMAP2(SL, SR), MP_CHMAP2(SDL, SDR)}, +}; + +// Modify out_layout and return the new value. The intention is reducing the +// loss libswresample's rematrixing will cause by exchanging similar, but +// strictly speaking incompatible channel pairs. For example, 7.1 should be +// changed to 7.1(wide) without dropping the SL/SR channels. (We still leave +// it to libswresample to create the remix matrix.) +static uint64_t fudge_layout_conversion(struct af_instance *af, + uint64_t in, uint64_t out) +{ + for (int n = 0; n < MP_ARRAY_SIZE(fudge_pairs); n++) { + uint64_t a = mp_chmap_to_lavc(&fudge_pairs[n][0]); + uint64_t b = mp_chmap_to_lavc(&fudge_pairs[n][1]); + if ((in & a) == a && (in & b) == 0 && + (out & a) == 0 && (out & b) == b) + { + out = (out & ~b) | a; + + MP_VERBOSE(af, "Fudge: %s -> %s\n", + mp_chmap_to_str(&fudge_pairs[n][0]), + mp_chmap_to_str(&fudge_pairs[n][1])); + } + } + return out; +} + // mp_chmap_get_reorder() performs: // to->speaker[n] = from->speaker[src[n]] // but libavresample does: @@ -230,10 +261,13 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in, av_opt_set_double(s->avrctx, "cutoff", s->opts.cutoff, 0); + int normalize = s->opts.normalize; + if (normalize < 0) + normalize = af->opts->audio_normalize; #if HAVE_LIBSWRESAMPLE - av_opt_set_double(s->avrctx, "rematrix_maxval", s->opts.normalize ? 1 : 1000, 0); + av_opt_set_double(s->avrctx, "rematrix_maxval", normalize ? 1 : 1000, 0); #else - av_opt_set_int(s->avrctx, "normalize_mix_level", s->opts.normalize, 0); + av_opt_set_int(s->avrctx, "normalize_mix_level", !!normalize, 0); #endif if (mp_set_avopts(af->log, s->avrctx, s->avopts) < 0) @@ -297,6 +331,8 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in, if (map_out.num > out_lavc.num) mp_audio_set_channels(&s->pool_fmt, &map_out); + out_ch_layout = fudge_layout_conversion(af, in_ch_layout, out_ch_layout); + // Real conversion; output is input to avrctx_out. av_opt_set_int(s->avrctx, "in_channel_layout", in_ch_layout, 0); av_opt_set_int(s->avrctx, "out_channel_layout", out_ch_layout, 0); @@ -583,7 +619,7 @@ const struct af_info af_info_lavrresample = { .filter_size = 16, .cutoff = 0.0, .phase_shift = 10, - .normalize = 1, + .normalize = -1, }, .playback_speed = 1.0, .allow_detach = 1, @@ -594,7 +630,8 @@ const struct af_info af_info_lavrresample = { OPT_FLAG("linear", opts.linear, 0), OPT_DOUBLE("cutoff", opts.cutoff, M_OPT_RANGE, .min = 0, .max = 1), OPT_FLAG("detach", allow_detach, 0), - OPT_FLAG("normalize", opts.normalize, 0), + OPT_CHOICE("normalize", opts.normalize, 0, + ({"no", 0}, {"yes", 1}, {"auto", -1})), OPT_KEYVALUELIST("o", avopts, 0), {0} }, |