From 3aaa50a9972c9f350ad9ce6decf3ecb2aaffa84a Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Sun, 24 Nov 2013 02:35:33 +0100 Subject: [PATCH] lavd/pulse_audio_enc: add buffer size control options Add options to control the size of the PulseAudio buffer. Signed-off-by: Lukasz Marek Signed-off-by: Stefano Sabatini --- doc/outdevs.texi | 13 +++++++++++++ libavdevice/pulse_audio_enc.c | 17 +++++++++++++++++ libavdevice/version.h | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/doc/outdevs.texi b/doc/outdevs.texi index 6c8422cca4..f18982300b 100644 --- a/doc/outdevs.texi +++ b/doc/outdevs.texi @@ -164,6 +164,19 @@ by default it is set to the specified output name. Specify the device to use. Default device is used when not provided. List of output devices can be obtained with command @command{pactl list sinks}. +@item buffer_size +@item buffer_duration +Control the size and duration of the PulseAudio buffer. A small buffer +gives more control, but requires more frequent updates. + +@option{buffer_size} specifies size in bytes while +@option{buffer_duration} specifies duration in milliseconds. + +When both options are provided then the highest value is used +(duration is recalculated to bytes using stream parameters). If they +are set to 0 (which is default), the device will use the default +PulseAudio duration value. By default PulseAudio set buffer duration +to around 2 seconds. @end table @subsection Examples diff --git a/libavdevice/pulse_audio_enc.c b/libavdevice/pulse_audio_enc.c index a2abc4aea5..e047299391 100644 --- a/libavdevice/pulse_audio_enc.c +++ b/libavdevice/pulse_audio_enc.c @@ -35,6 +35,8 @@ typedef struct PulseData { const char *device; pa_simple *pa; int64_t timestamp; + int buffer_size; + int buffer_duration; } PulseData; static av_cold int pulse_write_header(AVFormatContext *h) @@ -59,6 +61,19 @@ static av_cold int pulse_write_header(AVFormatContext *h) stream_name = "Playback"; } + if (s->buffer_duration) { + int64_t bytes = s->buffer_duration; + bytes *= st->codec->channels * st->codec->sample_rate * + av_get_bytes_per_sample(st->codec->sample_fmt); + bytes /= 1000; + attr.tlength = FFMAX(s->buffer_size, av_clip64(bytes, 0, UINT32_MAX - 1)); + av_log(s, AV_LOG_DEBUG, + "Buffer duration: %ums recalculated into %"PRId64" bytes buffer.\n", + s->buffer_duration, bytes); + av_log(s, AV_LOG_DEBUG, "Real buffer length is %u bytes\n", attr.tlength); + } else if (s->buffer_size) + attr.tlength = s->buffer_size; + ss.format = ff_codec_id_to_pulse_format(st->codec->codec_id); ss.rate = st->codec->sample_rate; ss.channels = st->codec->channels; @@ -142,6 +157,8 @@ static const AVOption options[] = { { "name", "set application name", OFFSET(name), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, E }, { "stream_name", "set stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, { "device", "set device name", OFFSET(device), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, + { "buffer_size", "set buffer size in bytes", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, + { "buffer_duration", "set buffer duration in millisecs", OFFSET(buffer_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, { NULL } }; diff --git a/libavdevice/version.h b/libavdevice/version.h index 8e3ff7f2ca..0bbd48e7a5 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -29,7 +29,7 @@ #define LIBAVDEVICE_VERSION_MAJOR 55 #define LIBAVDEVICE_VERSION_MINOR 5 -#define LIBAVDEVICE_VERSION_MICRO 101 +#define LIBAVDEVICE_VERSION_MICRO 102 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \