On 1/19/2022 2:20 PM, Andreas Rheinhardt wrote:
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().
Will change.
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_DEPRECATEDstatic 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 initializedreturn 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_LAYOUTav_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 ac3if(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.
More like the entire file. But ok, will fix the whitespace on the lines i change.
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.
Nice catch. Will fix.
And why don't you implement the old API in terms of the new API?
I'm not sure I understand what you mean.
+ 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; +#endifs->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 finetuneif(!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.
Just a missing "to". Will add.
Moreover, it does not document that an already allocated context will be freed here on error.
Will mention it.
+ * @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.
Will fix.
+ * @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".
_______________________________________________ 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".