31 #include <alsa/asoundlib.h> 61 default:
return SND_PCM_FORMAT_UNKNOWN;
65 #define MAKE_REORDER_FUNC(NAME, TYPE, CHANNELS, LAYOUT, MAP) \ 66 static void alsa_reorder_ ## NAME ## _ ## LAYOUT(const void *in_v, \ 70 const TYPE *in = in_v; \ 80 #define MAKE_REORDER_FUNCS(CHANNELS, LAYOUT, MAP) \ 81 MAKE_REORDER_FUNC(int8, int8_t, CHANNELS, LAYOUT, MAP) \ 82 MAKE_REORDER_FUNC(int16, int16_t, CHANNELS, LAYOUT, MAP) \ 83 MAKE_REORDER_FUNC(int32, int32_t, CHANNELS, LAYOUT, MAP) \ 84 MAKE_REORDER_FUNC(f32, float, CHANNELS, LAYOUT, MAP) 154 default:
return AVERROR(ENOSYS);
172 const char *audio_device;
176 snd_pcm_hw_params_t *hw_params;
177 snd_pcm_uframes_t buffer_size, period_size;
180 if (ctx->
url[0] == 0) audio_device =
"default";
181 else audio_device = ctx->
url;
186 if (format == SND_PCM_FORMAT_UNKNOWN) {
193 flags = SND_PCM_NONBLOCK;
195 res = snd_pcm_open(&h, audio_device, mode, flags);
198 audio_device, snd_strerror(res));
202 res = snd_pcm_hw_params_malloc(&hw_params);
209 res = snd_pcm_hw_params_any(h, hw_params);
216 res = snd_pcm_hw_params_set_access(h, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
223 res = snd_pcm_hw_params_set_format(h, hw_params, format);
226 *codec_id, format, snd_strerror(res));
230 res = snd_pcm_hw_params_set_rate_near(h, hw_params, sample_rate, 0);
237 res = snd_pcm_hw_params_set_channels(h, hw_params, channels);
240 channels, snd_strerror(res));
244 snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size);
247 res = snd_pcm_hw_params_set_buffer_size_near(h, hw_params, &buffer_size);
254 snd_pcm_hw_params_get_period_size_min(hw_params, &period_size,
NULL);
256 period_size = buffer_size / 4;
257 res = snd_pcm_hw_params_set_period_size_near(h, hw_params, &period_size,
NULL);
265 res = snd_pcm_hw_params(h, hw_params);
272 snd_pcm_hw_params_free(hw_params);
274 if (channels > 2 && layout) {
275 if (find_reorder_func(s, *codec_id, layout, mode == SND_PCM_STREAM_PLAYBACK) < 0) {
279 name, mode == SND_PCM_STREAM_PLAYBACK ?
"playback" :
"capture");
293 snd_pcm_hw_params_free(hw_params);
303 if (snd_pcm_stream(s->
h) == SND_PCM_STREAM_PLAYBACK) {
304 snd_pcm_nonblock(s->
h, 0);
308 if (CONFIG_ALSA_INDEV)
317 snd_pcm_t *handle = s->
h;
321 err = snd_pcm_prepare(handle);
323 av_log(s1,
AV_LOG_ERROR,
"cannot recover from underrun (snd_pcm_prepare failed: %s)\n", snd_strerror(err));
327 }
else if (err == -ESTRPIPE) {
341 while (size < min_size)
358 const char *
filter = stream_type == SND_PCM_STREAM_PLAYBACK ?
"Output" :
"Input";
360 if (snd_device_name_hint(-1,
"pcm", &hints) < 0)
364 name = snd_device_name_get_hint(*n,
"NAME");
365 descr = snd_device_name_get_hint(*n,
"DESC");
366 io = snd_device_name_get_hint(*n,
"IOID");
367 if (!io || !strcmp(io, filter)) {
374 if ((tmp = strrchr(descr,
'\n')) && tmp[1])
401 snd_device_name_free_hint(hints);
Structure describes basic parameters of the device.
#define AV_CH_LAYOUT_7POINT1
void ff_timefilter_destroy(TimeFilter *self)
Free all resources associated with the filter.
char * device_description
human friendly name
#define AV_LOG_WARNING
Something somehow does not look correct.
char * device_name
device name, format depends on device
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample format(the sample packing is implied by the sample format) and sample rate.The lists are not just lists
#define AV_CH_LAYOUT_5POINT0
ALSA input and output: definitions and structures.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
AVStream ** streams
A list of all streams in the file.
int flags
Flags modifying the (de)muxer behaviour.
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)
int ff_alsa_extend_reorder_buf(AlsaData *s, int min_size)
uint64_t channel_layout
Audio only.
#define AV_CH_LAYOUT_5POINT1
Main libavdevice API header.
static av_cold snd_pcm_format_t codec_id_to_pcm_format(int codec_id)
AVCodecID
Identify the syntax and semantics of the bitstream.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
char * url
input or output URL.
simple assert() macros that are a bit more flexible than ISO C assert().
#define AV_CH_LAYOUT_QUAD
AVDeviceInfo ** devices
list of autodetected devices
#define MAKE_REORDER_FUNCS(CHANNELS, LAYOUT, MAP)
#define ALSA_BUFFER_SIZE_MAX
void(* reorder_func)(const void *, void *, int)
audio channel layout utility functions
#define AV_CH_LAYOUT_5POINT1_BACK
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.
char * av_strdup(const char *s)
Duplicate a string.
int ff_alsa_xrun_recover(AVFormatContext *s1, int err)
Try to recover from ALSA buffer underrun.
av_cold int ff_alsa_close(AVFormatContext *s1)
Close the ALSA PCM.
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
int ff_alsa_get_device_list(AVDeviceInfoList *device_list, snd_pcm_stream_t stream_type)
#define AV_CH_LAYOUT_5POINT0_BACK
int default_device
index of default device or -1 if no default
#define PICK_REORDER(layout)
#define flags(name, subs,...)
int period_size
preferred size for reads and writes, in frames
void * priv_data
Format private data.
int frame_size
bytes per sample * channels
AVCodecParameters * codecpar
Codec parameters associated with this stream.
#define av_malloc_array(a, b)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
int nb_devices
number of autodetected devices
#define AVERROR_EXTERNAL
Generic error in an external library.
int reorder_buf_size
in frames
mode
Use these values in ebur128_init (or'ed).
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, unsigned int *sample_rate, int channels, enum AVCodecID *codec_id)
Open an ALSA PCM.