Browse code

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>

Lukasz Marek authored on 2013/11/24 10:35:33
Showing 3 changed files
... ...
@@ -164,6 +164,19 @@ by default it is set to the specified output name.
164 164
 Specify the device to use. Default device is used when not provided.
165 165
 List of output devices can be obtained with command @command{pactl list sinks}.
166 166
 
167
+@item buffer_size
168
+@item buffer_duration
169
+Control the size and duration of the PulseAudio buffer. A small buffer
170
+gives more control, but requires more frequent updates.
171
+
172
+@option{buffer_size} specifies size in bytes while
173
+@option{buffer_duration} specifies duration in milliseconds.
174
+
175
+When both options are provided then the highest value is used
176
+(duration is recalculated to bytes using stream parameters). If they
177
+are set to 0 (which is default), the device will use the default
178
+PulseAudio duration value. By default PulseAudio set buffer duration
179
+to around 2 seconds.
167 180
 @end table
168 181
 
169 182
 @subsection Examples
... ...
@@ -35,6 +35,8 @@ typedef struct PulseData {
35 35
     const char *device;
36 36
     pa_simple *pa;
37 37
     int64_t timestamp;
38
+    int buffer_size;
39
+    int buffer_duration;
38 40
 } PulseData;
39 41
 
40 42
 static av_cold int pulse_write_header(AVFormatContext *h)
... ...
@@ -59,6 +61,19 @@ static av_cold int pulse_write_header(AVFormatContext *h)
59 59
             stream_name = "Playback";
60 60
     }
61 61
 
62
+    if (s->buffer_duration) {
63
+        int64_t bytes = s->buffer_duration;
64
+        bytes *= st->codec->channels * st->codec->sample_rate *
65
+                 av_get_bytes_per_sample(st->codec->sample_fmt);
66
+        bytes /= 1000;
67
+        attr.tlength = FFMAX(s->buffer_size, av_clip64(bytes, 0, UINT32_MAX - 1));
68
+        av_log(s, AV_LOG_DEBUG,
69
+               "Buffer duration: %ums recalculated into %"PRId64" bytes buffer.\n",
70
+               s->buffer_duration, bytes);
71
+        av_log(s, AV_LOG_DEBUG, "Real buffer length is %u bytes\n", attr.tlength);
72
+    } else if (s->buffer_size)
73
+        attr.tlength = s->buffer_size;
74
+
62 75
     ss.format = ff_codec_id_to_pulse_format(st->codec->codec_id);
63 76
     ss.rate = st->codec->sample_rate;
64 77
     ss.channels = st->codec->channels;
... ...
@@ -142,6 +157,8 @@ static const AVOption options[] = {
142 142
     { "name",          "set application name",   OFFSET(name),        AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT},  0, 0, E },
143 143
     { "stream_name",   "set stream description", OFFSET(stream_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
144 144
     { "device",        "set device name",        OFFSET(device),      AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
145
+    { "buffer_size",   "set buffer size in bytes", OFFSET(buffer_size), AV_OPT_TYPE_INT,  {.i64 = 0}, 0, INT_MAX, E },
146
+    { "buffer_duration", "set buffer duration in millisecs", OFFSET(buffer_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
145 147
     { NULL }
146 148
 };
147 149
 
... ...
@@ -29,7 +29,7 @@
29 29
 
30 30
 #define LIBAVDEVICE_VERSION_MAJOR  55
31 31
 #define LIBAVDEVICE_VERSION_MINOR   5
32
-#define LIBAVDEVICE_VERSION_MICRO 101
32
+#define LIBAVDEVICE_VERSION_MICRO 102
33 33
 
34 34
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
35 35
                                                LIBAVDEVICE_VERSION_MINOR, \