xbmc / xbmc

Kodi is an award-winning free and open source home theater/media center software and entertainment hub for digital media. With its beautiful interface and powerful skinning engine, it's available for Android, BSD, Linux, macOS, iOS, tvOS and Windows.
https://kodi.tv/
Other
18.53k stars 6.3k forks source link

linux audio - "Kodi-Tester", causes launch issues, when trying to detect or initialize audio backends #21509

Open dreamcat4 opened 2 years ago

dreamcat4 commented 2 years ago

Bug report

Describe the bug

Here is a clear and concise description of what the problem is:

When kodi launches on a linux host (with pipewire and pipewire-pulse audio server), the following situation will occur:

And one of 2 situations will occur

Situation 1)

Situation 2)

Expected Behavior

Here is a clear and concise description of what was expected to happen:

To Reproduce

Steps to reproduce the behavior:

To visually see this Kodi-Tester node, I am using the GUI graphical program qpwgraph. Which is installable via flathub.

You also need to disable the feature in pipewire known as node.autoconnect, which defaults to true and then will auto-connect the Kodi-Tester device to the default alsa soundcard. So that also is another reason why under a default pipewire settings, this bug may not be noticed.

However the node.autoconnect setting itself is a pretty bad setting for other reasons (as it globally affects all other client applications within pipewire, and can be very disruptive). So that is not a reasonable or proper solution for these startup issues which are quite unique to kodi.

Debuglog

Sorry but ran out of time. (However a debug can always be provided later on if requested).

Screenshots

Out of time.

Additional context or screenshots (if appropriate)

Here is some additional context or explanation that might help:

How has this bug affected you? What were you trying to accomplish?

Your Environment

Used Operating system:

dreamcat4 commented 2 years ago

ok so...

this is the function in Kodi that is doing this:

https://github.com/xbmc/xbmc/blob/master/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp#L689-L719

and we can see in there that the kodi code itself does not seem to be setting any explicit timeout for this action. Instead it's calling:

pa_simple_new(NULL, "Kodi-Tester", PA_STREAM_PLAYBACK, NULL, "Test", &ss, NULL, NULL, NULL)

where pa_simple_new() is a standard pulse audio library as is documented here:

https://freedesktop.org/software/pulseaudio/doxygen/simple.html

so presumably the timeout is happening elsewhere, it is probably the thread is blocking (of that simple syncronous api call) is waiting for a response. I have seen that before.

Anyhow. That whole function is being called from here:

https://github.com/xbmc/xbmc/blob/master/xbmc/platform/linux/OptionalsReg.cpp#L30-L64

Where we can see options are getting added or appended. The thing that strikes me here, is that on a system that has pipewire installed... *then pipewire-pulse is probably (almost definately) also installed and running too. At least on any sane modern distros. That isn't a broken installation of pipewire.

So given this, and that pipewire is not getting adopted (for sure) on most major distros. It might be nice for kodi to default to first of all checking for the existence of pipewire. Before then falling back to pulse audio. Since that way, (on a sane working typical modern mainstream linux system). Then if pipewire is not present, fall back to checking for pulse audio after that.

