On Fri Nov 22 14:55:40 2024 +0000, Conor McCarthy wrote:
I confirmed that native hangs if `MESourceStarted` is not sent and events are halted as we'd expect for a shutdown source. I tested this by wrapping the native media source in a custom one, which also required wrapping streams returned by `MENewStream` so their `GetMediaSource()` returns the wrapper. The wrapper intercepts `MESourceStarted` and blocks forwarding. I also tested reusing the session after a source is forcibly shutdown. This requires calling `ClearTopologies()`. Clearing the current topology is not enough. I have this working in Wine; I need to make sure the details are correct or reasonably close to it for review.
While event queues will invoke the callback after shutdown, this occurs for media sources only within a narrow window. Probably it enqueues `MESourceStarted`, but shutdown occurs before `EndGetEvent()` is called in the callback function. This is not sufficient to prevent the session hanging. I tested a media session with a wrapped media source which calls `Shutdown()` on the native source object immediately after the `Start()` call has been forwarded to it, and this causes a session hang in Windows. The only explanation I have for the game not hanging in Windows is either Windows has a workaround which only applies when `Shutdown()` is called from a different thread (unlikely), or it uses a private interface to receive shutdown notifications. In Windows the session queries from the source an interface `{0b5e1c7e-bd76-46bc-896c-b2edb40dd803}` which is not documented anywhere. Forwarding this `QueryInterface()` call to the native source doesn't prevent the hang, but wrapping could stil l prevent notification from working.
I see no way to prevent a hang without adding a private interface for shutdown notification. It will be much simpler than wrapping the media source in order to intercept the call to `Shutdown()`.