mumble-voip / mumble

Mumble is an open-source, low-latency, high quality voice chat software.
https://www.mumble.info
Other
6.44k stars 1.12k forks source link

Mumble is frozen for 10 seconds at startup when ODAC is connected #3224

Open Ingramz opened 7 years ago

Ingramz commented 7 years ago

This is a continuation of #1977

I was pleasantly surprised that after trying snapshot releases of Mumble, it does not freeze rest of Windows anymore during startup, however during that time Mumble is still unresponsive.

After a couple of hours setting up the build environment and then debug-printing, I found that the root cause was the following line: https://github.com/mumble-voip/mumble/blob/13bad232fac54c8134ed3223683ccd00e0adce48/src/mumble/GlobalShortcut_win.cpp#L617

Debug log entries show that there is a 10 second delay between enumerating ODAC and the device before it, which possibly means that the enumeration internally times out.

Quick Google search with ODAC and EnumDevices points to a discussion at Stack Overflow confirming my findings. Only that the timeout discussed there is 5 seconds, it's possible that newer Windows drivers have increased this delay.

My suggestion would be that this enumeration should be done asynchronously instead so that it wouldn't block rest of the application, if possible. I haven't tested whether forcing the devices to re-enumerate causes any sort of lag/delay mid-use yet, but I will try to do this once I can effectively trigger it.

As to attempting to blacklist ODAC and similar devices by ID, it's probably useless code as far as #1977 is concerned - that piece of code does not have any effect on the enumeration itself. 10-15 second delay mentioned in #1880 seems to be the same kind of issue.

Right now it seems like the best way to avoid all of this is by disabling the HID device associated with the DAC from Device Manager. Unfortunately I cannot tell if the SaviAudio SA9023 chip in ODAC uses this interface in any meaningful manner, but assuming it is unused input controls for volume control, it could/should be disabled by users to avoid any other issues with HID drivers. I'll try sniffing the USB communcation and/or asking SaviTech directly what kind of parameters they send over HID to decide whether it's a bad idea. Also probably worth mentioning them that it's an issue possibly caused by out of spec behavior, but that's not going to fix any existing chips and it's possible they are aware of it and being quiet about it as usual.


In case someone wonders why do USB DAC-s have HID devices, then this is quite normal practice in the embedded circuits industry. The chipmakers add this capability so device manufacturers can add a software-controlled volume control for devices such as USB headsets, here is a picture of a classic C-Media CM108 based USB sound card, which contains such functionality triggered via buttons. HID is sometimes also used to send back information to the chip from computer, for instance to modify parameters stored on the device or drive GPIO pins (could be used for toggling indicator LED-s).

Ingramz commented 7 years ago

I've been simulating the freezes using Sleep(5000); after EnumDevices and it's been very successful. At startup the delay only affects the UI of Mumble, but during use it will block the mouse movement as it does with 1.2.19 at startup. Hopefully this makes it easier to replicate the behavior without having to own a dysfunctional HID device. To trigger, any hardware change can be used, eg plugging/unplugging a device.

Ingramz commented 7 years ago

It looks like the issue comes from SA9023 and similar not responding to a descriptor request and the driver simply times out. It asks for string at index 2.

sa9023

Here is CM108's HID device for comparison, responding immediately. cm108

I wonder why Mumble triggers the enumeration twice, causing the mentioned 10 second delay (5s each).

As can be seen from CM108's image, there are "Usage" entries for Volume Increment, Volume Decrement and Mute and Undefined. The last one is for capturing microphone mute button, but it's not officially recognized by USB spec, but can be captured by any software capable of reading HID reports. This is how and why it works. SA9023's equivalent report descriptor has a list of Undefined usages, meaning it's vendor-only behavior, which can be safely disabled if not using any software supplied by SaviAudio.

savi_descriptor


Update: It seems like with enough persistence it's possible to even query the strings, however it's not extremely useful in our case. Steam does seem to do this properly, so that the application keeps running and remains usable during that time. Note the 4.6 second delay, by third attempt this seems to get cached and is returned in 7.7 milliseconds. I lack the knowledge to increase the 5 second timeout delay, so it's not possible for me to see if we waited longer, whether the string would be returned, but there is nothing we can do about it anyway.

odac_steam

mkrautz commented 7 years ago

Thanks very much for the detailed analysis.

Sorry for letting this sit for a while before replying.

Right now, we run all GlobalShortcut-related things in the global shortcut thread. I'm not sure about the safety of running the device enumeration on another thread.

Perhaps we should move each GlobalShortcut provider to its own thread, and just do cross-thread communication for the events. Or at least move DirectInput to its own thread.

I recently implemented some changes in GlobalShorcut where we pass native Windows messages into GlobalShortcut from the main thread. If the DirectInput enumeration is running at this time, the main thread will block until the GlobalShortcut thread has time to process the incoming event. We can combat this by allowing users to disable DirectInput. Then, users who only use mouse+keyboards should be sufficiently served by native Windows messages.

I think a plan is to:

  1. Allow DirectInput to be disabled via "Additional shortcut engines" (easy)
  2. Try to move DirectInput to its own thread and communicate via events like InjectKeyboardMessageEvent. (not too bad, next step after 1)
amasondev commented 5 years ago

Seem to be affected by this issue with Corsair Void Pro RGB Wireless headset. Probably has HID for the adjustable rgb LEDs. Mumble unreliably freezes for a good 30 seconds on startup. When the headset is plugged in or disconnected from USB to charge, Mumble crashes