From 3dc661fe8e262014567c5850b9d71f49de3df79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Mon, 19 Jun 2023 19:43:12 +0200 Subject: [PATCH] ao_wasapi: remove infinite loop hack in AOCONTROL_UPDATE_STREAM_TITLE Instead of brute forcing the name until it is set, without any error checking and expecting it would start to work, fallback to client name if initial request fails. Fixes player going into infinite loop with very long title names. The API rejects unreasonably long names, which make sense. As for alleged "weird race condition in the IAudioSessionControl itself" I cannot comment. It works on my end and even if it fails, it is not a critical error or even something that we should care about... and obviously not hang the whole player for that. Fixes: #11803 --- audio/out/ao_wasapi.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index 57b9c7d87d..fcb9c96818 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -406,20 +406,28 @@ static int thread_control(struct ao *ao, enum aocontrol cmd, void *arg) if (!state->pSessionControl) return CONTROL_FALSE; - wchar_t *title = mp_from_utf8(NULL, (char*)arg); - wchar_t *tmp = NULL; - // There is a weird race condition in the IAudioSessionControl itself -- - // it seems that *sometimes* the SetDisplayName does not take effect and - // it still shows the old title. Use this loop to insist until it works. - do { - IAudioSessionControl_SetDisplayName(state->pSessionControl, title, NULL); - - SAFE_DESTROY(tmp, CoTaskMemFree(tmp)); - IAudioSessionControl_GetDisplayName(state->pSessionControl, &tmp); - } while (wcscmp(title, tmp)); - SAFE_DESTROY(tmp, CoTaskMemFree(tmp)); + wchar_t *title = mp_from_utf8(NULL, (const char *)arg); + HRESULT hr = IAudioSessionControl_SetDisplayName(state->pSessionControl, + title,NULL); talloc_free(title); - return CONTROL_OK; + + if (SUCCEEDED(hr)) + return CONTROL_OK; + + MP_WARN(ao, "Error setting audio session name: %s\n", + mp_HRESULT_to_str(hr)); + + assert(ao->client_name); + if (!ao->client_name) + return CONTROL_ERROR; + + // Fallback to client name + title = mp_from_utf8(NULL, ao->client_name); + IAudioSessionControl_SetDisplayName(state->pSessionControl, + title, NULL); + talloc_free(title); + + return CONTROL_ERROR; } return state->share_mode == AUDCLNT_SHAREMODE_EXCLUSIVE ?