31 #include <alsa/asoundlib.h>
61 default:
return SND_PCM_FORMAT_UNKNOWN;
65 #define REORDER_OUT_50(NAME, TYPE) \
66 static void alsa_reorder_ ## NAME ## _out_50(const void *in_v, void *out_v, int n) \
68 const TYPE *in = in_v; \
82 #define REORDER_OUT_51(NAME, TYPE) \
83 static void alsa_reorder_ ## NAME ## _out_51(const void *in_v, void *out_v, int n) \
85 const TYPE *in = in_v; \
100 #define REORDER_OUT_71(NAME, TYPE) \
101 static void alsa_reorder_ ## NAME ## _out_71(const void *in_v, void *out_v, int n) \
103 const TYPE *in = in_v; \
138 #define PICK_REORDER(layout)\
140 case FORMAT_I8: s->reorder_func = alsa_reorder_int8_out_ ##layout; break;\
141 case FORMAT_I16: s->reorder_func = alsa_reorder_int16_out_ ##layout; break;\
142 case FORMAT_I32: s->reorder_func = alsa_reorder_int32_out_ ##layout; break;\
143 case FORMAT_F32: s->reorder_func = alsa_reorder_f32_out_ ##layout; break;\
173 default:
return AVERROR(ENOSYS);
191 const char *audio_device;
193 snd_pcm_format_t format;
195 snd_pcm_hw_params_t *hw_params;
196 snd_pcm_uframes_t buffer_size, period_size;
199 if (ctx->
filename[0] == 0) audio_device =
"default";
205 if (format == SND_PCM_FORMAT_UNKNOWN) {
212 flags = SND_PCM_NONBLOCK;
214 res = snd_pcm_open(&h, audio_device, mode, flags);
217 audio_device, snd_strerror(res));
221 res = snd_pcm_hw_params_malloc(&hw_params);
228 res = snd_pcm_hw_params_any(h, hw_params);
235 res = snd_pcm_hw_params_set_access(h, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
242 res = snd_pcm_hw_params_set_format(h, hw_params, format);
245 *codec_id, format, snd_strerror(res));
249 res = snd_pcm_hw_params_set_rate_near(h, hw_params, sample_rate, 0);
256 res = snd_pcm_hw_params_set_channels(h, hw_params, channels);
259 channels, snd_strerror(res));
263 snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size);
266 res = snd_pcm_hw_params_set_buffer_size_near(h, hw_params, &buffer_size);
273 snd_pcm_hw_params_get_period_size_min(hw_params, &period_size,
NULL);
275 period_size = buffer_size / 4;
276 res = snd_pcm_hw_params_set_period_size_near(h, hw_params, &period_size,
NULL);
284 res = snd_pcm_hw_params(h, hw_params);
291 snd_pcm_hw_params_free(hw_params);
293 if (channels > 2 && layout) {
294 if (
find_reorder_func(s, *codec_id, layout, mode == SND_PCM_STREAM_PLAYBACK) < 0) {
298 name, mode == SND_PCM_STREAM_PLAYBACK ?
"playback" :
"capture");
312 snd_pcm_hw_params_free(hw_params);
323 if (CONFIG_ALSA_INDEV)
332 snd_pcm_t *handle = s->
h;
336 err = snd_pcm_prepare(handle);
338 av_log(s1,
AV_LOG_ERROR,
"cannot recover from underrun (snd_pcm_prepare failed: %s)\n", snd_strerror(err));
342 }
else if (err == -ESTRPIPE) {
356 while (size < min_size)