This would in effect be a simpler? Type of a fix to implement in the sense that it only requires re-arranging the loading order of these respective Options / Optionals. As a way to avoid changing that legacy pulseaudio tester / probing code, (which by using the simple pulse api is blocking, (and presumably might be rather more effort to fix more properly / more robustly).

However of course the drawback of doing this would be on legacy pulse audio linux systems. Where there still remains no pipewire. In however this situation it might not actually be as detrimental since (unlike the pulse simple api)... then maybe the pipewire api is not actually blocking? Then legacy pulse users might not encounter or incurr any extra startup delay? IDK but it's a possibility. Depending how sacrasant you consider this legacy startup probing order to be. But it sure is a bag of pain for me!

So maybe this leaves us still looking for other possible solutions or workarounds. So as not to be caught out waiting for the PA_STREAM_READY response on that blocking thread. And there are probably a whole variety of other possible options to choose from.

Please weigh in if you thing you have any better sorts of approach or suggestions. Many thanks

fritsch commented 2 years ago

pulseaudio sink was written when no pipewire existed and therefore no userspace pulseaudio-emulation happened. So - in short, you want that I workaround broken pipewire-pulse wrapper in the native pulse sink withing kodi?

Where I agree is, that setting a timeout vs. waiting forever make sense in most cases - this I can add - but I honestly don't want to workaround broken pipewire tunneling.

As you say: It's not a broken installation of pipwire. <- Yeah, most likely not - but that pipewire-pulse thing seems to act quite broken :-). If you look at the implementation of pa_simple_new in pulseaudio with a pulseaudio server - you can basically see, that there is no chance to block forever really.

fritsch commented 2 years ago

Checked the code once more: Sorry, please fix the root-cause - there is absolutely nothing wrong with this code. It opens a sample sink and when this succeeds it closes it and knows that pulseaudio is working ... I assume a race inside pipewire so that the mainloop callback does not come back.

See here how it should behave: https://github.com/pulseaudio/pulseaudio/blob/master/src/pulse/simple.c#L137

And something else: The issue you want to fix in kodi will hit every single pulseaudio native app on this planet which is using pa's simple sink ... so - I definitely don't start to workaround pipewire basics here, that should work on every setup when it is default sound server.

fritsch commented 2 years ago

Maybe: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1811 https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2319

Try to debug pipewire with exporting e.g. PIPEWIRE_LOG_SYSTEMD=false PIPEWIRE_DEBUG=5

then you can see if and where it hangs and the root-cause can be fixed.

dreamcat4 commented 2 years ago

thanks for the quick response and suggestions. and indeed those are some useful leads to follow up on.

in terms of debugging the code... that setting the PIPEWIRE_DEBUG=5 it prints such a huge amount of trace logging. That is a lot of unnecessary stuff to trawl through. My thinking is perhaps having both client app and pipewire server (or pipewire-pulse daemon) each in their own VSCode debugger. That might be a bit nicer debugging experience IMHO. So then can very easily step thru just the relevant sections of each respective code. Is often worth an extra effort to be setting that up (if i was a developer, but am not a developer here).

Maybe one day there will be a proper guide for doing all that in VSCode. They use ninja/meson build system.

Anyhow nevermind that ! Because since your helpful reply it gave me a very simple idea: just disable / or turn off the pulse audio for kodi only. Just been asking for this on the pipewire chat (element io / matrix / riot). Simple solution for that already exists. This is a very neat workaround just be setting the following env var to an empty string "":

PULSE_SERVER="" kodi-bin

This does indeed disable pipewire-pulse. Stops it from working. But only for the chosen program that has that in its environment. So any other pulse clients on the rest of the system are not affected by that change. And will continue to work with pipewire-pulse. Just for Kodi.

Already tested this workaround (just now). And OMG it works so well. There is no longer that long startup delays / thread blocking. Gone! And kodi then proceeds to continue AE backend detection (as it should). And then detect all of the other available types of audio backends that are running. So ALSA and JACK and Pipewire. They are all visible after loading up, can choose them in the settings options. Thank god.

SO situation 2) --> Now is solved. 1 out of 2 is success. That's 50%, some good news.

The people over on pipewire chat server are really helpful guys, and have made some very good points. They just want to help. As for me (personally) am simply glad to have the workaround solution for the time being.

For any other affected user: can potentially insert this empty env var setting PULSE_SERVER="" within the Kodi.desktop file. And should launch normally.

Of course the 'correct' solution still is necessary to investigate more properly the "Situation 1)" Which occurs after that code point we were discussing here today.

So that occurs when was returned success (and pipewire-pulse is not behaving exactly like the original pulse audio server, and then somehow kodi then gets messed up, cannot detect the other backends). For this case we also have an existing bug report over on pipewire project:

https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2268

Hope you are well, and again thanks for your insights here. It really did help me, to then better know what to look for / be asking for (to come to that specific workaround). Am so very grateful & have a good day.

dreamcat4 commented 2 years ago

How to modify the .desktop file:

# 1. copy the original .dekstop file to user folder (should become higher priority)
cp /usr/share/applications/kodi.desktop ~/.local/share/applications

2) then edit the .desktop file and replace this line:

Exec=kodi

with:

Exec=env PULSE_SERVER="" kodi

3) restart Kodi. (Was tested on ubuntu 22.04, it works for me)

fritsch commented 2 years ago

I am not so sure why you focus on workarounds?

PULSE_SERVER is exposed out of a very good reason on these pipewire setups. It is there to create backwards compatibility. The same is done for alsa and jack and others. Therefore this has to work or else you break the entire standard desktop that existed until last year.

And concerning Ubuntu 22.04 - pulseaudio works nicely there. Did you by chance play around with wireblumber? Routing everything through pulseaudio, but having pulseaudio removed? And that case I'd say: fix your installation.

wsnipex commented 2 years ago

does this help? https://github.com/xbmc/xbmc/pull/21443

fritsch commented 2 years ago

I don't think so, as he hangs in pulse method. Which ends up in the pipewire pulse wrapper.

That's the reason I insist of fixing the root cause as it is outside of Kodi.

dreamcat4 commented 2 years ago

to be a little clearer, in situation 2) which is what you are so obsessing over here...

that is where pipewire is delegating the setting up of the connection and out sourcing the establishment of the stream over to the media session manager. so it has to block and wait until the session manager (wireplumber) returns back a connected node

as soon as that happens. the pipewire pulse server immediately returns the call with the pa_stream_ready. that is an intential design decision of how to split up their tasks. the original pulse audio server never had any such session manager running in a seperate process. so it never had to worry about blocking this call

so the blocking or timeout waiting thin its not actually considered to be a bug in that sense when trying to establish a successful connection (in that situation). it is entirely necessary. it only becomes a drawback when (like me) i am a user who requires pipewire instead. so i never need (or ever want) kodi to be loading up pulse audio backends. so in this situation the workaround makes sense.

