[FFmpeg-cvslog] swresample/swresample: add a used channel layout option using the new API

James Almer git at videolan.org
Sun Feb 19 23:30:32 EET 2023


ffmpeg | branch: release/6.0 | James Almer <jamrial at gmail.com> | Fri Feb 17 15:41:56 2023 -0300| [a34b348328dd33d122ea772fc9f516e6aaef193e] | committer: James Almer

swresample/swresample: add a used channel layout option using the new API

Replaces the "used channel count" option, which is now deprecated.

Signed-off-by: James Almer <jamrial at gmail.com>
(cherry picked from commit 223c70cf1d8b816b59dede36a21492d7e8542e06)

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a34b348328dd33d122ea772fc9f516e6aaef193e
---

 doc/resampler.texi                  |  4 +--
 libswresample/options.c             |  6 ++--
 libswresample/rematrix.c            |  2 +-
 libswresample/swresample.c          | 56 +++++++++++++++++++++++--------------
 libswresample/swresample_internal.h |  5 ++--
 libswresample/x86/rematrix_init.c   |  2 +-
 6 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/doc/resampler.texi b/doc/resampler.texi
index d55654e7bc..a6224eefb3 100644
--- a/doc/resampler.texi
+++ b/doc/resampler.texi
@@ -11,8 +11,8 @@ programmatic use.
 
 @table @option
 
- at item uch, used_channel_count
-Set the number of used input channels. Default value is 0. This option is
+ at item uchl, used_chlayout
+Set used input channel layout. Default is unset. This option is
 only used for special remapping.
 
 @item isr, in_sample_rate
diff --git a/libswresample/options.c b/libswresample/options.c
index ffa27c590d..fb109fdbab 100644
--- a/libswresample/options.c
+++ b/libswresample/options.c
@@ -46,9 +46,9 @@ static const AVOption options[]={
                                                           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},
