On Sat, 18 Oct 2014 20:36:22 +0200 Lukasz Marek <lukasz.m.lu...@gmail.com> wrote:
> --- > libavdevice/alsa-audio-common.c | 60 > +++++++++++++++++++++++++++++++++++++++++ > libavdevice/alsa-audio-dec.c | 6 +++++ > libavdevice/alsa-audio-enc.c | 6 +++++ > libavdevice/alsa-audio.h | 2 ++ > 4 files changed, 74 insertions(+) > > diff --git a/libavdevice/alsa-audio-common.c b/libavdevice/alsa-audio-common.c > index 4e63397..1061917 100644 > --- a/libavdevice/alsa-audio-common.c > +++ b/libavdevice/alsa-audio-common.c > @@ -343,3 +343,63 @@ int ff_alsa_extend_reorder_buf(AlsaData *s, int min_size) > s->reorder_buf_size = size; > return 0; > } > + > +/* ported from alsa-utils/aplay.c */ > +int ff_alsa_get_device_list(AVDeviceInfoList *device_list, snd_pcm_stream_t > stream_type) > +{ > + int ret; > + void **hints, **n; > + char *name = NULL, *descr = NULL, *io = NULL, *tmp; > + AVDeviceInfo *new_device = NULL; > + const char *filter = stream_type == SND_PCM_STREAM_PLAYBACK ? "Output" : > "Input"; > + > + av_log(NULL, AV_LOG_INFO, "%s\n", filter); > + > + if (snd_device_name_hint(-1, "pcm", &hints) < 0) > + return AVERROR_EXTERNAL; > + n = hints; > + while (*n) { > + name = snd_device_name_get_hint(*n, "NAME"); > + descr = snd_device_name_get_hint(*n, "DESC"); > + io = snd_device_name_get_hint(*n, "IOID"); > + if (!io || !strcmp(io, filter)) { > + new_device = av_mallocz(sizeof(AVDeviceInfo)); > + if (!new_device) { > + ret = AVERROR(ENOMEM); > + goto fail; > + } > + new_device->device_name = name; > + name = NULL; > + if ((tmp = strrchr(descr, '\n')) && tmp[1]) { > + new_device->device_description = av_strdup(&tmp[1]); > + if (!new_device->device_description) { > + ret = AVERROR(ENOMEM); > + goto fail; > + } > + } else { > + new_device->device_description = descr; > + descr = NULL; > + } > + if ((ret = av_dynarray_add_nofree(&device_list->devices, > + &device_list->nb_devices, > new_device)) < 0) { > + goto fail; > + } > + new_device = NULL; > + } > + av_freep(&io); > + av_freep(&name); > + av_freep(&descr); > + n++; > + } > + fail: > + av_free(io); > + av_free(name); > + av_free(descr); > + if (new_device) { > + av_free(new_device->device_description); > + av_free(new_device->device_name); > + av_free(new_device); > + } > + snd_device_name_free_hint(hints); > + return ret; > +} > diff --git a/libavdevice/alsa-audio-dec.c b/libavdevice/alsa-audio-dec.c > index 2cdf356..7f8f8cd 100644 > --- a/libavdevice/alsa-audio-dec.c > +++ b/libavdevice/alsa-audio-dec.c > @@ -132,6 +132,11 @@ static int audio_read_packet(AVFormatContext *s1, > AVPacket *pkt) > return 0; > } This will list all pseudo-devices. I concluded that this doesn't really work. The device name also controls the channel layout, and listing the device "hints" includes those multichannel pseudo-devies (e.g "surround51:CARD=Intel,DEV=0"). But shouldn't you select the device name based on the input audio channel layout you get? There are other reasons to change the device name, e.g. adding the "plug" converter plugin. So I'm not sure what would be the best. Maybe enumerate raw devices only? > +static int audio_get_device_list(AVFormatContext *h, AVDeviceInfoList > *device_list) > +{ > + return ff_alsa_get_device_list(device_list, SND_PCM_STREAM_CAPTURE); > +} > + > static const AVOption options[] = { > { "sample_rate", "", offsetof(AlsaData, sample_rate), AV_OPT_TYPE_INT, > {.i64 = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, > { "channels", "", offsetof(AlsaData, channels), AV_OPT_TYPE_INT, > {.i64 = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, > @@ -153,6 +158,7 @@ AVInputFormat ff_alsa_demuxer = { > .read_header = audio_read_header, > .read_packet = audio_read_packet, > .read_close = ff_alsa_close, > + .get_device_list = audio_get_device_list, > .flags = AVFMT_NOFILE, > .priv_class = &alsa_demuxer_class, > }; > diff --git a/libavdevice/alsa-audio-enc.c b/libavdevice/alsa-audio-enc.c > index e42cc8f..43d097d 100644 > --- a/libavdevice/alsa-audio-enc.c > +++ b/libavdevice/alsa-audio-enc.c > @@ -142,6 +142,11 @@ audio_get_output_timestamp(AVFormatContext *s1, int > stream, > *dts = s->timestamp - delay; > } > > +static int audio_get_device_list(AVFormatContext *h, AVDeviceInfoList > *device_list) > +{ > + return ff_alsa_get_device_list(device_list, SND_PCM_STREAM_PLAYBACK); > +} > + > static const AVClass alsa_muxer_class = { > .class_name = "ALSA muxer", > .item_name = av_default_item_name, > @@ -159,6 +164,7 @@ AVOutputFormat ff_alsa_muxer = { > .write_packet = audio_write_packet, > .write_trailer = ff_alsa_close, > .write_uncoded_frame = audio_write_frame, > + .get_device_list = audio_get_device_list, > .get_output_timestamp = audio_get_output_timestamp, > .flags = AVFMT_NOFILE, > .priv_class = &alsa_muxer_class, > diff --git a/libavdevice/alsa-audio.h b/libavdevice/alsa-audio.h > index 583c911..cf0e942 100644 > --- a/libavdevice/alsa-audio.h > +++ b/libavdevice/alsa-audio.h > @@ -99,4 +99,6 @@ int ff_alsa_xrun_recover(AVFormatContext *s1, int err); > > int ff_alsa_extend_reorder_buf(AlsaData *s, int size); > > +int ff_alsa_get_device_list(AVDeviceInfoList *device_list, snd_pcm_stream_t > stream_type); > + > #endif /* AVDEVICE_ALSA_AUDIO_H */ _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel