[FFmpeg-devel] [PATCH] lavd/alsa: implement get_device_list callbacks

Nicolas George george at nsup.org
Wed Oct 22 11:53:22 CEST 2014


Le septidi 27 vendémiaire, an CCXXIII, Lukasz Marek a écrit :
> ---
>  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);

Stray?

> +
> +    if (snd_device_name_hint(-1, "pcm", &hints) < 0)
> +        return AVERROR_EXTERNAL;
> +    n = hints;
> +    while (*n) {

Can hints be NULL here? If so, you need to init "ret = 0", otherwise you are
using it uninitialized at the end.


> +        name = snd_device_name_get_hint(*n, "NAME");
> +        descr = snd_device_name_get_hint(*n, "DESC");
> +        io = snd_device_name_get_hint(*n, "IOID");

I suspect you need to av_strdup() all these strings, as av_free() may not be
compatible with the plain free() needed for the strings returned by ALSA
(for example with CONFIG_MEMALIGN_HACK).

> +        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;
>  }
>  
> +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 */

The rest looks good to me, but I have not checked the actual output. If you
have a working test tree, can you show the output on a typical system?

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20141022/5715e28b/attachment.asc>


More information about the ffmpeg-devel mailing list