Limited to the same channels as a native layout, but not constrained by channel ordering.
Unified · Split
| @@ -49,6 +49,8 @@ version 7.1: · 48 unmodified lines | |||
| 49 | error, as such a specifier makes no sense | 49 | error, as such a specifier makes no sense |
| 50 | - Mastering Display and Content Light Level metadata support in hevc_nvenc | 50 | - Mastering Display and Content Light Level metadata support in hevc_nvenc |
| 51 | and av1_nvenc encoders | 51 | and av1_nvenc encoders |
| 52 | - libswresample now accepts custom order channel layouts as input, with some | ||
| 53 | constrains | ||
| 52 | 54 | ||
| 53 | 55 | ||
| 54 | version 7.0: | 56 | version 7.0: |
| @@ -104,7 +104,14 @@ static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s · 103 unmodified lines | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static int sane_layout(AVChannelLayout *ch_layout) { | 106 | static int sane_layout(AVChannelLayout *ch_layout) { |
| 107 | if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE) | 107 | if(ch_layout->nb_channels >= SWR_CH_MAX) |
| 108 | return 0; | ||
| 109 | if(ch_layout->order == AV_CHANNEL_ORDER_CUSTOM) | ||
| 110 | for (int i = 0; i < ch_layout->nb_channels; i++) { | ||
| 111 | if (ch_layout->u.map[i].id >= 64) | ||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | else if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE) | ||
| 108 | return 0; | 115 | return 0; |
| 109 | if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker | 116 | if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker |
| 110 | return 0; | 117 | return 0; |
| @@ -118,8 +125,6 @@ static int sane_layout(AVChannelLayout *ch_layout) { · 7 unmodified lines | |||
| 118 | return 0; | 125 | return 0; |
| 119 | if(!even(av_channel_layout_subset(ch_layout, (AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT)))) | 126 | if(!even(av_channel_layout_subset(ch_layout, (AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT)))) |
| 120 | return 0; | 127 | return 0; |
| 121 | if(ch_layout->nb_channels >= SWR_CH_MAX) | ||
| 122 | return 0; | ||
| 123 | 128 | ||
| 124 | return 1; | 129 | return 1; |
| 125 | } | 130 | } |
| @@ -130,9 +135,10 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay · 4 unmodified lines | |||
| 130 | ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding) | 135 | ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding) |
| 131 | { | 136 | { |
| 132 | double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; | 137 | double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; |
| 133 | uint64_t unaccounted = in_ch_layout->u.mask & ~out_ch_layout->u.mask; | 138 | uint64_t unaccounted = av_channel_layout_subset(in_ch_layout, UINT64_MAX) & |
| 139 | ~av_channel_layout_subset(out_ch_layout, UINT64_MAX); | ||
| 134 | double maxcoef=0; | 140 | double maxcoef=0; |
| 135 | int i, j, out_i; | 141 | int i, j; |
| 136 | 142 | ||
| 137 | for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){ | 143 | for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){ |
| 138 | if( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 | 144 | if( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 |
| @@ -305,14 +311,15 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay · 166 unmodified lines | |||
| 305 | } | 311 | } |
| 306 | 312 | ||
| 307 | 313 | ||
| 308 | for(out_i=i=0; i<64; i++){ | 314 | for (i = 0; i < 64; i++) { |
| 309 | double sum=0; | 315 | double sum=0; |
| 310 | int in_i=0; | 316 | int out_i = av_channel_layout_index_from_channel(out_ch_layout, i); |
| 311 | if (av_channel_layout_index_from_channel(out_ch_layout, i) < 0) | 317 | if (out_i < 0) |
| 312 | continue; | 318 | continue; |
| 313 | for(j=0; j<64; j++){ | 319 | for(j=0; j<64; j++){ |
| 314 | if (av_channel_layout_index_from_channel(in_ch_layout, j) < 0) | 320 | int in_i = av_channel_layout_index_from_channel(in_ch_layout, j); |
| 315 | continue; | 321 | if (in_i < 0) |
| 322 | continue; | ||
| 316 | if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) | 323 | if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) |
| 317 | matrix_param[stride*out_i + in_i] = matrix[i][j]; | 324 | matrix_param[stride*out_i + in_i] = matrix[i][j]; |
| 318 | else | 325 | else |
| @@ -320,10 +327,8 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay · 1 unmodified line | |||
| 320 | ( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 | 327 | ( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 |
| 321 | && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0); | 328 | && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0); |
| 322 | sum += fabs(matrix_param[stride*out_i + in_i]); | 329 | sum += fabs(matrix_param[stride*out_i + in_i]); |
| 323 | in_i++; | ||
| 324 | } | 330 | } |
| 325 | maxcoef= FFMAX(maxcoef, sum); | 331 | maxcoef= FFMAX(maxcoef, sum); |
| 326 | out_i++; | ||
| 327 | } | 332 | } |
| 328 | if(rematrix_volume < 0) | 333 | if(rematrix_volume < 0) |
| 329 | maxcoef = -rematrix_volume; | 334 | maxcoef = -rematrix_volume; |