I'm trying to test module-match but so far the only result is making the daemon assert. #0 0x00007fa2ff30f475 in raise () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007fa2ff3126f0 in abort () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00007fa3005960fe in pa_cvolume_set (a=a@entry=0x7fff7544ce50, channels=<optimized out>, v=<optimized out>) at pulse/volume.c:77 #3 0x00007fa2ee574727 in sink_input_new_hook_callback (c=<optimized out>, si=0x7fff7544d5f0, u=<optimized out>) at modules/module-match.c:236 #4 0x00007fa300a38d5c in pa_hook_fire (hook=hook@entry=0xf764b8, data=data@entry=0x7fff7544d5f0) at pulsecore/hook-list.c:106 #5 0x00007fa300a51783 in pa_sink_input_new (_i=_i@entry=0x7fff7544d478, core=0xf76130, data=data@entry=0x7fff7544d5f0) at pulsecore/sink-input.c:273 #6 0x00007fa2f68d27d8 in playback_stream_new (ret=<synthetic pointer>, missing=<synthetic pointer>, syncid=2, relative_volume=false, early_requests=false, adjust_latency=true, p=0xf972a0, flags=PA_SINK_INPUT_START_CORKED, muted_set=false, muted=false, volume=0x0, a=0x7fff7544d490, formats=0x0, map=0x7fff7544d4d0, ss=0x7fff7544d480, sink=0x0, c=0x10ab610) at pulsecore/protocol-native.c:1147 #7 command_create_playback_stream (pd=<optimized out>, command=<optimized out>, tag=<optimized out>, t=<optimized out>, userdata=0x10ab610) at pulsecore/protocol-native.c:2134 #8 0x00007fa3007dd8fd in pa_pdispatch_run (pd=0xf8e1d0, packet=<optimized out>, creds=0xf9bf40, userdata=userdata@entry=0x10ab610) at pulsecore/pdispatch.c:336 #9 0x00007fa2f68d31e0 in pstream_packet_callback (p=0xf9bdf0, packet=<optimized out>, creds=<optimized out>, userdata=0x10ab610) at pulsecore/protocol-native.c:4747 #10 0x00007fa3007e192b in do_read (p=0xf9bdf0) at pulsecore/pstream.c:812 #11 do_something (p=0xf9bdf0) at pulsecore/pstream.c:180 #12 0x00007fa300585654 in dispatch_pollfds (m=0xf75d50) at pulse/mainloop.c:677 #13 pa_mainloop_dispatch (m=m@entry=0xf75d50) at pulse/mainloop.c:927 #14 0x00007fa300585a05 in pa_mainloop_iterate (m=m@entry=0xf75d50, block=block@entry=1, retval=retval@entry=0x7fff7544db14) at pulse/mainloop.c:958 #15 0x00007fa300585ab0 in pa_mainloop_run (m=m@entry=0xf75d50, retval=retval@entry=0x7fff7544db14) at pulse/mainloop.c:973 #16 0x000000000040732f in main (argc=<optimized out>, argv=<optimized out>) at daemon/main.c:1135 From a quick look in gdb, it seems that module-match.c:sink_input_new_hook_callback() calls pa_cvolume_set() with channels=0. This happens with e.g. this match.table line: .* 0
Oh, this is on pulseaudio 2.0 (wouldn't have just filed this but I thought I was running latest release...)
Had some debugging help... It looks like gstreamer does something weird and pulseaudio decides to assert because of that. If I use paplay everything works, but gstreamer using apps will assert PA with module-match. Here's a pa_sink_input_new_data* in pa_sink_input_new() -- notice how the sample_spec is just empty, e.g. sample_spec.channels = 0: Breakpoint 1, pa_sink_input_new (_i=_i@entry=0x7fffb2fd4508, core=0x21ea130, data=data@entry=0x7fffb2fd4680) at pulsecore/sink-input.c:239 239 pulsecore/sink-input.c: No such file or directory. (gdb) print *data $1 = {flags = PA_SINK_INPUT_START_CORKED, proplist = 0x2208780, driver = 0x7f681ee55920 "pulsecore/protocol-native.c", module = 0x2272550, client = 0x2204350, sink = 0x0, origin_sink = 0x0, resample_method = PA_RESAMPLER_INVALID, sync_base = 0x0, sample_spec = {format = PA_SAMPLE_U8, rate = 0, channels = 0 '\000'}, channel_map = {channels = 0 '\000', map = { PA_CHANNEL_POSITION_MONO <repeats 32 times>}}, format = 0x0, req_formats = 0x2200e80, nego_formats = 0x0, volume = {channels = 0 '\000', values = {0 <repeats 32 times>}}, volume_factor = {channels = 0 '\000', values = { 0 <repeats 32 times>}}, volume_factor_sink = {channels = 0 '\000', values = {0 <repeats 32 times>}}, muted = false, sample_spec_is_set = false, channel_map_is_set = false, volume_is_set = false, volume_factor_is_set = false, volume_factor_sink_is_set = false, muted_is_set = false, volume_is_absolute = false, volume_writable = true, save_sink = false, save_volume = false, save_muted = false} I don't think PA should assert when this happens.
I couldn't reproduce this, but the information posted so far is enough to find the error. module-match uses the SINK_INPUT_NEW hook, and then relies on the sample spec being properly initialized. This is clearly wrong: if the sink input uses the FIX_CHANNELS flag, the number of channels will be unknown until the sink input has been routed to some sink. In your case the FIX_CHANNELS flag is not being used. I'm not sure if there's some other bug involved in your case (I wouldn't be surprised), but fixing module-match should make things work for you. If the fix doesn't turn out to be hard to do, I'll post a patch soon.
Created attachment 67767 [details] [review] Fix candidate Does this patch fix the problem for you?
(In reply to comment #4) > Created attachment 67767 [details] [review] [review] > Fix candidate > > Does this patch fix the problem for you? It does. No asserts and seems to work as expected. Thanks.
Although I did not test at the same time with stream-restore... Is this bound to break the functionality refered in this comment: /* hook EARLY - 1, to match before stream-restore */ (I'm not familiar with the internals so maybe that makes no sense)
This patch actually makes the comment correct :) I think earlier module-stream-restore used the NEW hook too, and the comment was written at that time. Then module-stream-restore was changed to use the FIXATE hook, possibly to fix a bug similar to this, so the comment became outdated. Now the comment is relevant again, because the two modules use the same hook.
Fix applied in master: http://cgit.freedesktop.org/pulseaudio/pulseaudio/commit/?id=0a8634f03e64a84f594bc8533235998e969eda66
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.