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);
187 unsigned int *sample_rate,
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);
330 snd_pcm_t *handle = s->
h;
334 err = snd_pcm_prepare(handle);
336 av_log(s1,
AV_LOG_ERROR,
"cannot recover from underrun (snd_pcm_prepare failed: %s)\n", snd_strerror(err));
340 }
else if (err == -ESTRPIPE) {
354 while (size < min_size)
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
#define AV_CH_LAYOUT_7POINT1
#define AV_LOG_WARNING
Something somehow does not look correct.
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_dlog(ac->avr, "%d samples - audio_convert: %s to %s (dithered)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
#define AV_CH_LAYOUT_5POINT0
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
#define av_assert0(cond)
assert() equivalent, that is always enabled.
AVStream ** streams
A list of all streams in the file.
av_cold int ff_alsa_close(AVFormatContext *s1)
Close the ALSA PCM.
int flags
Flags modifying the (de)muxer behaviour.
int ff_alsa_extend_reorder_buf(AlsaData *s, int min_size)
#define AV_CH_LAYOUT_5POINT1
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.
simple assert() macros that are a bit more flexible than ISO C assert().
#define AV_CH_LAYOUT_QUAD
void av_log(void *avcl, int level, const char *fmt,...)
uint64_t channel_layout
Audio channel layout.
AVCodecContext * codec
Codec context associated with this stream.
void(* reorder_func)(const void *, void *, int)
audio channel layout utility functions
char filename[1024]
input or output filename
static av_cold int find_reorder_func(AlsaData *s, int codec_id, uint64_t layout, int out)
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.
#define AV_CH_LAYOUT_5POINT1_BACK
#define AV_CH_LAYOUT_5POINT0_BACK
int ff_alsa_xrun_recover(AVFormatContext *s1, int err)
Try to recover from ALSA buffer underrun.
#define PICK_REORDER(layout)
int period_size
bytes per sample * channels
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
#define ALSA_BUFFER_SIZE_MAX
void * priv_data
Format private data.
#define REORDER_OUT_71(NAME, TYPE)
int frame_size
preferred size for reads and writes
ALSA input and output: definitions and structures.
static av_cold snd_pcm_format_t codec_id_to_pcm_format(int codec_id)
#define REORDER_OUT_51(NAME, TYPE)
int reorder_buf_size
in frames
#define REORDER_OUT_50(NAME, TYPE)
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.