and it was never in the capabilities of the original pulse simple api to have non blocking calls. its not specified. that is why they have the async api. so there is not there such bug for kodi to worry for since it is not actually responsible itself for the blocking once it gives away so readily all of its control to another runtime. and at this point in the history of the program it would not be constructive to change that.

the real bug here remainin is for the situation 1). so you can forget situation 2) there is no bug there. and we already discussed mostly the reasons for that.

i only put here the workaround in the issue for situation 2) for completeness sake. so it could be a help other kodi users who are in that same situation of no longer needing or wanting to deal with those legacy pulse audio. which is only ever going to increase over time.

to get back on track....

fritsch commented 2 years ago

Hi, not sure what you want to proof or not. But you are technically entirely incorrect. Pulse-Audio is always a separate process and the clients (again own process) connect to it. How would multiple audio streams work else?

But as you said - your pipewire "blocking forever" seems to be a design choice and that's why kodi's pulse sink - as any other pulseaudio client, same as even paplay - has wait forever.

dreamcat4 commented 2 years ago

ok. so to try to put this bug in a better context:

the thing about situation 1) as a bug, is that it only seems to occur for pipewire users. who also have the pipewire-pulse running. as far as we know it does not affect pulse audio users.

so if this bug only occur for pipewire users, it is then always going to be possible on those systems to use the workaound to disable pulse. and since kodi now has native pipewire backend that will always be available for these users going forwards....

that is then what makes this situation 1), even if it is a real bug overall something lower priority. and becomes harder to justify the time to fix it. there are probably other higher priority open bugs (at this time). at least this is my view now. after considering what other bugs are more important (at least to me). for example perhaps other pipewire-puse users do not see this bug, if like you are saying my configuration is broken in some obscure ways

close as resolved, or close as not-resolved, or leave open for now (to expect to close later on if there is no more activity or progress). anything you feel appropriate i am happy whatever you guys decide

at things stand i will only return to this issue if i end up debugging kodi (in debugger) for some other higher priority bug. then it would be pretty easy to step thru it then as a bonus. but unless / until i am not actually setup to buiild kodi and fire up a debbugger ATM. (or until then), not much further for me to say / add.

please I thank you for your help, and comments. and good day

fritsch commented 2 years ago

Bug can stay open, but don't loose focus. Every single application on this planet using pulseaudio natively will be affected by this issue ... and hiding it in kodi won't help anyone.

fritsch commented 2 years ago

paplay /path/to/some.wav

fritsch commented 2 years ago

Did you hear back from the pipewire guys?

dreamcat4 commented 2 years ago

Yes, pipewire people did come through with some reasonable set of suggestions (thanks 'PinkFlames' on matrix chat, who was a great help). Just I got interrupted halfway through trying / testing those new suggested configurations.

But the 'jist of it' is:

However it only really should be set in the 1st, or 1st + 2nd (pipewire native, and possibly jack too). But not for the 3rd, pulse audio.

So there in pipewire-pulse.conf we can possibly change it but should not. And instead leave the default node.autoconnect = true. Then this will auto connect to 'whatever is set the default sink'. For any new connections coming from pulse clients using the simple API (which is synchronous interface).

Most the rest of the configuration details / issues, is about getting a dummy default sink to work properly. And without crashing or causing other issues. In pipewire land, that is one of several types of pipewire 'virtual devices'. Either sink, or duplex, and with various properties etc.

So clearly the virtual (or dummy / fake) device needs to itself work well enough when it is interacting with pulse audio clients. Not to cause other types of crashing or different set of issues (or bugs). And that testing I only got halfway with. So I shall be coming back to finish my own testing later on, once I am able to find the time, and with a clear head. And making sure there is no other types of bugs that will interfere with those testing. (because perhaps I am seeing some problem, but it could be due to other issues, which isn't related to pulse, so I want to try to solve those first, before returning back to this matter).

So yet in theory it should work with a virtual device. I just myself have not been able to quite at the moment. However perhaps other users will see this work well for themselves.

Further to this matter, I would also like to add that perhaps in the future, it might be cool if there was some extra way(s) to differentiate between pulse clients, so that we could have the auto connection feature be enabled (or disabled) for some specific pulse clients, and not for other pulse clients.

That type of a finer grained solution might also be cool to think about, but IDK how that would work, personally I have not considered that situation myself. Whether it's possible, or worthwhile or not. Since with a virtual device, it may not be needed. Just treat all pulse clients the same.

Hopefully that was enough clarifications for the time being. Since I cannot get back to pick that back up and continue testing. Just not just yet... but hope to eventually, since it is one of the specific needs for my own specific setup here, (not that should necessarily matter more widely for other users).

tiagogaspar8 commented 1 year ago

Hi all,

Is there any news about this issue?

diegoflyer commented 11 months ago

Hi all, I am also looking at a solution. Now Kodi swith automatically to alsa because pipewire is not recognized. Is there some actions on it?