Age | Commit message (Collapse) | Author | Files | Lines |
|
It's possible that the memblockq of a sink input is rewound to a negative read
index if the sink input is moved between sinks shortly after its creation. When
this happens, pa_memblockq_peek() returns a memchunk whose 'memblock' field is
NULL and whose 'length' field indicates the length of the gap caused by the
negative read index. This will trigger an assert in play-memblockq.c.
If the memblockq had a silence memchunk, pa_memblockq_peek() would return
silence for the duration of the gap and the assert would be avoided. However,
this approach would prevent the sink input from being drained and is thus not
possible. Instead, we handle the aforementioned situation by dropping the gap
indicated by the 'length' field of the memchunk and by peeking the actual data
that comes after the gap.
This scenario seems to be quite rare in everyday use, but it causes a severe
bug in the handheld world. The assert can be triggered e.g. by loading two null
sinks, playing a sample from the cache to one of them and then moving the
created sink input between the two sinks. The rewinds done by the null sinks
seem to be quite long (I don't know if this is normal behaviour or something
fishy in module-null-sink).
See also:
6bd34156b130c07b130de10111a12ef6dab18b52
virtual-sink: Fix a crash when moving the sink to a new master right after setup.
https://tango.0pointer.de/pipermail/pulseaudio-discuss/2011-February/009105.html
Reproduce:
This problem can be reproduced with the following script:
SAMPLE_PATH="/usr/share/sounds/alsa/"
SAMPLE="Front_Left"
pactl remove-sample $SAMPLE 2> /dev/null
pactl upload-sample $SAMPLE_PATH$SAMPLE.wav
mod1=`pactl load-module module-null-sink sink_name=null1`
mod2=`pactl load-module module-null-sink sink_name=null2`
pactl play-sample $SAMPLE null1
input=`pactl list | grep "Sink Input #" | tail -n 1 | cut -d# -f2`
echo "Sample $SAMPLE playing as Sink Input #$input"
pactl move-sink-input $input null2
pactl move-sink-input $input null1
pactl unload-module $mod1
pactl unload-module $mod2
|
|
setup.
If the virtual sink is moved to a new master right after it has been created,
then the virtual sink input's memblockq can be rewound to a negative read
index. The data written prior to the move starts from index zero, so after the
rewind there's a bit of silence. If the memblockq doesn't have a silence
memchunk set, then pa_memblockq_peek() will return zero in such case, and the
returned memchunk's memblock pointer will be NULL.
That scenario wasn't taken into account in the implementation of
sink_input_pop_cb. Setting a silence memchunk for the memblockq solves this
problem, because pa_memblock_peek() will now return a valid memblock if the
read index happens to point to a hole in the memblockq.
I believe this isn't the best possible solution, though. It doesn't really make
sense to rewind the sink input's memblockq beyond index 0 in the first place,
because now when the stream starts to play to the new master sink, there's some
unnecessary silence before the actual data starts. This is a small problem,
though, and I don't grok the rewinding system well enough to know how to fix
this issue properly.
I went through all files that call pa_memblockq_peek() to see if there are more
similar bugs. play-memblockq.c was the only one that looked to me like it might
be broken in the same way. I didn't try reproducing the bug with
play-memblockq.c, though, so I just added a FIXME comment there.
|
|
when the sink is suspended
libcanberra already sets the appropriate flags for uncached sample
streams, we now need to make sure to set them for cached samples too.
|
|
hooks can access it
|
|
Instead of using string contents for type identification use the address
of a constant string array. This should speed up type verifications a
little sind we only need to compare one machine word instead of a full
string. Also, this saves a few strings.
To make clear that types must be compared via address and not string
contents 'type_name' is now called 'type_id'.
This also simplifies the macros for declaring and defining public and
private subclasses.
|
|
|
|
internally and automatically by the sink input
|
|
|
|
field to sinks/sources
|
|
|
|
|
|
|
|
resampler might run for too long and we get a heavy delay/underrun
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2490 fefdeb5f-60dc-0310-8127-8f9354f1896f
|
|
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2445 fefdeb5f-60dc-0310-8127-8f9354f1896f
|
|
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1971 fefdeb5f-60dc-0310-8127-8f9354f1896f
|
|
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1426 fefdeb5f-60dc-0310-8127-8f9354f1896f
|
|
mmmkay?
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1418 fefdeb5f-60dc-0310-8127-8f9354f1896f
|
|
this I modified the pa_sink_input_new() signature to take a pa_sink_input_new_data structure instead of direct arguments.
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1237 fefdeb5f-60dc-0310-8127-8f9354f1896f
|
|
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1167 fefdeb5f-60dc-0310-8127-8f9354f1896f
|
|
data from the memblockq to it. after that is done, frees the memblockq
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1161 fefdeb5f-60dc-0310-8127-8f9354f1896f
|