+{"uch"                  , "set used channel count"      , OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0                    }, 0      , SWR_CH_MAX, PARAM|DEPREC},
+{"used_channel_count"   , "set used channel count"      , OFFSET(user_used_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},
 {"in_sample_rate"       , "set input sample rate"       , OFFSET( in_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
 {"osr"                  , "set output sample rate"      , OFFSET(out_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
@@ -73,6 +73,8 @@ static const AVOption options[]={
 {"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"},
+{"uchl"                 , "set used channel layout"     , OFFSET(user_used_chlayout), AV_OPT_TYPE_CHLAYOUT, {.str=NULL            }, 0, 0 , PARAM, "chlayout"},
+{"used_chlayout"        , "set used channel layout"     , OFFSET(user_used_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 0c3fff6c42..79e8a43eac 100644
--- a/libswresample/rematrix.c
+++ b/libswresample/rematrix.c
@@ -492,7 +492,7 @@ av_cold static int auto_matrix(SwrContext *s)
 
 av_cold int swri_rematrix_init(SwrContext *s){
     int i, j;
-    int nb_in  = s->used_ch_count;
+    int nb_in  = s->used_ch_layout.nb_channels;
     int nb_out = s->out.ch_count;
 
     s->mix_any_f = NULL;
diff --git a/libswresample/swresample.c b/libswresample/swresample.c
index 5884f8d533..6dc329a9d0 100644
--- a/libswresample/swresample.c
+++ b/libswresample/swresample.c
@@ -161,6 +161,7 @@ static void clear_context(SwrContext *s){
     free_temp(&s->dither.temp);
     av_channel_layout_uninit(&s->in_ch_layout);
     av_channel_layout_uninit(&s->out_ch_layout);
+    av_channel_layout_uninit(&s->used_ch_layout);
     swri_audio_convert_free(&s-> in_convert);
     swri_audio_convert_free(&s->out_convert);
     swri_audio_convert_free(&s->full_convert);
@@ -176,6 +177,7 @@ av_cold void swr_free(SwrContext **ss){
         clear_context(s);
         av_channel_layout_uninit(&s->user_in_chlayout);
         av_channel_layout_uninit(&s->user_out_chlayout);
+        av_channel_layout_uninit(&s->user_used_chlayout);
 
         if (s->resampler)
             s->resampler->free(&s->resample);
@@ -211,12 +213,20 @@ 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;
 
     // if the old/new fields are set inconsistently, prefer the old ones
+    if (s->user_used_ch_count && s->user_used_ch_count != s->user_used_chlayout.nb_channels) {
+        av_channel_layout_uninit(&s->used_ch_layout);
+        s->used_ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+        s->used_ch_layout.nb_channels = s->user_used_ch_count;
+    } else if (av_channel_layout_check(&s->user_used_chlayout)) {
+        ret = av_channel_layout_copy(&s->used_ch_layout, &s->user_used_chlayout);
+        if (ret < 0)
+            return ret;
+    }
     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))) {
@@ -243,9 +253,9 @@ av_cold int swr_init(struct SwrContext *s){
     } else if (av_channel_layout_check(&s->user_out_chlayout))
         av_channel_layout_copy(&s->out_ch_layout, &s->user_out_chlayout);
 
-    if (!s->out.ch_count && !s->user_out_ch_layout)
+    if (!s->out.ch_count)
         s->out.ch_count  = s->out_ch_layout.nb_channels;
-    if (!s-> in.ch_count && !s-> user_in_ch_layout)
+    if (!s-> in.ch_count)
         s-> in.ch_count  = s->in_ch_layout.nb_channels;
 
     if (!(ret = av_channel_layout_check(&s->in_ch_layout)) || s->in_ch_layout.nb_channels > SWR_CH_MAX) {
@@ -281,6 +291,7 @@ av_cold int swr_init(struct SwrContext *s){
 
     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);
+    ret |= av_channel_layout_copy(&s->used_ch_layout, &s->user_used_chlayout);
     if (ret < 0)
         return ret;
 #endif
@@ -299,16 +310,19 @@ av_cold int swr_init(struct SwrContext *s){
             return AVERROR(EINVAL);
     }
 
-    if(!s->used_ch_count)
-        s->used_ch_count= s->in.ch_count;
+    if (!av_channel_layout_check(&s->used_ch_layout))
+        av_channel_layout_default(&s->used_ch_layout, s->in.ch_count);
 
-    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");
+    if (s->used_ch_layout.nb_channels != s->in_ch_layout.nb_channels)
         av_channel_layout_uninit(&s->in_ch_layout);
-    }
 
-    if (s->in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
-        av_channel_layout_default(&s->in_ch_layout, s->used_ch_count);
+    if (s->used_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
+        av_channel_layout_default(&s->used_ch_layout, s->used_ch_layout.nb_channels);
+    if (s->in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+        ret = av_channel_layout_copy(&s->in_ch_layout, &s->used_ch_layout);
+        if (ret < 0)
+            return ret;
+    }
     if (s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
         av_channel_layout_default(&s->out_ch_layout, s->out.ch_count);
 
@@ -389,8 +403,8 @@ av_cold int swr_init(struct SwrContext *s){
 #define RSC 1 //FIXME finetune
     if(!s-> in.ch_count)
         s-> in.ch_count = s->in_ch_layout.nb_channels;
-    if(!s->used_ch_count)
-        s->used_ch_count= s->in.ch_count;
+    if (!av_channel_layout_check(&s->used_ch_layout))
+        av_channel_layout_default(&s->used_ch_layout, s->in.ch_count);
     if(!s->out.ch_count)
         s->out.ch_count = s->out_ch_layout.nb_channels;
 
@@ -410,23 +424,23 @@ av_cold int swr_init(struct SwrContext *s){
     }
 #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);
+    if (s->in_ch_layout.order != AV_CHANNEL_ORDER_UNSPEC && s->used_ch_layout.nb_channels != 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_layout.nb_channels);
         ret = AVERROR(EINVAL);
         goto fail;
     }
 
     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) {
+         || s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) && s->used_ch_layout.nb_channels != 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);
         goto fail;
     }
 
-av_assert0(s->used_ch_count);
+av_assert0(s->used_ch_layout.nb_channels);
 av_assert0(s->out.ch_count);
-    s->resample_first= RSC*s->out.ch_count/s->used_ch_count - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
+    s->resample_first= RSC*s->out.ch_count/s->used_ch_layout.nb_channels - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
 
     s->in_buffer= s->in;
     s->silence  = s->in;
@@ -442,7 +456,7 @@ av_assert0(s->out.ch_count);
     }
 
     s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt,
-                                             s-> in_sample_fmt, s->used_ch_count, s->channel_map, 0);
+                                             s-> in_sample_fmt, s->used_ch_layout.nb_channels, s->channel_map, 0);
     s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
                                              s->int_sample_fmt, s->out.ch_count, NULL, 0);
 
@@ -457,9 +471,9 @@ av_assert0(s->out.ch_count);
 
     if(s->channel_map){
         s->postin.ch_count=
-        s->midbuf.ch_count= s->used_ch_count;
+        s->midbuf.ch_count= s->used_ch_layout.nb_channels;
         if(s->resample)
-            s->in_buffer.ch_count= s->used_ch_count;
+            s->in_buffer.ch_count= s->used_ch_layout.nb_channels;
     }
     if(!s->resample_first){
         s->midbuf.ch_count= s->out.ch_count;
@@ -697,7 +711,7 @@ static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_co
     if((ret=swri_realloc_audio(&s->postin, in_count))<0)
         return ret;
     if(s->resample_first){
-        av_assert0(s->midbuf.ch_count == s->used_ch_count);
+        av_assert0(s->midbuf.ch_count == s->used_ch_layout.nb_channels);
         if((ret=swri_realloc_audio(&s->midbuf, out_count))<0)
             return ret;
     }else{
diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h
index 262a0e2b8c..ad902d73fa 100644
--- a/libswresample/swresample_internal.h
+++ b/libswresample/swresample_internal.h
@@ -99,6 +99,7 @@ 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
+    AVChannelLayout used_ch_layout;                 ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count)
     AVChannelLayout  in_ch_layout;                  ///< input channel layout
     AVChannelLayout out_ch_layout;                  ///< output channel layout
     int      in_sample_rate;                        ///< input sample rate
@@ -111,16 +112,16 @@ struct SwrContext {
     float rematrix_maxval;                          ///< maximum value for rematrixing output
     int matrix_encoding;                            /**< matrixed stereo encoding */
     const int *channel_map;                         ///< channel index (or -1 if muted channel) map
-    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_used_ch_count;                         ///< User set used channel count
     int user_in_ch_count;                           ///< User set input channel count
     int user_out_ch_count;                          ///< User set output 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_used_chlayout;             ///< User set used channel layout
     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
diff --git a/libswresample/x86/rematrix_init.c b/libswresample/x86/rematrix_init.c
index b6ed38bf67..ce794eef90 100644
--- a/libswresample/x86/rematrix_init.c
+++ b/libswresample/x86/rematrix_init.c
@@ -33,7 +33,7 @@ D(int16, sse2)
 av_cold int swri_rematrix_init_x86(struct SwrContext *s){
 #if HAVE_X86ASM
     int mm_flags = av_get_cpu_flags();
-    int nb_in  = s->used_ch_count;
+    int nb_in  = s->used_ch_layout.nb_channels;
     int nb_out = s->out.ch_count;
     int num    = nb_in * nb_out;
     int i,j;



More information about the ffmpeg-cvslog mailing list