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

Lukasz Marek lukasz.m.luki2 at gmail.com
Tue Oct 21 22:54:25 CEST 2014


On 19.10.2014 16:27, wm4 wrote:
> On Sat, 18 Oct 2014 20:36:22 +0200
> Lukasz Marek <lukasz.m.luki2 at 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.

I don't understand you clearly here.

> So I'm not sure what would be the best. Maybe enumerate raw devices
> only?

Well, I have doubts about that too. I will change that when no other 
comments.


More information about the ffmpeg-devel mailing list