[pulseaudio-discuss] [PATCH] pulse: Fix hole handling in pa_stream_peek().
Tanu Kaskinen
tanuk at iki.fi
Wed Nov 7 06:46:51 PST 2012
On Wed, 2012-11-07 at 14:21 +0100, David Henningsson wrote:
> On 11/07/2012 09:36 AM, Tanu Kaskinen wrote:
> > Previously, if there was a hole in a recording stream,
> > pa_stream_peek() would crash. Holes could be handled silently inside
> > pa_stream_peek() by generating silence (wouldn't work for compressed
> > streams, though) or by skipping any holes. However, I think it's
> > better to let the caller decide how the holes should be handled, so
> > in case of holes, pa_stream_peek() will return NULL data pointer and
> > the length of the hole in the nbytes argument.
> >
> > This change is technically an interface break, because previously the
> > documentation didn't mention the possibility of holes that need
> > special handling. However, since holes caused crashing anyway in the
> > past, it's not a regression if applications keep misbehaving due to
> > not handing holes properly.
> >
> > When adapting pacat to this change, a dependency to sample-util was
> > added, and that required moving some code from libpulsecore to
> > libpulsecommon.
>
> It was a little confusing to see both things in one. Maybe split the
> patch in one to add what's necessary to improve pa_stream_peek, and one
> to deal with the utils?
Yes, that's definitely better.
> Btw, exactly what did you need from sample-util? Maybe it's smarter to
> move that particular thing to pulse/something.h rather than moving
> sample-util to libpulsecommon?
I need pa_silence_memory(). It might be a useful utility function for
clients also, so moving it to libpulse might make sense. On the other
hand, pa_silence_memblock() and pa_silence_memchunk() are sort of
related, so it makes sense to have them in the same place as
pa_silence_memory(), and they don't belong in the public API... I won't
do changes for now. If you have a good concrete plan about what to move
and where, I can definitely consider it, but I don't see moving stuff
from libpulsecore to libpulsecommon as a very significant issue, so I
don't want to spend too much time thinking about it.
> > @@ -257,24 +258,36 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {
> > return;
> > }
> >
> > - pa_assert(data);
> > pa_assert(length > 0);
> >
> > - if (buffer) {
> > - buffer = pa_xrealloc(buffer, buffer_length + length);
> > - memcpy((uint8_t*) buffer + buffer_length, data, length);
> > - buffer_length += length;
> > - } else {
> > - buffer = pa_xmalloc(length);
> > - memcpy(buffer, data, length);
> > - buffer_length = length;
> > - buffer_index = 0;
> > + /* If there is a hole in the stream, we generate silence, except
> > + * if it's a passthrough stream in which case we skip the hole. */
> > + if (data || !(flags & PA_STREAM_PASSTHROUGH)) {
>
> It looks like this can be more elegantly rewritten as
>
> if (!buffer)
> buffer_length = 0;
> as reallocs can take null pointers.
>
> > + if (buffer) {
> > + buffer = pa_xrealloc(buffer, buffer_length + length);
> > + if (data)
> > + memcpy((uint8_t *) buffer + buffer_length, data, length);
> > + else
> > + pa_silence_memory((uint8_t *) buffer + buffer_length, length, &sample_spec);
> > + buffer_length += length;
> > + } else {
>
> ...and then the entire section handling this case can be removed.
Very good suggestion. I didn't know/remember the exact realloc behavior.
--
Tanu
More information about the pulseaudio-discuss
mailing list