This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 09f879b074280a42e3ff211db6cdf077fe61a55d Author: Kacper Michajłow <[email protected]> AuthorDate: Sun Sep 27 16:05:52 2026 +0200 Commit: Kacper Michajłow <[email protected]> CommitDate: Tue Sep 29 22:16:46 2026 +0200 swresample: keep integer samples if channels are only copied With a matrix, samples of more than 16 bits are mixed in floating point, which takes the lowest bits of s32. A matrix that only copies channels computes nothing, so select the internal format like without a matrix. Layouts that differ in the order of their channels or in unused ones get such a matrix. The matrix is built before the format is selected for this. The limit for its coefficients no longer looks at the selected format. For mixing that is an integer format only if the output has one or if it was set, which is what the limit looks at now. s64 still goes through double, the matrix has no functions for it. Bump the micro version, as this and the previous commits change which custom layouts can be used. Signed-off-by: Kacper Michajłow <[email protected]> --- libswresample/rematrix.c | 36 ++++++++++++++++++++++++++++++++---- libswresample/swresample.c | 34 +++++++++++++++++++++------------- libswresample/swresample_internal.h | 2 ++ libswresample/version.h | 2 +- tests/fate/libswresample.mak | 10 ++++++++++ 5 files changed, 66 insertions(+), 18 deletions(-) diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index 3bec10360e..31b1078bcc 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -697,7 +697,8 @@ av_cold static int auto_matrix(SwrContext *s) if (s->rematrix_maxval > 0) { maxval = s->rematrix_maxval; } else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT - || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) { + || (s->user_int_sample_fmt != AV_SAMPLE_FMT_NONE && + av_get_packed_sample_fmt(s->user_int_sample_fmt) < AV_SAMPLE_FMT_FLT)) { maxval = 1.0; } else maxval = INT_MAX; @@ -709,13 +710,12 @@ av_cold static int auto_matrix(SwrContext *s) s->matrix[1] - s->matrix[0], s->matrix_encoding, s); } -av_cold int swri_rematrix_init(SwrContext *s){ +av_cold int swri_rematrix_build(SwrContext *s) +{ int i, j; int nb_in = s->used_ch_layout.nb_channels; int nb_out = s->out.ch_count; - s->mix_any_f = NULL; - if (!s->rematrix_custom) { int r = auto_matrix(s); if (r) @@ -735,6 +735,34 @@ av_cold int swri_rematrix_init(SwrContext *s){ av_log(s, AV_LOG_DEBUG, "\n"); } } + + /* a channel that is one channel of the input, or silent, is not mixed */ + for (i = 0; i < nb_out; i++) { + int sources = 0; + for (j = 0; j < nb_in; j++) { + if (s->matrix[i][j] == 0.0) + continue; + if (s->matrix[i][j] != 1.0 || sources++) + return 1; + } + } + + return 0; +} + +av_cold int swri_rematrix_init(SwrContext *s){ + int i, j; + int nb_in = s->used_ch_layout.nb_channels; + int nb_out = s->out.ch_count; + + s->mix_any_f = NULL; + + /* a matrix that is applied was built by swri_rematrix_build() */ + if (!s->rematrix) { + int r = auto_matrix(s); + if (r) + return r; + } if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){ int maxsum = 0; s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int)); diff --git a/libswresample/swresample.c b/libswresample/swresample.c index 3fa2f3bf6c..cd84c731d9 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -154,7 +154,7 @@ av_cold void swr_close(SwrContext *s){ } av_cold int swr_init(struct SwrContext *s){ - int ret; + int ret, mixing; char l1[1024], l2[1024]; clear_context(s); @@ -232,6 +232,24 @@ av_cold int swr_init(struct SwrContext *s){ s->rematrix_volume!=1.0 || s->rematrix_custom; + av_channel_layout_describe(&s->out_ch_layout, l2, sizeof(l2)); + av_channel_layout_describe(&s->in_ch_layout, l1, sizeof(l1)); + if (( s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC + || s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) && s->used_ch_layout.nb_channels != s->out.ch_count && !s->rematrix_custom) { + av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s " + "but there is not enough information to do it\n", l1, l2); + return AVERROR(EINVAL); + } + + /* a matrix that only copies channels leaves the samples as they are, + * so the format in between is selected like without a matrix */ + mixing = 0; + if (s->rematrix) { + mixing = swri_rematrix_build(s); + if (mixing < 0) + return mixing; + } + if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){ // DSD to PCM conversion is done in floating point if( s->in_sample_fmt == AV_SAMPLE_FMT_DSD @@ -247,13 +265,13 @@ av_cold int swr_init(struct SwrContext *s){ +av_get_bytes_per_sample(s->out_sample_fmt) <= 3 ) { s->int_sample_fmt= AV_SAMPLE_FMT_S16P; }else if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2 - && !s->rematrix + && !mixing && s->out_sample_rate==s->in_sample_rate && !(s->flags & SWR_FLAG_RESAMPLE)){ s->int_sample_fmt= AV_SAMPLE_FMT_S16P; }else if( av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P && av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P - && !s->rematrix + && !mixing && s->out_sample_rate == s->in_sample_rate && !(s->flags & SWR_FLAG_RESAMPLE) && s->engine != SWR_ENGINE_SOXR){ @@ -328,22 +346,12 @@ av_cold int swr_init(struct SwrContext *s){ goto fail; } - av_channel_layout_describe(&s->out_ch_layout, l2, sizeof(l2)); - av_channel_layout_describe(&s->in_ch_layout, l1, sizeof(l1)); if (s->in_ch_layout.order != AV_CHANNEL_ORDER_UNSPEC && s->used_ch_layout.nb_channels != s->in_ch_layout.nb_channels) { av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_layout.nb_channels); ret = AVERROR(EINVAL); goto fail; } - if (( s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC - || s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) && s->used_ch_layout.nb_channels != s->out.ch_count && !s->rematrix_custom) { - av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s " - "but there is not enough information to do it\n", l1, l2); - ret = AVERROR(EINVAL); - goto fail; - } - av_assert0(s->used_ch_layout.nb_channels); av_assert0(s->out.ch_count); s->resample_first= RSC*s->out.ch_count/s->used_ch_layout.nb_channels - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0; diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h index 0cde2760bb..dcfb5335e7 100644 --- a/libswresample/swresample_internal.h +++ b/libswresample/swresample_internal.h @@ -207,6 +207,8 @@ void swri_noise_shaping_int32 (SwrContext *s, AudioData *dsts, const AudioData * void swri_noise_shaping_float (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count); void swri_noise_shaping_double(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count); +av_warn_unused_result +int swri_rematrix_build(SwrContext *s); av_warn_unused_result int swri_rematrix_init(SwrContext *s); void swri_rematrix_free(SwrContext *s); diff --git a/libswresample/version.h b/libswresample/version.h index d1795b5545..403be6227a 100644 --- a/libswresample/version.h +++ b/libswresample/version.h @@ -31,7 +31,7 @@ #include "version_major.h" #define LIBSWRESAMPLE_VERSION_MINOR 3 -#define LIBSWRESAMPLE_VERSION_MICRO 100 +#define LIBSWRESAMPLE_VERSION_MICRO 101 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ LIBSWRESAMPLE_VERSION_MINOR, \ diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak index 27a48a790b..19408e6567 100644 --- a/tests/fate/libswresample.mak +++ b/tests/fate/libswresample.mak @@ -1106,6 +1106,16 @@ fate-swr-custom-rematrix: REF = 2a14a44deb4ae26e3b474ddbfbc048f8 FATE_SWR += $(FATE_SWR_CUSTOM_REMATRIX-yes) +FATE_SWR_S32_SRC = mod(n*$(1)\,4294967296)/2147483648-1 +FATE_SWR_S32_7_1 = $(call FATE_SWR_S32_SRC,1103515245)|$(call FATE_SWR_S32_SRC,22695477)|$(call FATE_SWR_S32_SRC,214013)|$(call FATE_SWR_S32_SRC,1664525)|$(call FATE_SWR_S32_SRC,134775813)|$(call FATE_SWR_S32_SRC,69069)|$(call FATE_SWR_S32_SRC,1812433253)|$(call FATE_SWR_S32_SRC,2654435761) + +FATE_SWR_CUSTOM_REORDER-$(call ENCMUX, PCM_S32LE, PCM_S32LE, AEVALSRC_FILTER ARESAMPLE_FILTER AFORMAT_FILTER FILE_PROTOCOL) += fate-swr-custom-reorder +fate-swr-custom-reorder: CMD = md5 -filter_complex "aevalsrc=$(FATE_SWR_S32_7_1):c=7.1:d=0.5,aresample,aformat=f=s32:cl=7.1,aresample,aformat=f=s32:cl=FR+FL+FC+LFE+SL+SR+BL+BR[OUT]" -map [OUT] -f s32le +fate-swr-custom-reorder: CMP = oneline +fate-swr-custom-reorder: REF = 3621f90f05eb313858791b3915b9ca18 + +FATE_SWR += $(FATE_SWR_CUSTOM_REORDER-yes) + FATE_SWR_22_2_LAYOUTS = 9.1.6 9.1.4 7.2.3 7.1.6 7.1.4 7.1.2 5.1.6 5.1.4 5.1.2 7.1 5.1 stereo mono FATE_SWR_9_1_6_LAYOUTS = 9.1.4 7.2.3 7.1.6 7.1.4 7.1.2 5.1.6 5.1.4 5.1.2 7.1 5.1 stereo mono FATE_SWR_9_1_4_LAYOUTS = 7.2.3 7.1.4 7.1.2 5.1.4 5.1.2 7.1 5.1 stereo mono -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
