31#include "config_components.h"
33#include <alsa/asoundlib.h>
64 default:
return SND_PCM_FORMAT_UNKNOWN;
68#define MAKE_REORDER_FUNC(NAME, TYPE, CHANNELS, LAYOUT, MAP) \
69static void alsa_reorder_ ## NAME ## _ ## LAYOUT(const void *in_v, \
73 const TYPE *in = in_v; \
83#define MAKE_REORDER_FUNCS(CHANNELS, LAYOUT, MAP) \
84 MAKE_REORDER_FUNC(int8, int8_t, CHANNELS, LAYOUT, MAP) \
85 MAKE_REORDER_FUNC(int16, int16_t, CHANNELS, LAYOUT, MAP) \
86 MAKE_REORDER_FUNC(int32, int32_t, CHANNELS, LAYOUT, MAP) \
87 MAKE_REORDER_FUNC(f32, float, CHANNELS, LAYOUT, MAP)
176 snd_pcm_chmap_t *chmap = snd_pcm_get_chmap(
h);
182 if (
layout->nb_channels != chmap->channels) {
193 for (
unsigned i = 0;
i < chmap->channels;
i++) {
195 SND_CHMAP_POSITION_MASK);
198 "unknown ALSA channel position %u.\n",
199 chmap->pos[
i] & SND_CHMAP_POSITION_MASK);
241 default:
return AVERROR(ENOSYS);
253 return s->reorder_func ? 0 :
AVERROR(ENOSYS);
257 unsigned int *sample_rate,
261 const char *audio_device;
265 snd_pcm_hw_params_t *hw_params;
266 snd_pcm_uframes_t buffer_size, period_size;
268 if (
ctx->url[0] == 0) audio_device =
"default";
269 else audio_device =
ctx->url;
274 if (
format == SND_PCM_FORMAT_UNKNOWN) {
279 flags = SND_PCM_NONBLOCK;
281 res = snd_pcm_open(&
h, audio_device,
mode,
flags);
284 audio_device, snd_strerror(res));
288 res = snd_pcm_hw_params_malloc(&hw_params);
295 res = snd_pcm_hw_params_any(
h, hw_params);
302 res = snd_pcm_hw_params_set_access(
h, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
309 res = snd_pcm_hw_params_set_format(
h, hw_params,
format);
316 res = snd_pcm_hw_params_set_rate_near(
h, hw_params, sample_rate, 0);
325 if (
mode == SND_PCM_STREAM_CAPTURE &&
layout->nb_channels == 0) {
327 if (snd_pcm_hw_params_test_channels(
h, hw_params,
channels) < 0) {
328 res = snd_pcm_hw_params_get_channels_min(hw_params, &
channels);
335 "stereo not supported, falling back to %u channel(s)\n",
channels);
341 res = snd_pcm_hw_params_set_channels(
h, hw_params,
layout->nb_channels);
344 layout->nb_channels, snd_strerror(res));
350 snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size);
353 res = snd_pcm_hw_params_set_buffer_size_near(
h, hw_params, &buffer_size);
360 snd_pcm_hw_params_get_period_size_min(hw_params, &period_size,
NULL);
362 period_size = buffer_size / 4;
363 res = snd_pcm_hw_params_set_period_size_near(
h, hw_params, &period_size,
NULL);
369 s->period_size = period_size;
371 res = snd_pcm_hw_params(
h, hw_params);
378 snd_pcm_hw_params_free(hw_params);
383 if (
mode == SND_PCM_STREAM_CAPTURE &&
397 name,
mode == SND_PCM_STREAM_PLAYBACK ?
"playback" :
"capture");
399 if (
s->reorder_func) {
400 s->reorder_buf_size = buffer_size;
415 snd_pcm_hw_params_free(hw_params);
425 if (snd_pcm_stream(
s->h) == SND_PCM_STREAM_PLAYBACK) {
426 snd_pcm_nonblock(
s->h, 0);
430 if (CONFIG_ALSA_INDEV)
440 snd_pcm_t *handle =
s->h;
444 err = snd_pcm_prepare(handle);
446 av_log(s1,
AV_LOG_ERROR,
"cannot recover from underrun (snd_pcm_prepare failed: %s)\n", snd_strerror(err));
451 }
else if (err == -ESTRPIPE) {
462 int size =
s->reorder_buf_size;
466 while (
size < min_size)
472 s->reorder_buf_size =
size;
483 const char *
filter = stream_type == SND_PCM_STREAM_PLAYBACK ?
"Output" :
"Input";
485 if (snd_device_name_hint(-1,
"pcm", &hints) < 0)
489 name = snd_device_name_get_hint(*n,
"NAME");
490 descr = snd_device_name_get_hint(*n,
"DESC");
491 io = snd_device_name_get_hint(*n,
"IOID");
492 if (!io || !strcmp(io,
filter)) {
501 else if ((
tmp = strrchr(descr,
'\n')) &&
tmp[1])
528 snd_device_name_free_hint(hints);
static const char *const format[]
int ff_alsa_xrun_recover(AVFormatContext *s1, int err)
Try to recover from ALSA buffer underrun.
av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, unsigned int *sample_rate, AVChannelLayout *layout, enum AVCodecID *codec_id)
Open an ALSA PCM.
#define MAKE_REORDER_FUNCS(CHANNELS, LAYOUT, MAP)
int ff_alsa_get_device_list(AVDeviceInfoList *device_list, snd_pcm_stream_t stream_type)
static av_cold int find_reorder_func(AlsaData *s, int codec_id, const AVChannelLayout *layout, int out)
#define PICK_REORDER(layout)
static enum AVChannel alsa_chmap_pos_to_av_chan(unsigned int pos)
int ff_alsa_extend_reorder_buf(AlsaData *s, int min_size)
static av_cold snd_pcm_format_t codec_id_to_pcm_format(int codec_id)
static int alsa_get_chmap(AVFormatContext *ctx, snd_pcm_t *h, AVChannelLayout *layout)
av_cold int ff_alsa_close(AVFormatContext *s1)
Close the ALSA PCM.
ALSA input and output: definitions and structures.
#define ALSA_BUFFER_SIZE_MAX
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Main libavdevice API header.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
Public libavutil channel layout APIs header.
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
AVCodecID
Identify the syntax and semantics of the bitstream.
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
#define AV_CHANNEL_LAYOUT_5POINT1_BACK
#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL
The specified retype target order is ignored and the simplest possible (canonical) order is used for ...
#define AV_CHANNEL_LAYOUT_5POINT0
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
#define AV_CHANNEL_LAYOUT_2_2
#define AV_CHANNEL_LAYOUT_5POINT0_BACK
#define AV_CHANNEL_LAYOUT_5POINT1
int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
#define AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_QUAD
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
@ AV_CHAN_UNUSED
Channel is empty can be safely skipped.
@ AV_CHAN_FRONT_RIGHT_OF_CENTER
@ AV_CHAN_TOP_FRONT_RIGHT
@ AV_CHAN_FRONT_LEFT_OF_CENTER
@ AV_CHAN_NONE
Invalid channel index.
@ AV_CHAN_LOW_FREQUENCY_2
@ AV_CHAN_TOP_BACK_CENTER
@ AV_CHAN_UNKNOWN
Channel contains data, but its position is unknown.
@ AV_CHAN_BOTTOM_FRONT_CENTER
@ AV_CHAN_BOTTOM_FRONT_RIGHT
@ AV_CHAN_BOTTOM_FRONT_LEFT
@ AV_CHAN_TOP_FRONT_CENTER
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Memory handling functions.
#define FF_ARRAY_ELEMS(a)
An AVChannelLayout holds information about the channel layout of audio data.
int nb_devices
number of autodetected devices
int default_device
index of default device or -1 if no default
AVDeviceInfo ** devices
list of autodetected devices
Structure describes basic parameters of the device.
char * device_description
human friendly name
char * device_name
device name, format depends on device
void * priv_data
Format private data.
#define av_malloc_array(a, b)
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
void ff_timefilter_destroy(TimeFilter *self)
Free all resources associated with the filter.