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

Stefano Sabatini stefasab at gmail.com
Sun Nov 24 21:31:39 CET 2013


On date Sunday 2013-11-24 02:35:33 +0100, Lukasz Marek encoded:
> Add options to control the length of the PulseAudio buffer.
> 
> Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
> ---
>  doc/outdevs.texi              |    9 +++++++++
>  libavdevice/pulse_audio_enc.c |   17 +++++++++++++++++
>  libavdevice/version.h         |    2 +-
>  3 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/outdevs.texi b/doc/outdevs.texi
> index c737225..1255d30 100644
> --- a/doc/outdevs.texi
> +++ b/doc/outdevs.texi
> @@ -164,6 +164,15 @@ 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
> +Control the length and duration of the PulseAudio buffer. A small buffer
> +gives more control, but requires more frequent updates.

> +buffer_length specifies length in bytes while buffer_duration specifies length in milliseconds.

@option{buffer_length} ... @option{buffer_duration} ...

> +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 a2abc4a..192a046 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,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_length, av_clip64(bytes, 0, 0xFFFFFFFE));

0xFFFFFFFE -> UINT32_MAX-1 ?

why -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_length)
> +        attr.tlength = s->buffer_length;
> +
>      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_length",   "set buffer length in bytes", OFFSET(buffer_length),   AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0xFFFFFFFE, E },

nit++: buffer_size if probably more clear, since "length" is usually
associated to a string length.

Also 0xFFFFFFFE should be replaced by a symbolic constants for better
readability. Also probably if you want to store an uint32_t you should
probably use TYPE_INT64.

> +    { "buffer_duration", "set buffer length in msecs", OFFSET(buffer_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E },

could overflow in case value > INT_MAX (in general with TYPE_INT you
should use max <= INT_MAX).
-- 
FFmpeg = Fostering Fascinating MultiPurpose Ecletic Generator


More information about the ffmpeg-devel mailing list