lavd/pulse_audio_enc: add buffer size control options

Add options to control the size of the PulseAudio buffer.

Signed-off-by: Lukasz Marek <lukasz.m.luki@gmail.com>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
This commit is contained in:
Lukasz Marek 2013-11-24 02:35:33 +01:00 committed by Stefano Sabatini
parent a12b4bd107
commit 3aaa50a997
3 changed files with 31 additions and 1 deletions

View File

@ -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. 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}. 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 @end table
@subsection Examples @subsection Examples

View File

@ -35,6 +35,8 @@ typedef struct PulseData {
const char *device; const char *device;
pa_simple *pa; pa_simple *pa;
int64_t timestamp; int64_t timestamp;
int buffer_size;
int buffer_duration;
} PulseData; } PulseData;
static av_cold int pulse_write_header(AVFormatContext *h) 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"; 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.format = ff_codec_id_to_pulse_format(st->codec->codec_id);
ss.rate = st->codec->sample_rate; ss.rate = st->codec->sample_rate;
ss.channels = st->codec->channels; 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 }, { "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 }, { "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 }, { "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 } { NULL }
}; };

View File

@ -29,7 +29,7 @@
#define LIBAVDEVICE_VERSION_MAJOR 55 #define LIBAVDEVICE_VERSION_MAJOR 55
#define LIBAVDEVICE_VERSION_MINOR 5 #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, \ #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \ LIBAVDEVICE_VERSION_MINOR, \