PR #23096 opened by toots URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23096 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23096.patch
>From 404407b54fe59f8cf5f395c4eecbde3063082d5d Mon Sep 17 00:00:00 2001 From: Romain Beauxis <[email protected]> Date: Wed, 13 May 2026 08:18:49 -0400 Subject: [PATCH] avdevice/alsa: auto-detect channel layout when none is requested --- libavdevice/alsa.c | 22 +++++++++++++++++++--- libavdevice/alsa.h | 5 +++-- libavdevice/alsa_dec.c | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/libavdevice/alsa.c b/libavdevice/alsa.c index 966eea519a..ac790013db 100644 --- a/libavdevice/alsa.c +++ b/libavdevice/alsa.c @@ -173,7 +173,7 @@ static av_cold int find_reorder_func(AlsaData *s, int codec_id, av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, unsigned int *sample_rate, - const AVChannelLayout *layout, enum AVCodecID *codec_id) + AVChannelLayout *layout, enum AVCodecID *codec_id) { AlsaData *s = ctx->priv_data; const char *audio_device; @@ -193,8 +193,6 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, av_log(ctx, AV_LOG_ERROR, "sample format 0x%04x is not supported\n", *codec_id); return AVERROR(ENOSYS); } - s->frame_size = av_get_bits_per_sample(*codec_id) / 8 * layout->nb_channels; - if (ctx->flags & AVFMT_FLAG_NONBLOCK) { flags = SND_PCM_NONBLOCK; } @@ -240,6 +238,22 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, goto fail; } + if (layout->nb_channels == 0) { + unsigned int channels = 2; + if (snd_pcm_hw_params_test_channels(h, hw_params, channels) < 0) { + res = snd_pcm_hw_params_get_channels_min(hw_params, &channels); + if (res < 0) { + av_log(ctx, AV_LOG_ERROR, "cannot get minimum channel count (%s)\n", + snd_strerror(res)); + goto fail; + } + av_log(ctx, AV_LOG_VERBOSE, + "stereo not supported, falling back to %u channel(s)\n", channels); + } + av_channel_layout_uninit(layout); + av_channel_layout_default(layout, channels); + } + res = snd_pcm_hw_params_set_channels(h, hw_params, layout->nb_channels); if (res < 0) { av_log(ctx, AV_LOG_ERROR, "cannot set channel count to %d (%s)\n", @@ -247,6 +261,8 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, goto fail; } + s->frame_size = av_get_bits_per_sample(*codec_id) / 8 * layout->nb_channels; + snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size); buffer_size = FFMIN(buffer_size, ALSA_BUFFER_SIZE_MAX); /* TODO: maybe use ctx->max_picture_buffer somehow */ diff --git a/libavdevice/alsa.h b/libavdevice/alsa.h index d3dfa478c5..ed2ac66e93 100644 --- a/libavdevice/alsa.h +++ b/libavdevice/alsa.h @@ -72,7 +72,8 @@ typedef struct AlsaData { * @param mode either SND_PCM_STREAM_CAPTURE or SND_PCM_STREAM_PLAYBACK * @param sample_rate in: requested sample rate; * out: actually selected sample rate - * @param layout channel layout + * @param layout in: requested channel layout, or nb_channels=0 for auto-detect; + * out: actually selected channel layout * @param codec_id in: requested AVCodecID or AV_CODEC_ID_NONE; * out: actually selected AVCodecID, changed only if * AV_CODEC_ID_NONE was requested @@ -82,7 +83,7 @@ typedef struct AlsaData { av_warn_unused_result int ff_alsa_open(AVFormatContext *s, snd_pcm_stream_t mode, unsigned int *sample_rate, - const AVChannelLayout *layout, enum AVCodecID *codec_id); + AVChannelLayout *layout, enum AVCodecID *codec_id); /** * Close the ALSA PCM. diff --git a/libavdevice/alsa_dec.c b/libavdevice/alsa_dec.c index 63409a7785..54d9b3a783 100644 --- a/libavdevice/alsa_dec.c +++ b/libavdevice/alsa_dec.c @@ -160,7 +160,7 @@ static const AVOption options[] = { #if FF_API_ALSA_CHANNELS { "channels", "", offsetof(AlsaData, channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_DEPRECATED }, #endif - { "ch_layout", "", offsetof(AlsaData, ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = "2C"}, INT_MIN, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, + { "ch_layout", "", offsetof(AlsaData, ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, INT_MIN, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, { NULL }, }; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
