James Almer: > Signed-off-by: James Almer <jamr...@gmail.com> > --- > libswresample/options.c | 33 +++- > libswresample/rematrix.c | 237 ++++++++++++++++++---------- > libswresample/rematrix_template.c | 7 +- > libswresample/swresample.c | 152 +++++++++++++++--- > libswresample/swresample.h | 63 ++++++++
This header still contains many references to swr_alloc_set_opts(). > libswresample/swresample_frame.c | 65 +++++++- > libswresample/swresample_internal.h | 10 +- > 7 files changed, 445 insertions(+), 122 deletions(-) > > diff --git a/libswresample/options.c b/libswresample/options.c > index 6911709157..ffa27c590d 100644 > --- a/libswresample/options.c > +++ b/libswresample/options.c > @@ -34,12 +34,19 @@ > > #define OFFSET(x) offsetof(SwrContext,x) > #define PARAM AV_OPT_FLAG_AUDIO_PARAM > +#define DEPREC AV_OPT_FLAG_DEPRECATED > > static const AVOption options[]={ > -{"ich" , "set input channel count" , > OFFSET(user_in_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM}, > -{"in_channel_count" , "set input channel count" , > OFFSET(user_in_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM}, > -{"och" , "set output channel count" , > OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM}, > -{"out_channel_count" , "set output channel count" , > OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM}, > +#if FF_API_OLD_CHANNEL_LAYOUT > +{"ich" , "set input channel count (Deprecated, use ichl)", > + > OFFSET(user_in_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM|DEPREC}, > +{"in_channel_count" , "set input channel count (Deprecated, use > in_chlayout)", > + > OFFSET(user_in_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM|DEPREC}, > +{"och" , "set output channel count (Deprecated, use ochl)", > + > OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM|DEPREC}, > +{"out_channel_count" , "set output channel count (Deprecated, use > out_chlayout)", > + > OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM|DEPREC}, > +#endif > {"uch" , "set used channel count" , > OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM}, > {"used_channel_count" , "set used channel count" , > OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0 }, 0 > , SWR_CH_MAX, PARAM}, > {"isr" , "set input sample rate" , OFFSET( > in_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , > INT_MAX , PARAM}, > @@ -52,10 +59,20 @@ static const AVOption options[]={ > {"out_sample_fmt" , "set output sample format" , > OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, > -1 , INT_MAX, PARAM}, > {"tsf" , "set internal sample format" , > OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , > {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, > {"internal_sample_fmt" , "set internal sample format" , > OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , > {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, > -{"icl" , "set input channel layout" , > OFFSET(user_in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, > INT64_MIN, INT64_MAX , PARAM, "channel_layout"}, > -{"in_channel_layout" , "set input channel layout" , > OFFSET(user_in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, > INT64_MIN, INT64_MAX , PARAM, "channel_layout"}, > -{"ocl" , "set output channel layout" , > OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, > INT64_MIN, INT64_MAX , PARAM, "channel_layout"}, > -{"out_channel_layout" , "set output channel layout" , > OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, > INT64_MIN, INT64_MAX , PARAM, "channel_layout"}, > +#if FF_API_OLD_CHANNEL_LAYOUT > +{"icl" , "set input channel layout (Deprecated, use ichl)", > + > OFFSET(user_in_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, > INT64_MIN, INT64_MAX, PARAM|DEPREC, "channel_layout"}, > +{"in_channel_layout" , "set input channel layout (Deprecated, use > in_chlayout)", > + > OFFSET(user_in_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, > INT64_MIN, INT64_MAX, PARAM|DEPREC, "channel_layout"}, > +{"ocl" , "set output channel layout (Deprecated, use ochl)", > + > OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, > INT64_MIN, INT64_MAX, PARAM|DEPREC, "channel_layout"}, > +{"out_channel_layout" , "set output channel layout (Deprecated, use > out_chlayout)", > + > OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, > INT64_MIN, INT64_MAX, PARAM|DEPREC, "channel_layout"}, > +#endif > +{"ichl" , "set input channel layout" , > OFFSET(user_in_chlayout ), AV_OPT_TYPE_CHLAYOUT, {.str=NULL }, 0, > 0 , PARAM, "chlayout"}, > +{"in_chlayout" , "set input channel layout" , > OFFSET(user_in_chlayout ), AV_OPT_TYPE_CHLAYOUT, {.str=NULL }, 0, > 0 , PARAM, "chlayout"}, > +{"ochl" , "set output channel layout" , > OFFSET(user_out_chlayout), AV_OPT_TYPE_CHLAYOUT, {.str=NULL }, 0, > 0 , PARAM, "chlayout"}, > +{"out_chlayout" , "set output channel layout" , > OFFSET(user_out_chlayout), AV_OPT_TYPE_CHLAYOUT, {.str=NULL }, 0, > 0 , PARAM, "chlayout"}, > {"clev" , "set center mix level" , OFFSET(clev > ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , > PARAM}, > {"center_mix_level" , "set center mix level" , OFFSET(clev > ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , > PARAM}, > {"slev" , "set surround mix level" , OFFSET(slev > ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , > PARAM}, > diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c > index 94b3de88f6..35086c218d 100644 > --- a/libswresample/rematrix.c > +++ b/libswresample/rematrix.c > @@ -64,15 +64,37 @@ > int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) > { > int nb_in, nb_out, in, out; > + int user_in_chlayout_nb_channels, user_out_chlayout_nb_channels; > > if (!s || s->in_convert) // s needs to be allocated but not initialized > return AVERROR(EINVAL); > memset(s->matrix, 0, sizeof(s->matrix)); > memset(s->matrix_flt, 0, sizeof(s->matrix_flt)); > - nb_in = (s->user_in_ch_count > 0) ? s->user_in_ch_count : > - av_get_channel_layout_nb_channels(s->user_in_ch_layout); > - nb_out = (s->user_out_ch_count > 0) ? s->user_out_ch_count : > - av_get_channel_layout_nb_channels(s->user_out_ch_layout); > + > +#if FF_API_OLD_CHANNEL_LAYOUT > +FF_DISABLE_DEPRECATION_WARNINGS > + user_in_chlayout_nb_channels = > av_get_channel_layout_nb_channels(s->user_in_ch_layout); > +FF_ENABLE_DEPRECATION_WARNINGS > + if (!user_in_chlayout_nb_channels) > +#endif > + user_in_chlayout_nb_channels = s->user_in_chlayout.nb_channels; > + nb_in = > +#if FF_API_OLD_CHANNEL_LAYOUT > + (s->user_in_ch_count > 0) ? s->user_in_ch_count : > +#endif > + user_in_chlayout_nb_channels; > +#if FF_API_OLD_CHANNEL_LAYOUT > +FF_DISABLE_DEPRECATION_WARNINGS > + user_out_chlayout_nb_channels = > av_get_channel_layout_nb_channels(s->user_out_ch_layout); > +FF_ENABLE_DEPRECATION_WARNINGS > + if (!user_out_chlayout_nb_channels) > +#endif > + user_out_chlayout_nb_channels = s->user_out_chlayout.nb_channels; > + nb_out = > +#if FF_API_OLD_CHANNEL_LAYOUT > + (s->user_out_ch_count > 0) ? s->user_out_ch_count : > +#endif > + user_out_chlayout_nb_channels; > for (out = 0; out < nb_out; out++) { > for (in = 0; in < nb_in; in++) > s->matrix_flt[out][in] = s->matrix[out][in] = matrix[in]; > @@ -88,95 +110,141 @@ static int even(int64_t layout){ > return 0; > } > > -static int64_t clean_layout(void *s, int64_t layout){ > - if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) { > +static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, > void *s) > +{ > + int ret = 0; > + > + if(av_channel_layout_index_from_channel(in, AV_CH_FRONT_CENTER) < 0 && > in->nb_channels == 1) { > char buf[128]; > - av_get_channel_layout_string(buf, sizeof(buf), -1, layout); > + av_channel_layout_describe(in, buf, sizeof(buf)); > av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf); > - return AV_CH_FRONT_CENTER; > - } > + *out = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; > + } else > + ret = av_channel_layout_copy(out, in); > > - return layout; > + return ret; > } > > -static int sane_layout(int64_t layout){ > - if(!(layout & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker > +static int sane_layout(AVChannelLayout *ch_layout) { > + 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 > return 0; > - if(!even(layout & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT))) // no > asymetric front > + if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT | > AV_CH_FRONT_RIGHT)))) // no asymetric front > return 0; > - if(!even(layout & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT))) // no > asymetric side > + if(!even(av_channel_layout_subset(ch_layout, (AV_CH_SIDE_LEFT | > AV_CH_SIDE_RIGHT)))) // no asymetric side > return 0; > - if(!even(layout & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT))) > + if(!even(av_channel_layout_subset(ch_layout, (AV_CH_BACK_LEFT | > AV_CH_BACK_RIGHT)))) > return 0; > - if(!even(layout & (AV_CH_FRONT_LEFT_OF_CENTER | > AV_CH_FRONT_RIGHT_OF_CENTER))) > + if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT_OF_CENTER > | AV_CH_FRONT_RIGHT_OF_CENTER)))) > return 0; > - if(av_get_channel_layout_nb_channels(layout) >= SWR_CH_MAX) > + if(ch_layout->nb_channels >= SWR_CH_MAX) > return 0; > > return 1; > } > > +#if FF_API_OLD_CHANNEL_LAYOUT > av_cold int swr_build_matrix(uint64_t in_ch_layout_param, uint64_t > out_ch_layout_param, > double center_mix_level, double > surround_mix_level, > double lfe_mix_level, double maxval, > double rematrix_volume, double *matrix_param, > int stride, enum AVMatrixEncoding > matrix_encoding, void *log_context) > { > - int i, j, out_i; > + AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 }; > + int ret; > + > + ret = av_channel_layout_from_mask(&in_ch_layout, in_ch_layout_param); > + ret |= av_channel_layout_from_mask(&out_ch_layout, out_ch_layout_param); > + if (ret < 0) > + return ret; > + > + return swr_build_matrix2(&in_ch_layout, &out_ch_layout, > center_mix_level, surround_mix_level, > + lfe_mix_level, maxval, rematrix_volume, > matrix_param, > + stride, matrix_encoding, log_context); > +} > +#endif > + > +av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const > AVChannelLayout *out_layout, > + double center_mix_level, double > surround_mix_level, > + double lfe_mix_level, double maxval, > + double rematrix_volume, double *matrix_param, > + ptrdiff_t stride, enum AVMatrixEncoding > matrix_encoding, void *log_context) > +{ > + int i, j, out_i, ret; > + AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 }; > double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; > - int64_t unaccounted, in_ch_layout, out_ch_layout; > + int64_t unaccounted; > double maxcoef=0; > char buf[128]; > > - in_ch_layout = clean_layout(log_context, in_ch_layout_param); > - out_ch_layout = clean_layout(log_context, out_ch_layout_param); > - > - if( out_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX > - && (in_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0 > - ) > - out_ch_layout = AV_CH_LAYOUT_STEREO; > + ret = clean_layout(&in_ch_layout, in_layout, log_context); > + ret |= clean_layout(&out_ch_layout, out_layout, log_context); > + if (ret < 0) > + goto fail; > > - if( in_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX > - && (out_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0 > - ) > - in_ch_layout = AV_CH_LAYOUT_STEREO; > - > - if (in_ch_layout == AV_CH_LAYOUT_22POINT2 && > - out_ch_layout != AV_CH_LAYOUT_22POINT2) { > - in_ch_layout = (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER); > - av_get_channel_layout_string(buf, sizeof(buf), -1, in_ch_layout); > + if( !av_channel_layout_compare(&out_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) > + && !av_channel_layout_subset(&in_ch_layout, > AV_CH_LAYOUT_STEREO_DOWNMIX) > + ) { > + av_channel_layout_uninit(&out_ch_layout); > + out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; > + } > + if( !av_channel_layout_compare(&in_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) > + && !av_channel_layout_subset(&out_ch_layout, > AV_CH_LAYOUT_STEREO_DOWNMIX) > + ) { > + av_channel_layout_uninit(&in_ch_layout); > + in_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; > + } > + if (!av_channel_layout_compare(&in_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2) && > + av_channel_layout_compare(&out_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2)) { > + av_channel_layout_from_mask(&in_ch_layout, > (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER)); > + av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); > av_log(log_context, AV_LOG_WARNING, > "Full-on remixing from 22.2 has not yet been implemented! " > "Processing the input as '%s'\n", > buf); > } > > - if(!sane_layout(in_ch_layout)){ > - av_get_channel_layout_string(buf, sizeof(buf), -1, > in_ch_layout_param); > + if(!av_channel_layout_check(&in_ch_layout)) { > + av_log(log_context, AV_LOG_ERROR, "Input channel layout is > invalid\n"); > + ret = AVERROR(EINVAL); > + goto fail; > + } > + if(!sane_layout(&in_ch_layout)) { > + av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); > av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not > supported\n", buf); > - return AVERROR(EINVAL); > + ret = AVERROR(EINVAL); > + goto fail; > } > > - if(!sane_layout(out_ch_layout)){ > - av_get_channel_layout_string(buf, sizeof(buf), -1, > out_ch_layout_param); > + if(!av_channel_layout_check(&out_ch_layout)) { > + av_log(log_context, AV_LOG_ERROR, "Output channel layout is > invalid\n"); > + ret = AVERROR(EINVAL); > + goto fail; > + } > + if(!sane_layout(&out_ch_layout)) { > + av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf)); > av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not > supported\n", buf); > - return AVERROR(EINVAL); > + ret = AVERROR(EINVAL); > + goto fail; > } > > for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){ > - if(in_ch_layout & out_ch_layout & (1ULL<<i)) > + int idx; > + if( (idx = av_channel_layout_index_from_channel(&in_ch_layout, i)) > >= 0 > + && av_channel_layout_index_from_channel(&out_ch_layout, i) == idx) > matrix[i][i]= 1.0; > } > > - unaccounted= in_ch_layout & ~out_ch_layout; > + unaccounted = in_ch_layout.u.mask & ~out_ch_layout.u.mask; Weird whitespace. > > //FIXME implement dolby surround > //FIXME implement full ac3 > > > if(unaccounted & AV_CH_FRONT_CENTER){ > - if((out_ch_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO){ > - if(in_ch_layout & AV_CH_LAYOUT_STEREO) { > + 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)) > { Missing whitespace. Applies to the whole patch. > matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level; > matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level; > } else { > @@ -187,23 +255,23 @@ av_cold int swr_build_matrix(uint64_t > in_ch_layout_param, uint64_t out_ch_layout > av_assert0(0); > } > if(unaccounted & AV_CH_LAYOUT_STEREO){ > - if(out_ch_layout & AV_CH_FRONT_CENTER){ > + if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_CENTER) >= 0){ > matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2; > matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2; > - if(in_ch_layout & AV_CH_FRONT_CENTER) > + if(av_channel_layout_index_from_channel(&in_ch_layout, > AV_CHAN_FRONT_CENTER) >= 0) > matrix[FRONT_CENTER][ FRONT_CENTER] = > center_mix_level*sqrt(2); > }else > av_assert0(0); > } > > if(unaccounted & AV_CH_BACK_CENTER){ > - if(out_ch_layout & AV_CH_BACK_LEFT){ > + if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_BACK_LEFT) >= 0){ > matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2; > matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2; > - }else if(out_ch_layout & AV_CH_SIDE_LEFT){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_SIDE_LEFT) >= 0){ > matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2; > matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2; > - }else if(out_ch_layout & AV_CH_FRONT_LEFT){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_LEFT) >= 0){ > if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY || > matrix_encoding == AV_MATRIX_ENCODING_DPLII) { > if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) { > @@ -217,24 +285,24 @@ av_cold int swr_build_matrix(uint64_t > in_ch_layout_param, uint64_t out_ch_layout > matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * > M_SQRT1_2; > matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * > M_SQRT1_2; > } > - }else if(out_ch_layout & AV_CH_FRONT_CENTER){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_CENTER) >= 0){ > matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * > M_SQRT1_2; > }else > av_assert0(0); > } > if(unaccounted & AV_CH_BACK_LEFT){ > - if(out_ch_layout & AV_CH_BACK_CENTER){ > + if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_BACK_CENTER) >= 0){ > matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2; > matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2; > - }else if(out_ch_layout & AV_CH_SIDE_LEFT){ > - if(in_ch_layout & AV_CH_SIDE_LEFT){ > + }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){ > 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(out_ch_layout & AV_CH_FRONT_LEFT){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_LEFT) >= 0){ > 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; > @@ -249,7 +317,7 @@ av_cold int swr_build_matrix(uint64_t in_ch_layout_param, > uint64_t out_ch_layout > matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level; > matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level; > } > - }else if(out_ch_layout & AV_CH_FRONT_CENTER){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_CENTER) >= 0){ > matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2; > matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2; > }else > @@ -257,20 +325,20 @@ av_cold int swr_build_matrix(uint64_t > in_ch_layout_param, uint64_t out_ch_layout > } > > if(unaccounted & AV_CH_SIDE_LEFT){ > - if(out_ch_layout & AV_CH_BACK_LEFT){ > + if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_BACK_LEFT) >= 0){ > /* if back channels do not exist in the input, just copy side > channels to back channels, otherwise mix side into back */ > - if (in_ch_layout & AV_CH_BACK_LEFT) { > + if (av_channel_layout_index_from_channel(&in_ch_layout, > AV_CHAN_BACK_LEFT) >= 0) { > 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(out_ch_layout & AV_CH_BACK_CENTER){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_BACK_CENTER) >= 0){ > matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2; > matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2; > - }else if(out_ch_layout & AV_CH_FRONT_LEFT){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_LEFT) >= 0){ > 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; > @@ -285,7 +353,7 @@ av_cold int swr_build_matrix(uint64_t in_ch_layout_param, > uint64_t out_ch_layout > matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level; > matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level; > } > - }else if(out_ch_layout & AV_CH_FRONT_CENTER){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_CENTER) >= 0){ > matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * > M_SQRT1_2; > matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * > M_SQRT1_2; > }else > @@ -293,10 +361,10 @@ av_cold int swr_build_matrix(uint64_t > in_ch_layout_param, uint64_t out_ch_layout > } > > if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){ > - if(out_ch_layout & AV_CH_FRONT_LEFT){ > + if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_LEFT) >= 0){ > matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0; > matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0; > - }else if(out_ch_layout & AV_CH_FRONT_CENTER){ > + }else if(av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_CENTER) >= 0){ > matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2; > matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2; > }else > @@ -304,9 +372,9 @@ av_cold int swr_build_matrix(uint64_t in_ch_layout_param, > uint64_t out_ch_layout > } > /* mix LFE into front left/right or center */ > if (unaccounted & AV_CH_LOW_FREQUENCY) { > - if (out_ch_layout & AV_CH_FRONT_CENTER) { > + if (av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_CENTER) >= 0) { > matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level; > - } else if (out_ch_layout & AV_CH_FRONT_LEFT) { > + } else if (av_channel_layout_index_from_channel(&out_ch_layout, > AV_CHAN_FRONT_LEFT) >= 0) { > matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; > matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; > } else > @@ -316,15 +384,19 @@ av_cold int swr_build_matrix(uint64_t > in_ch_layout_param, uint64_t out_ch_layout > for(out_i=i=0; i<64; i++){ > double sum=0; > int in_i=0; > - if((out_ch_layout & (1ULL<<i)) == 0) > + if(av_channel_layout_index_from_channel(&out_ch_layout, i) < 0) > continue; > for(j=0; j<64; j++){ > - if((in_ch_layout & (1ULL<<j)) == 0) > + if(av_channel_layout_index_from_channel(&in_ch_layout, j) < 0) > continue; > 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 && (in_ch_layout > & out_ch_layout & (1ULL<<i)); > + else { > + int idx; > + matrix_param[stride*out_i + in_i] = i == j && > + ( (idx = > av_channel_layout_index_from_channel(&in_ch_layout, i)) >= 0 > + && av_channel_layout_index_from_channel(&out_ch_layout, i) > == idx); > + } > sum += fabs(matrix_param[stride*out_i + in_i]); > in_i++; > } > @@ -350,17 +422,22 @@ av_cold int swr_build_matrix(uint64_t > in_ch_layout_param, uint64_t out_ch_layout > } > > av_log(log_context, AV_LOG_DEBUG, "Matrix coefficients:\n"); > - for(i=0; i<av_get_channel_layout_nb_channels(out_ch_layout); i++){ > - const char *c = > - > av_get_channel_name(av_channel_layout_extract_channel(out_ch_layout, i)); > - av_log(log_context, AV_LOG_DEBUG, "%s: ", c ? c : "?"); > - for(j=0; j<av_get_channel_layout_nb_channels(in_ch_layout); j++){ > - c = > av_get_channel_name(av_channel_layout_extract_channel(in_ch_layout, j)); > - av_log(log_context, AV_LOG_DEBUG, "%s:%f ", c ? c : "?", > matrix_param[stride*i + j]); > + for(i = 0; i < out_ch_layout.nb_channels; i++){ > + av_channel_name(buf, sizeof(buf), > av_channel_layout_channel_from_index(&out_ch_layout, i)); > + av_log(log_context, AV_LOG_DEBUG, "%s: ", buf); > + for(j = 0; j < in_ch_layout.nb_channels; j++){ > + av_channel_name(buf, sizeof(buf), > av_channel_layout_channel_from_index(&in_ch_layout, j)); > + av_log(log_context, AV_LOG_DEBUG, "%s:%f ", buf, > matrix_param[stride*i + j]); > } > av_log(log_context, AV_LOG_DEBUG, "\n"); > } > - return 0; > + > + ret = 0; > +fail: > + av_channel_layout_uninit(&in_ch_layout); > + av_channel_layout_uninit(&out_ch_layout); > + > + return ret; > } > > av_cold static int auto_matrix(SwrContext *s) > @@ -377,7 +454,7 @@ av_cold static int auto_matrix(SwrContext *s) > maxval = INT_MAX; > > memset(s->matrix, 0, sizeof(s->matrix)); > - ret = swr_build_matrix(s->in_ch_layout, s->out_ch_layout, > + ret = swr_build_matrix2(&s->in_ch_layout, &s->out_ch_layout, > s->clev, s->slev, s->lfe_mix_level, > maxval, s->rematrix_volume, (double*)s->matrix, > s->matrix[1] - s->matrix[0], s->matrix_encoding, > s); > @@ -519,8 +596,8 @@ int swri_rematrix(SwrContext *s, AudioData *out, > AudioData *in, int len, int mus > off = len1 * out->bps; > } > > - av_assert0(!s->out_ch_layout || out->ch_count == > av_get_channel_layout_nb_channels(s->out_ch_layout)); > - av_assert0(!s-> in_ch_layout || in ->ch_count == > av_get_channel_layout_nb_channels(s-> in_ch_layout)); > + av_assert0(s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || > out->ch_count == s->out_ch_layout.nb_channels); > + av_assert0(s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || in > ->ch_count == s->in_ch_layout.nb_channels); > > for(out_i=0; out_i<out->ch_count; out_i++){ > switch(s->matrix_ch[out_i][0]){ > diff --git a/libswresample/rematrix_template.c > b/libswresample/rematrix_template.c > index add65e3155..f5a508361c 100644 > --- a/libswresample/rematrix_template.c > +++ b/libswresample/rematrix_template.c > @@ -88,13 +88,16 @@ static void RENAME(mix8to2)(SAMPLE **out, const SAMPLE > **in, COEFF *coeffp, inte > } > > static RENAME(mix_any_func_type) *RENAME(get_mix_any_func)(SwrContext *s){ > - if( s->out_ch_layout == AV_CH_LAYOUT_STEREO && (s->in_ch_layout == > AV_CH_LAYOUT_5POINT1 || s->in_ch_layout == AV_CH_LAYOUT_5POINT1_BACK) > + if( !av_channel_layout_compare(&s->out_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO) > + && ( !av_channel_layout_compare(&s->in_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1) > + || !av_channel_layout_compare(&s->in_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK)) > && s->matrix[0][2] == s->matrix[1][2] && s->matrix[0][3] == > s->matrix[1][3] > && !s->matrix[0][1] && !s->matrix[0][5] && !s->matrix[1][0] && > !s->matrix[1][4] > ) > return RENAME(mix6to2); > > - if( s->out_ch_layout == AV_CH_LAYOUT_STEREO && s->in_ch_layout == > AV_CH_LAYOUT_7POINT1 > + if( !av_channel_layout_compare(&s->out_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO) > + && !av_channel_layout_compare(&s->in_ch_layout, > &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1) > && s->matrix[0][2] == s->matrix[1][2] && s->matrix[0][3] == > s->matrix[1][3] > && !s->matrix[0][1] && !s->matrix[0][5] && !s->matrix[1][0] && > !s->matrix[1][4] > && !s->matrix[0][7] && !s->matrix[1][6] > diff --git a/libswresample/swresample.c b/libswresample/swresample.c > index 16734c9df9..f8fbd9134b 100644 > --- a/libswresample/swresample.c > +++ b/libswresample/swresample.c > @@ -56,6 +56,8 @@ int swr_set_channel_mapping(struct SwrContext *s, const int > *channel_map){ > return 0; > } > > +#if FF_API_OLD_CHANNEL_LAYOUT > +FF_DISABLE_DEPRECATION_WARNINGS > struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, > int64_t out_ch_layout, enum > AVSampleFormat out_sample_fmt, int out_sample_rate, > int64_t in_ch_layout, enum > AVSampleFormat in_sample_fmt, int in_sample_rate, > @@ -97,6 +99,58 @@ fail: > swr_free(&s); > return NULL; > } > +FF_ENABLE_DEPRECATION_WARNINGS > +#endif > + > +int swr_alloc_set_opts2(struct SwrContext **ps, > + AVChannelLayout *out_ch_layout, enum AVSampleFormat > out_sample_fmt, int out_sample_rate, > + AVChannelLayout *in_ch_layout, enum AVSampleFormat > in_sample_fmt, int in_sample_rate, > + int log_offset, void *log_ctx) { > + struct SwrContext *s = *ps; > + int ret; > + > + if (!s) s = swr_alloc(); > + if (!s) return AVERROR(ENOMEM); > + > + s->log_level_offset= log_offset; > + s->log_ctx= log_ctx; This has been copied from swr_alloc_set_opts without fixing whitespace issues. > + > + if ((ret = av_opt_set_chlayout(s, "ochl", out_ch_layout, 0)) < 0) > + goto fail; > + > + if ((ret = av_opt_set_int(s, "osf", out_sample_fmt, 0)) < 0) > + goto fail; > + > + if ((ret = av_opt_set_int(s, "osr", out_sample_rate, 0)) < 0) > + goto fail; > + > + if ((ret = av_opt_set_chlayout(s, "ichl", in_ch_layout, 0)) < 0) > + goto fail; > + > + if ((ret = av_opt_set_int(s, "isf", in_sample_fmt, 0)) < 0) > + goto fail; > + > + if ((ret = av_opt_set_int(s, "isr", in_sample_rate, 0)) < 0) > + goto fail; > + > + av_opt_set_int(s, "uch", 0, 0); > + > +#if FF_API_OLD_CHANNEL_LAYOUT > + // Clear old API values so they don't take precedence in swr_init() > + av_opt_set_int(s, "icl", 0, 0); > + av_opt_set_int(s, "ocl", 0, 0); > + av_opt_set_int(s, "ich", 0, 0); > + av_opt_set_int(s, "och", 0, 0); > +#endif > + > + *ps = s; > + > + return 0; > +fail: > + av_log(s, AV_LOG_ERROR, "Failed to set option\n"); > + swr_free(ps); In case s has been allocated by this function, it leaks. *ps = s needs to be moved directly after allocation. And why don't you implement the old API in terms of the new API? > + return ret; > +} > > static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt){ > a->fmt = fmt; > @@ -125,6 +179,8 @@ static void clear_context(SwrContext *s){ > free_temp(&s->drop_temp); > free_temp(&s->dither.noise); > free_temp(&s->dither.temp); > + av_channel_layout_uninit(&s->in_ch_layout); > + av_channel_layout_uninit(&s->out_ch_layout); > swri_audio_convert_free(&s-> in_convert); > swri_audio_convert_free(&s->out_convert); > swri_audio_convert_free(&s->full_convert); > @@ -138,6 +194,9 @@ av_cold void swr_free(SwrContext **ss){ > SwrContext *s= *ss; > if(s){ > clear_context(s); > + av_channel_layout_uninit(&s->user_in_chlayout); > + av_channel_layout_uninit(&s->user_out_chlayout); > + > if (s->resampler) > s->resampler->free(&s->resample); > } > @@ -172,25 +231,66 @@ av_cold int swr_init(struct SwrContext *s){ > av_log(s, AV_LOG_ERROR, "Requested output sample rate %d is > invalid\n", s->out_sample_rate); > return AVERROR(EINVAL); > } > + s->used_ch_count = s->user_used_ch_count; > +#if FF_API_OLD_CHANNEL_LAYOUT > s->out.ch_count = s-> user_out_ch_count; > s-> in.ch_count = s-> user_in_ch_count; > - s->used_ch_count = s->user_used_ch_count; > > - s-> in_ch_layout = s-> user_in_ch_layout; > - s->out_ch_layout = s->user_out_ch_layout; > + // if the old/new fields are set inconsistently, prefer the old ones > + if ((s->user_in_ch_count && s->user_in_ch_count != > s->user_in_chlayout.nb_channels) || > + (s->user_in_ch_layout && (s->user_in_chlayout.order != > AV_CHANNEL_ORDER_NATIVE || > + s->user_in_chlayout.u.mask != > s->user_in_ch_layout))) { > + av_channel_layout_uninit(&s->in_ch_layout); > + if (s->user_in_ch_layout) > + av_channel_layout_from_mask(&s->in_ch_layout, > s->user_in_ch_layout); > + else { > + s->in_ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; > + s->in_ch_layout.nb_channels = s->user_in_ch_count; > + } > + } else > + av_channel_layout_copy(&s->in_ch_layout, &s->user_in_chlayout); > + > + if ((s->user_out_ch_count && s->user_out_ch_count != > s->user_out_chlayout.nb_channels) || > + (s->user_out_ch_layout && (s->user_out_chlayout.order != > AV_CHANNEL_ORDER_NATIVE || > + s->user_out_chlayout.u.mask != > s->user_out_ch_layout))) { > + av_channel_layout_uninit(&s->out_ch_layout); > + if (s->user_out_ch_layout) > + av_channel_layout_from_mask(&s->out_ch_layout, > s->user_out_ch_layout); > + else { > + s->out_ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; > + s->out_ch_layout.nb_channels = s->user_out_ch_count; > + } > + } else > + av_channel_layout_copy(&s->out_ch_layout, &s->user_out_chlayout); > + > + if (!s->out.ch_count && !s->user_out_ch_layout) > + s->out.ch_count = s->out_ch_layout.nb_channels; > + if (!s-> in.ch_count && !s-> user_in_ch_layout) > + s-> in.ch_count = s->in_ch_layout.nb_channels; > +#else > + s->out.ch_count = s-> user_out_chlayout.nb_channels; > + s-> in.ch_count = s-> user_in_chlayout.nb_channels; > + > + ret = av_channel_layout_copy(&s->in_ch_layout, &s->user_in_chlayout); > + ret |= av_channel_layout_copy(&s->out_ch_layout, &s->user_out_chlayout); > + if (ret < 0) > + return ret; > +#endif > > s->int_sample_fmt= s->user_int_sample_fmt; > > s->dither.method = s->user_dither_method; > > - if(av_get_channel_layout_nb_channels(s-> in_ch_layout) > SWR_CH_MAX) { > - av_log(s, AV_LOG_WARNING, "Input channel layout 0x%"PRIx64" is > invalid or unsupported.\n", s-> in_ch_layout); > - s->in_ch_layout = 0; > + if (!av_channel_layout_check(&s->in_ch_layout) || > s->in_ch_layout.nb_channels > SWR_CH_MAX) { > + av_channel_layout_describe(&s->in_ch_layout, l1, sizeof(l1)); > + av_log(s, AV_LOG_WARNING, "Input channel layout \"%s\" is invalid or > unsupported.\n", l1); > + av_channel_layout_uninit(&s->in_ch_layout); > } > > - if(av_get_channel_layout_nb_channels(s->out_ch_layout) > SWR_CH_MAX) { > - av_log(s, AV_LOG_WARNING, "Output channel layout 0x%"PRIx64" is > invalid or unsupported.\n", s->out_ch_layout); > - s->out_ch_layout = 0; > + if (!av_channel_layout_check(&s->out_ch_layout) || > s->out_ch_layout.nb_channels > SWR_CH_MAX) { > + av_channel_layout_describe(&s->out_ch_layout, l2, sizeof(l2)); > + av_log(s, AV_LOG_WARNING, "Output channel layout \"%s\" is invalid > or unsupported.\n", l2); > + av_channel_layout_uninit(&s->out_ch_layout); > } > > switch(s->engine){ > @@ -206,17 +306,18 @@ av_cold int swr_init(struct SwrContext *s){ > if(!s->used_ch_count) > s->used_ch_count= s->in.ch_count; > > - if(s->used_ch_count && s-> in_ch_layout && s->used_ch_count != > av_get_channel_layout_nb_channels(s-> in_ch_layout)){ > + if(s->used_ch_count && s->in_ch_layout.order != AV_CHANNEL_ORDER_UNSPEC > && s->used_ch_count != s->in_ch_layout.nb_channels){ > av_log(s, AV_LOG_WARNING, "Input channel layout has a different > number of channels than the number of used channels, ignoring layout\n"); > - s-> in_ch_layout= 0; > + av_channel_layout_uninit(&s->in_ch_layout); > } > > - if(!s-> in_ch_layout) > - s-> in_ch_layout= av_get_default_channel_layout(s->used_ch_count); > - if(!s->out_ch_layout) > - s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count); > + if(!s->in_ch_layout.nb_channels || s->in_ch_layout.order == > AV_CHANNEL_ORDER_UNSPEC) > + av_channel_layout_default(&s->in_ch_layout, s->used_ch_count); > + if(!s->out_ch_layout.nb_channels || s->out_ch_layout.order == > AV_CHANNEL_ORDER_UNSPEC) > + av_channel_layout_default(&s->out_ch_layout, s->out.ch_count); > > - s->rematrix= s->out_ch_layout !=s->in_ch_layout || > s->rematrix_volume!=1.0 || > + s->rematrix= av_channel_layout_compare(&s->out_ch_layout, > &s->in_ch_layout) || > + s->rematrix_volume!=1.0 || > s->rematrix_custom; > > if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){ > @@ -291,33 +392,36 @@ av_cold int swr_init(struct SwrContext *s){ > > #define RSC 1 //FIXME finetune > if(!s-> in.ch_count) > - s-> in.ch_count= av_get_channel_layout_nb_channels(s-> in_ch_layout); > + s-> in.ch_count = s->in_ch_layout.nb_channels; > if(!s->used_ch_count) > s->used_ch_count= s->in.ch_count; > if(!s->out.ch_count) > - s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout); > + s->out.ch_count = s->out_ch_layout.nb_channels; > > if(!s-> in.ch_count){ > - av_assert0(!s->in_ch_layout); > + av_assert0(s->in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC); > av_log(s, AV_LOG_ERROR, "Input channel count and layout are > unset\n"); > ret = AVERROR(EINVAL); > goto fail; > } > > - av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> > in_ch_layout); > - av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, > s->out_ch_layout); > - if (s->out_ch_layout && s->out.ch_count != > av_get_channel_layout_nb_channels(s->out_ch_layout)) { > +#if FF_API_OLD_CHANNEL_LAYOUT > + av_channel_layout_describe(&s->out_ch_layout, l1, sizeof(l1)); > + if (s->out_ch_layout.order != AV_CHANNEL_ORDER_UNSPEC && s->out.ch_count > != s->out_ch_layout.nb_channels) { > av_log(s, AV_LOG_ERROR, "Output channel layout %s mismatches > specified channel count %d\n", l2, s->out.ch_count); > ret = AVERROR(EINVAL); > goto fail; > } > - if (s->in_ch_layout && s->used_ch_count != > av_get_channel_layout_nb_channels(s->in_ch_layout)) { > +#endif > + av_channel_layout_describe(&s->in_ch_layout, l1, sizeof(l1)); > + if (s->in_ch_layout.order != AV_CHANNEL_ORDER_UNSPEC && s->used_ch_count > != 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_count); > ret = AVERROR(EINVAL); > goto fail; > } > > - if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != > s->out.ch_count && !s->rematrix_custom) { > + if (( s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC > + || s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) && > s->used_ch_count != 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); > diff --git a/libswresample/swresample.h b/libswresample/swresample.h > index c7b84fbcac..c6ff2345e9 100644 > --- a/libswresample/swresample.h > +++ b/libswresample/swresample.h > @@ -227,6 +227,7 @@ int swr_init(struct SwrContext *s); > */ > int swr_is_initialized(struct SwrContext *s); > > +#if FF_API_OLD_CHANNEL_LAYOUT > /** > * Allocate SwrContext if needed and set/reset common parameters. > * > @@ -246,12 +247,40 @@ int swr_is_initialized(struct SwrContext *s); > * > * @see swr_init(), swr_free() > * @return NULL on error, allocated context otherwise > + * @deprecated use @ref swr_alloc_set_opts2() > */ > +attribute_deprecated > struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, > int64_t out_ch_layout, enum > AVSampleFormat out_sample_fmt, int out_sample_rate, > int64_t in_ch_layout, enum > AVSampleFormat in_sample_fmt, int in_sample_rate, > int log_offset, void *log_ctx); > +#endif > > +/** > + * Allocate SwrContext if needed and set/reset common parameters. > + * > + * This function does not require s to be allocated with swr_alloc(). On the > + * other hand, swr_alloc() can use swr_alloc_set_opts() to set the parameters > + * on the allocated context. > + * > + * @param ps Pointer to an existing Swr context if available, > or to NULL if not. > + * On success, *ps will be set the allocated context. This does not sound like proper English to me. Moreover, it does not document that an already allocated context will be freed here on error. > + * @param out_ch_layout output channel layout (AV_CH_LAYOUT_*) > + * @param out_sample_fmt output sample format (AV_SAMPLE_FMT_*). > + * @param out_sample_rate output sample rate (frequency in Hz) > + * @param in_ch_layout input channel layout (AV_CH_LAYOUT_*) > + * @param in_sample_fmt input sample format (AV_SAMPLE_FMT_*). > + * @param in_sample_rate input sample rate (frequency in Hz) > + * @param log_offset logging level offset > + * @param log_ctx parent logging context, can be NULL > + * > + * @see swr_init(), swr_free() > + * @return 0 on success, a negative AVERROR code on error. > + */ > +int swr_alloc_set_opts2(struct SwrContext **ps, > + AVChannelLayout *out_ch_layout, enum AVSampleFormat > out_sample_fmt, int out_sample_rate, > + AVChannelLayout *in_ch_layout, enum AVSampleFormat > in_sample_fmt, int in_sample_rate, > + int log_offset, void *log_ctx); > /** > * @} > * > @@ -362,6 +391,7 @@ int swr_set_compensation(struct SwrContext *s, int > sample_delta, int compensatio > */ > int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map); > > +#if FF_API_OLD_CHANNEL_LAYOUT > /** > * Generate a channel mixing matrix. > * > @@ -384,13 +414,46 @@ int swr_set_channel_mapping(struct SwrContext *s, const > int *channel_map); > * @param matrix_encoding matrixed stereo downmix mode (e.g. dplii) > * @param log_ctx parent logging context, can be NULL > * @return 0 on success, negative AVERROR code on failure > + * @deprecated use @ref swr_build_matrix2() > */ > +attribute_deprecated > int swr_build_matrix(uint64_t in_layout, uint64_t out_layout, > double center_mix_level, double surround_mix_level, > double lfe_mix_level, double rematrix_maxval, > double rematrix_volume, double *matrix, > int stride, enum AVMatrixEncoding matrix_encoding, > void *log_ctx); > +#endif > + > +/** > + * Generate a channel mixing matrix. > + * > + * This function is the one used internally by libswresample for building the > + * default mixing matrix. It is made public just as a utility function for > + * building custom matrices. > + * > + * @param in_layout input channel layout > + * @param out_layout output channel layout > + * @param center_mix_level mix level for the center channel > + * @param surround_mix_level mix level for the surround channel(s) > + * @param lfe_mix_level mix level for the low-frequency effects channel > + * @param rematrix_maxval if 1.0, coefficients will be normalized to > prevent > + * overflow. if INT_MAX, coefficients will not be > + * normalized. > + * @param[out] matrix mixing coefficients; matrix[i + stride * o] is > + * the weight of input channel i in output > channel o. The parameter below is named matrix_param. > + * @param stride distance between adjacent input channels in the > + * matrix array > + * @param matrix_encoding matrixed stereo downmix mode (e.g. dplii) > + * @param log_ctx parent logging context, can be NULL > + * @return 0 on success, negative AVERROR code on failure > + */ > +int swr_build_matrix2(const AVChannelLayout *in_layout, const > AVChannelLayout *out_layout, > + double center_mix_level, double surround_mix_level, > + double lfe_mix_level, double maxval, > + double rematrix_volume, double *matrix_param, > + ptrdiff_t stride, enum AVMatrixEncoding > matrix_encoding, > + void *log_context); > > /** > * Set a customized remix matrix. > diff --git a/libswresample/swresample_frame.c > b/libswresample/swresample_frame.c > index d95c1cc537..747cf119a9 100644 > --- a/libswresample/swresample_frame.c > +++ b/libswresample/swresample_frame.c > @@ -29,7 +29,19 @@ int swr_config_frame(SwrContext *s, const AVFrame *out, > const AVFrame *in) > swr_close(s); > > if (in) { > - if (av_opt_set_int(s, "icl", in->channel_layout, 0) < 0) > + AVChannelLayout in_ch_layout = { 0 }; > +#if FF_API_OLD_CHANNEL_LAYOUT > +FF_DISABLE_DEPRECATION_WARNINGS > + // if the old/new fields are set inconsistently, prefer the old ones > + if ((in->channel_layout && (in->ch_layout.order != > AV_CHANNEL_ORDER_NATIVE || > + in->ch_layout.u.mask != > in->channel_layout))) { > + av_channel_layout_from_mask(&in_ch_layout, in->channel_layout); > +FF_ENABLE_DEPRECATION_WARNINGS > + } else > +#endif > + if (av_channel_layout_copy(&in_ch_layout, &in->ch_layout) < 0) > + goto fail; > + if (av_opt_set_chlayout(s, "ichl", &in_ch_layout, 0) < 0) > goto fail; > if (av_opt_set_int(s, "isf", in->format, 0) < 0) > goto fail; > @@ -38,7 +50,19 @@ int swr_config_frame(SwrContext *s, const AVFrame *out, > const AVFrame *in) > } > > if (out) { > - if (av_opt_set_int(s, "ocl", out->channel_layout, 0) < 0) > + AVChannelLayout out_ch_layout = { 0 }; > +#if FF_API_OLD_CHANNEL_LAYOUT > +FF_DISABLE_DEPRECATION_WARNINGS > + // if the old/new fields are set inconsistently, prefer the old ones > + if ((out->channel_layout && (out->ch_layout.order != > AV_CHANNEL_ORDER_NATIVE || > + out->ch_layout.u.mask != > out->channel_layout))) { > + av_channel_layout_from_mask(&out_ch_layout, out->channel_layout); > +FF_ENABLE_DEPRECATION_WARNINGS > + } else > +#endif > + if (av_channel_layout_copy(&out_ch_layout, &out->ch_layout) < 0) > + goto fail; > + if (av_opt_set_chlayout(s, "ochl", &out_ch_layout, 0) < 0) > goto fail; > if (av_opt_set_int(s, "osf", out->format, 0) < 0) > goto fail; > @@ -58,7 +82,19 @@ static int config_changed(SwrContext *s, > int ret = 0; > > if (in) { > - if (s->in_ch_layout != in->channel_layout || > + AVChannelLayout in_ch_layout = { 0 }; > +#if FF_API_OLD_CHANNEL_LAYOUT > +FF_DISABLE_DEPRECATION_WARNINGS > + // if the old/new fields are set inconsistently, prefer the old ones > + if ((in->channel_layout && (in->ch_layout.order != > AV_CHANNEL_ORDER_NATIVE || > + in->ch_layout.u.mask != > in->channel_layout))) { > + av_channel_layout_from_mask(&in_ch_layout, in->channel_layout); > +FF_ENABLE_DEPRECATION_WARNINGS > + } else > +#endif > + if ((ret = av_channel_layout_copy(&in_ch_layout, &in->ch_layout)) < > 0) > + return ret; > + if (av_channel_layout_compare(&s->in_ch_layout, &in_ch_layout) || > s->in_sample_rate != in->sample_rate || > s->in_sample_fmt != in->format) { > ret |= AVERROR_INPUT_CHANGED; > @@ -66,7 +102,19 @@ static int config_changed(SwrContext *s, > } > > if (out) { > - if (s->out_ch_layout != out->channel_layout || > + AVChannelLayout out_ch_layout = { 0 }; > +#if FF_API_OLD_CHANNEL_LAYOUT > +FF_DISABLE_DEPRECATION_WARNINGS > + // if the old/new fields are set inconsistently, prefer the old ones > + if ((out->channel_layout && (out->ch_layout.order != > AV_CHANNEL_ORDER_NATIVE || > + out->ch_layout.u.mask != > out->channel_layout))) { > + av_channel_layout_from_mask(&out_ch_layout, out->channel_layout); > +FF_ENABLE_DEPRECATION_WARNINGS > + } else > +#endif > + if ((ret = av_channel_layout_copy(&out_ch_layout, &out->ch_layout)) > < 0) > + return ret; > + if (av_channel_layout_compare(&s->out_ch_layout, &out_ch_layout) || > s->out_sample_rate != out->sample_rate || > s->out_sample_fmt != out->format) { > ret |= AVERROR_OUTPUT_CHANGED; > @@ -116,7 +164,14 @@ static inline int available_samples(AVFrame *out) > if (av_sample_fmt_is_planar(out->format)) { > return samples; > } else { > - int channels = > av_get_channel_layout_nb_channels(out->channel_layout); > + int channels; > +#if FF_API_OLD_CHANNEL_LAYOUT > +FF_DISABLE_DEPRECATION_WARNINGS > + channels = av_get_channel_layout_nb_channels(out->channel_layout); > +FF_ENABLE_DEPRECATION_WARNINGS > + if (!channels) > +#endif > + channels = out->ch_layout.nb_channels; > return samples / channels; > } > } > diff --git a/libswresample/swresample_internal.h > b/libswresample/swresample_internal.h > index f2ea5a226d..262a0e2b8c 100644 > --- a/libswresample/swresample_internal.h > +++ b/libswresample/swresample_internal.h > @@ -99,8 +99,8 @@ struct SwrContext { > enum AVSampleFormat in_sample_fmt; ///< input sample format > enum AVSampleFormat int_sample_fmt; ///< internal sample > format (AV_SAMPLE_FMT_FLTP or AV_SAMPLE_FMT_S16P) > enum AVSampleFormat out_sample_fmt; ///< output sample format > - int64_t in_ch_layout; ///< input channel layout > - int64_t out_ch_layout; ///< output channel > layout > + AVChannelLayout in_ch_layout; ///< input channel layout > + AVChannelLayout out_ch_layout; ///< output channel > layout > int in_sample_rate; ///< input sample rate > int out_sample_rate; ///< output sample rate > int flags; ///< miscellaneous flags > such as SWR_FLAG_RESAMPLE > @@ -114,11 +114,15 @@ struct SwrContext { > int used_ch_count; ///< number of used > input channels (mapped channel count if channel_map, otherwise in.ch_count) > int engine; > > + int user_used_ch_count; ///< User set used > channel count > +#if FF_API_OLD_CHANNEL_LAYOUT > int user_in_ch_count; ///< User set input > channel count > int user_out_ch_count; ///< User set output > channel count > - int user_used_ch_count; ///< User set used > channel count > int64_t user_in_ch_layout; ///< User set input > channel layout > int64_t user_out_ch_layout; ///< User set output > channel layout > +#endif > + AVChannelLayout user_in_chlayout; ///< User set input > channel layout > + AVChannelLayout user_out_chlayout; ///< User set output > channel layout > enum AVSampleFormat user_int_sample_fmt; ///< User set internal > sample format > int user_dither_method; ///< User set dither > method > > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".