Ffplay not work with SDL


#1

Here is a problem when I use SDL(2.0.7) for audio playback with ffmpeg(3.4) in Windows 7. The program ffplay calls function audio_open which calls function SDL_OpenAudioDevice to get default audio device, WASAPI by default in Windows 7. The program always shutdown and show error message ‘WASAPI can’t initialize audio client’. So I add code to call function CoInitialize(NULL) in function main, but it is not work. And the same time, I checked SDL’s source code about initialize WASAPI, I found it calls function WIN_CoInitialize. So I change CoInitialize(NULL) to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED), it is not work, too. It works when I change parameter ‘COINIT_APARTMENTTHREADED’ to ‘COINIT_MULTITHREADED’. I think SDL should change the way when initialize WASAPI. Call CoInitializeEx(NULL, COINIT_MULTITHREADED) first in WIN_CoInitialize could be the right way, instead call CoInitializeEx(NULL, COINIT_ APARTMENTTHREADED) first.

Some modify code in ffplay listed below.
int main(int argc, char **argv)
{

#ifdef _WIN32
CoInitializeEx(NULL, COINIT_MULTITHREADED));
#endif

#ifdef _WIN32
CoUninitialize();
#endif

return 0;

}

SDL_windows.c
HRESULT
WIN_CoInitialize(void)
{
/* SDL handles any threading model, so initialize with the default, which
is compatible with OLE and if that doesn’t work, try multi-threaded mode.

   If you need multi-threaded mode, call CoInitializeEx() before SDL_Init()
*/

#ifdef WINRT
/* DLudwig: On WinRT, it is assumed that COM was initialized in main().
CoInitializeEx is available (not CoInitialize though), however
on WinRT, main() is typically declared with the [MTAThread]
attribute, which, AFAIK, should initialize COM.
*/
return S_OK;
#else
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (hr == RPC_E_CHANGED_MODE) {
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
}

/* S_FALSE means success, but someone else already initialized. */
/* You still need to call CoUninitialize in this case! */
if (hr == S_FALSE) {
    return S_OK;
}

return hr;

#endif
}