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 | 49 | error, as such a specifier makes no sense |
| 50 | 50 | - Mastering Display and Content Light Level metadata support in hevc_nvenc |
| 51 | 51 | and av1_nvenc encoders |
| 52 | +- libswresample now accepts custom order channel layouts as input, with some | |
| 53 | + constrains | |
| 52 | 54 | |
| 53 | 55 | |
| 54 | 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 | 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 | 115 | return 0; |
| 109 | 116 | if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker |
| 110 | 117 | return 0; |
| @@ -118,8 +125,6 @@ static int sane_layout(AVChannelLayout *ch_layout) { · 7 unmodified lines | ||
| 118 | 125 | return 0; |
| 119 | 126 | if(!even(av_channel_layout_subset(ch_layout, (AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT)))) |
| 120 | 127 | return 0; |
| 121 | − if(ch_layout->nb_channels >= SWR_CH_MAX) | |
| 122 | − return 0; | |
| 123 | 128 | |
| 124 | 129 | return 1; |
| 125 | 130 | } |
| @@ -130,9 +135,10 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay · 4 unmodified lines | ||
| 130 | 135 | ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding) |
| 131 | 136 | { |
| 132 | 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 | 140 | double maxcoef=0; |
| 135 | − int i, j, out_i; | |
| 141 | + int i, j; | |
| 136 | 142 | |
| 137 | 143 | for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){ |
| 138 | 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 | 315 | double sum=0; |
| 310 | − int in_i=0; | |
| 311 | − if (av_channel_layout_index_from_channel(out_ch_layout, i) < 0) | |
| 316 | + int out_i = av_channel_layout_index_from_channel(out_ch_layout, i); | |
| 317 | + if (out_i < 0) | |
| 312 | 318 | continue; |
| 313 | 319 | for(j=0; j<64; j++){ |
| 314 | − if (av_channel_layout_index_from_channel(in_ch_layout, j) < 0) | |
| 315 | − continue; | |
| 320 | + int in_i = av_channel_layout_index_from_channel(in_ch_layout, j); | |
| 321 | + if (in_i < 0) | |
| 322 | + continue; | |
| 316 | 323 | if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) |
| 317 | 324 | matrix_param[stride*out_i + in_i] = matrix[i][j]; |
| 318 | 325 | else |
| @@ -320,10 +327,8 @@ static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLay · 1 unmodified line | ||
| 320 | 327 | ( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0 |
| 321 | 328 | && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0); |
| 322 | 329 | sum += fabs(matrix_param[stride*out_i + in_i]); |
| 323 | − in_i++; | |
| 324 | 330 | } |
| 325 | 331 | maxcoef= FFMAX(maxcoef, sum); |
| 326 | − out_i++; | |
| 327 | 332 | } |
| 328 | 333 | if(rematrix_volume < 0) |
| 329 | 334 | maxcoef = -rematrix_volume; |