[FFmpeg-devel] [PATCH] lavd/pulse_audio_enc: add buffer length control options

Lukasz Marek lukasz.m.luki at gmail.com
Sat Nov 23 15:30:01 CET 2013


Add options to control the length of the PulseAudio buffer.

Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
---
 doc/outdevs.texi              |    8 ++++++++
 libavdevice/pulse_audio_enc.c |   21 +++++++++++++++++++++
 libavdevice/version.h         |    2 +-
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/doc/outdevs.texi b/doc/outdevs.texi
index c737225..0e7309e 100644
--- a/doc/outdevs.texi
+++ b/doc/outdevs.texi
@@ -164,6 +164,14 @@ 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}.
 
+ at item buffer_length
+ at item buffer_duration
+Controls the length of the PulseAudio buffer. Small buffer gives more control,
+but requires more frequent updates.
+buffer_length specifies length in bytes while buffer_duration specifies length in miliseconds.
+When both options are provided then higher value is used.
+By default PulseAudio set buffer length to around 2 seconds.
+
 @end table
 
 @subsection Examples
diff --git a/libavdevice/pulse_audio_enc.c b/libavdevice/pulse_audio_enc.c
index a2abc4a..0115862 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;
+    unsigned buffer_length;
+    unsigned buffer_duration;
 } PulseData;
 
 static av_cold int pulse_write_header(AVFormatContext *h)
@@ -59,6 +61,23 @@ 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_length, av_clip64_c(bytes, 0, 0xFFFFFFFE));
+        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_length) {
+        attr.tlength = s->buffer_length;
+        if (s->buffer_duration)
+            av_log(s, AV_LOG_WARNING, "buffer_duration parameter is ignored.\n");
+    }
+
     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 +161,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_length",   "set buffer length in bytes", OFFSET(buffer_length),   AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0xFFFFFFFE, E },
+    { "buffer_duration", "set buffer length in msecs", OFFSET(buffer_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E },
     { NULL }
 };
 
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 4f4ec99..8e3ff7f 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 100
+#define LIBAVDEVICE_VERSION_MICRO 101
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
                                                LIBAVDEVICE_VERSION_MINOR, \
-- 
1.7.10.4



More information about the ffmpeg-devel mailing list