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
This commit is contained in:
Kacper Michajłow 2023-06-19 19:43:12 +02:00 committed by sfan5
parent ee155d79fd
commit 3dc661fe8e
1 changed files with 21 additions and 13 deletions

View File

@ -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 ?