PR #24039 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24039 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24039.patch
>From f351bb5584a2296271a52ba8e6eb4d8ff37583d3 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 7 Aug 2026 12:10:01 +0200 Subject: [PATCH] swresample/rematrix: Avoid repeated calls to av_channel_layout* funcs Signed-off-by: Andreas Rheinhardt <[email protected]> --- libswresample/rematrix.c | 101 +++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index 269849a427..bcdb71ce4f 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -115,19 +115,20 @@ static int sane_layout(AVChannelLayout *ch_layout) { } else if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE) return 0; - if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker + uint64_t mask = av_channel_layout_subset(ch_layout, ~(uint64_t)0); + if(!(mask & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker return 0; - if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)))) // no asymmetric front + if (!even(mask & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT))) // no asymmetric front return 0; - if(!even(av_channel_layout_subset(ch_layout, (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)))) // no asymmetric side + if (!even(mask & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT))) // no asymmetric side return 0; - if(!even(av_channel_layout_subset(ch_layout, (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)))) + if (!even(mask & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT))) return 0; - if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)))) + if (!even(mask & (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER))) return 0; - if(!even(av_channel_layout_subset(ch_layout, (AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT)))) + if (!even(mask & (AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT))) return 0; - if(!even(av_channel_layout_subset(ch_layout, (AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT)))) + if (!even(mask & (AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT))) return 0; return 1; @@ -139,14 +140,14 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding) { double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; - uint64_t unaccounted = av_channel_layout_subset(in_ch_layout, UINT64_MAX) & - ~av_channel_layout_subset(out_ch_layout, UINT64_MAX); + uint64_t in_mask = av_channel_layout_subset(in_ch_layout, ~(uint64_t)0); + uint64_t out_mask = av_channel_layout_subset(out_ch_layout, ~(uint64_t)0); + uint64_t unaccounted = in_mask & ~out_mask; double maxcoef=0; int i, j; for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){ - if( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 - && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0) + if (in_mask & out_mask & (1ULL << i)) matrix[i][i]= 1.0; } @@ -154,8 +155,8 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay //FIXME implement full ac3 if(unaccounted & AV_CH_FRONT_CENTER){ - if (av_channel_layout_subset(out_ch_layout, AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) { - if (av_channel_layout_subset(in_ch_layout, AV_CH_LAYOUT_STEREO)) { + if ((out_mask & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) { + if (in_mask & AV_CH_LAYOUT_STEREO) { matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level; matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level; } else { @@ -166,23 +167,23 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay av_assert0(0); } if(unaccounted & AV_CH_LAYOUT_STEREO){ - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + if (out_mask & AV_CH_FRONT_CENTER) { matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2; matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2; - if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) + if (in_mask & AV_CH_FRONT_CENTER) matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2); }else av_assert0(0); } if(unaccounted & AV_CH_BACK_CENTER){ - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (out_mask & AV_CH_BACK_LEFT) { matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2; matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + } else if (out_mask & AV_CH_SIDE_LEFT) { matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2; matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (out_mask & AV_CH_FRONT_LEFT) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY || matrix_encoding == AV_MATRIX_ENCODING_DPLII) { if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) { @@ -196,24 +197,24 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; } - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (out_mask & AV_CH_FRONT_CENTER) { matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; }else av_assert0(0); } if(unaccounted & AV_CH_BACK_LEFT){ - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { + if (out_mask & AV_CH_BACK_CENTER) { matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2; matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { - if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + } else if (out_mask & AV_CH_SIDE_LEFT) { + if (in_mask & AV_CH_SIDE_LEFT) { matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2; matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2; }else{ matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0; matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0; } - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (out_mask & AV_CH_FRONT_LEFT) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) { matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2; matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2; @@ -228,7 +229,7 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level; matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level; } - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (out_mask & AV_CH_FRONT_CENTER) { matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2; matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2; }else @@ -236,20 +237,20 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay } if(unaccounted & AV_CH_SIDE_LEFT){ - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (out_mask & AV_CH_BACK_LEFT) { /* if back channels do not exist in the input, just copy side channels to back channels, otherwise mix side into back */ - if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + if (in_mask & AV_CH_BACK_LEFT) { matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2; matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2; } else { matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0; matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0; } - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { + } else if (out_mask & AV_CH_BACK_CENTER) { matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2; matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (out_mask & AV_CH_FRONT_LEFT) { if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) { matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2; matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2; @@ -264,7 +265,7 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level; matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level; } - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (out_mask & AV_CH_FRONT_CENTER) { matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2; matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2; }else @@ -272,10 +273,10 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay } if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){ - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + if (out_mask & AV_CH_FRONT_LEFT) { matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0; matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (out_mask & AV_CH_FRONT_CENTER) { matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2; matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2; }else @@ -283,16 +284,16 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay } if (unaccounted & AV_CH_TOP_FRONT_LEFT) { - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) { + if (out_mask & AV_CH_TOP_FRONT_CENTER) { matrix[TOP_FRONT_CENTER][TOP_FRONT_LEFT ] += M_SQRT1_2; matrix[TOP_FRONT_CENTER][TOP_FRONT_RIGHT] += M_SQRT1_2; - if (av_channel_layout_index_from_channel(in_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) + if (in_mask & AV_CH_TOP_FRONT_CENTER) matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2); - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (out_mask & AV_CH_FRONT_LEFT) { /* U+030 -> M+030 in ITU-R BS.2127-1, Table 16. */ matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += 1.0; matrix[FRONT_RIGHT][TOP_FRONT_RIGHT] += 1.0; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (out_mask & AV_CH_FRONT_CENTER) { matrix[FRONT_CENTER][TOP_FRONT_LEFT ] += M_SQRT1_2; matrix[FRONT_CENTER][TOP_FRONT_RIGHT] += M_SQRT1_2; } else @@ -300,23 +301,23 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay } if (unaccounted & AV_CH_TOP_BACK_LEFT) { - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_TOP_BACK_CENTER) >= 0) { + if (out_mask & AV_CH_TOP_BACK_CENTER) { matrix[TOP_BACK_CENTER][TOP_BACK_LEFT ] += M_SQRT1_2; matrix[TOP_BACK_CENTER][TOP_BACK_RIGHT] += M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_TOP_FRONT_LEFT) >= 0) { + } else if (out_mask & AV_CH_TOP_FRONT_LEFT) { /* IAMF v1.1.0, Section 7.3.2.1.1. */ matrix[TOP_FRONT_LEFT ][TOP_BACK_LEFT ] += M_SQRT1_2; matrix[TOP_FRONT_RIGHT][TOP_BACK_RIGHT] += M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + } else if (out_mask & AV_CH_BACK_LEFT) { matrix[BACK_LEFT ][TOP_BACK_LEFT ] += 1.0; matrix[BACK_RIGHT][TOP_BACK_RIGHT] += 1.0; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + } else if (out_mask & AV_CH_SIDE_LEFT) { matrix[SIDE_LEFT ][TOP_BACK_LEFT ] += 1.0; matrix[SIDE_RIGHT][TOP_BACK_RIGHT] += 1.0; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (out_mask & AV_CH_FRONT_LEFT) { matrix[FRONT_LEFT ][TOP_BACK_LEFT ] += surround_mix_level; matrix[FRONT_RIGHT][TOP_BACK_RIGHT] += surround_mix_level; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + } else if (out_mask & AV_CH_FRONT_CENTER) { matrix[FRONT_CENTER][TOP_BACK_LEFT ] += M_SQRT1_2; matrix[FRONT_CENTER][TOP_BACK_RIGHT] += M_SQRT1_2; } else @@ -325,19 +326,19 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay /* BS.2127-1 maps U+180 to rear outputs before front outputs. */ if (unaccounted & AV_CH_TOP_BACK_CENTER) { - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_TOP_BACK_LEFT) >= 0) { + if (out_mask & AV_CH_TOP_BACK_LEFT) { matrix[TOP_BACK_LEFT ][TOP_BACK_CENTER] += M_SQRT1_2; matrix[TOP_BACK_RIGHT][TOP_BACK_CENTER] += M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { + } else if (out_mask & AV_CH_BACK_LEFT) { matrix[BACK_LEFT ][TOP_BACK_CENTER] += M_SQRT1_2; matrix[BACK_RIGHT][TOP_BACK_CENTER] += M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { + } else if (out_mask & AV_CH_SIDE_LEFT) { matrix[SIDE_LEFT ][TOP_BACK_CENTER] += M_SQRT1_2; matrix[SIDE_RIGHT][TOP_BACK_CENTER] += M_SQRT1_2; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (out_mask & AV_CH_FRONT_LEFT) { matrix[FRONT_LEFT ][TOP_BACK_CENTER] += 0.5; matrix[FRONT_RIGHT][TOP_BACK_CENTER] += 0.5; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) + } else if (out_mask & AV_CH_FRONT_CENTER) matrix[FRONT_CENTER][TOP_BACK_CENTER] += 0.5; else av_assert0(0); @@ -345,9 +346,9 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay /* mix LFE into front left/right or center */ if (unaccounted & AV_CH_LOW_FREQUENCY) { - if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { + if (out_mask & AV_CH_FRONT_CENTER) { matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level; - } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { + } else if (out_mask & AV_CH_FRONT_LEFT) { matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; } else @@ -367,9 +368,7 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) matrix_param[stride*out_i + in_i] = matrix[i][j]; else - matrix_param[stride*out_i + in_i] = i == j && - ( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 - && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0); + matrix_param[stride*out_i + in_i] = i == j && (in_mask & out_mask & (1ULL << i)); sum += fabs(matrix_param[stride*out_i + in_i]); } maxcoef= FFMAX(maxcoef, sum); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
