From 4fe552f225dd216538283e69eba0b2f04622d349 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Fri, 24 Feb 2023 15:07:28 +0100 Subject: [PATCH] use common com_[un]initialize --- src/audio/capture/wasapi.cpp | 23 ++++++++++++----------- src/audio/playback/wasapi.cpp | 21 +++++++++++---------- src/blackmagic_common.cpp | 15 ++++++--------- src/host.cpp | 15 ++------------- src/utils/windows.cpp | 11 +++++++---- src/utils/windows.h | 7 +++++-- src/video_capture/DirectShowGrabber.cpp | 9 ++++----- src/video_capture/decklink.cpp | 2 +- 8 files changed, 48 insertions(+), 55 deletions(-) diff --git a/src/audio/capture/wasapi.cpp b/src/audio/capture/wasapi.cpp index 7c1dc01fa..136b88d52 100644 --- a/src/audio/capture/wasapi.cpp +++ b/src/audio/capture/wasapi.cpp @@ -71,6 +71,7 @@ using std::string; using std::wstring; struct state_acap_wasapi { + bool com_initialized; struct audio_frame frame; IMMDevice *pDevice; IAudioClient *pAudioClient; @@ -91,13 +92,13 @@ static void audio_cap_wasapi_probe(struct device_info **available_devices, int * *deleter = free; *available_devices = (struct device_info *) malloc(0); *dev_count = 0; + bool com_initialized = false; - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - IMMDeviceEnumerator *enumerator = nullptr; - IMMDeviceCollection *pEndpoints = nullptr; - if (hr != S_OK && hr != S_FALSE) { + if (!com_initialize(&com_initialized, MOD_NAME)) { return; } + IMMDeviceEnumerator *enumerator = nullptr; + IMMDeviceCollection *pEndpoints = nullptr; try { THROW_IF_FAILED(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, @@ -127,7 +128,7 @@ static void audio_cap_wasapi_probe(struct device_info **available_devices, int * } SAFE_RELEASE(enumerator); SAFE_RELEASE(pEndpoints); - CoUninitialize(); + com_uninitialize(&com_initialized); } static string wstring_to_string(wstring const & wstr) { @@ -180,10 +181,10 @@ static void show_help() { style::bold << fg::red << "\t-s wasapi" << fg::reset << "[:|:]\n" << style::reset << "\nAvailable devices:\n"; - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); IMMDeviceEnumerator *enumerator = nullptr; IMMDeviceCollection *pEndpoints = nullptr; - if (hr != S_OK && hr != S_FALSE) { + bool com_initialized = false; + if (!com_initialize(&com_initialized, MOD_NAME)) { return; } @@ -212,7 +213,7 @@ static void show_help() { } SAFE_RELEASE(enumerator); SAFE_RELEASE(pEndpoints); - CoUninitialize(); + com_uninitialize(&com_initialized); } static void * audio_cap_wasapi_init(struct module *parent, const char *cfg) @@ -232,11 +233,11 @@ static void * audio_cap_wasapi_init(struct module *parent, const char *cfg) mbtowc(deviceID, cfg, (sizeof deviceID / 2) - 1); } } - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if (hr != S_OK && hr != S_FALSE) { + auto s = new state_acap_wasapi(); + if (!com_initialize(&s->com_initialized, MOD_NAME)) { + delete s; return nullptr; } - auto s = new state_acap_wasapi(); IMMDeviceEnumerator *enumerator = nullptr; try { diff --git a/src/audio/playback/wasapi.cpp b/src/audio/playback/wasapi.cpp index 1184cc95b..ac4adb166 100644 --- a/src/audio/playback/wasapi.cpp +++ b/src/audio/playback/wasapi.cpp @@ -73,6 +73,7 @@ using std::wcout; using std::wstring; struct state_aplay_wasapi { + bool com_initialized; struct audio_desc desc; IMMDevice *pDevice; IAudioClient *pAudioClient; @@ -122,10 +123,10 @@ static void audio_play_wasapi_probe(struct device_info **available_devices, int *available_devices = (struct device_info *) malloc(0); *dev_count = 0; - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); IMMDeviceEnumerator *enumerator = nullptr; IMMDeviceCollection *pEndpoints = nullptr; - if (hr != S_OK && hr != S_FALSE) { + bool com_initialized = false; + if (!com_initialize(&com_initialized, MOD_NAME)) { return; } @@ -157,7 +158,7 @@ static void audio_play_wasapi_probe(struct device_info **available_devices, int } SAFE_RELEASE(enumerator); SAFE_RELEASE(pEndpoints); - CoUninitialize(); + com_uninitialize(&com_initialized); } static void audio_play_wasapi_help(const char *driver_name) @@ -171,8 +172,8 @@ static void show_help() { style::bold << fg::red << "\t-r wasapi" << fg::reset << "[:|:] --param audio-buffer-len=\n" << style::reset << "\nAvailable devices:\n"; - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if (hr != S_OK && hr != S_FALSE) { + bool com_initialized = false; + if (!com_initialize(&com_initialized, MOD_NAME)) { return; } IMMDeviceEnumerator *enumerator = nullptr; @@ -204,7 +205,7 @@ static void show_help() { } SAFE_RELEASE(enumerator); SAFE_RELEASE(pEndpoints); - CoUninitialize(); + com_uninitialize(&com_initialized); } static void * audio_play_wasapi_init(const char *cfg) @@ -222,11 +223,11 @@ static void * audio_play_wasapi_init(const char *cfg) mbtowc(deviceID, cfg, (sizeof deviceID / 2) - 1); } } - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if (hr != S_OK && hr != S_FALSE) { + auto s = new state_aplay_wasapi(); + if (!com_initialize(&s->com_initialized, MOD_NAME)) { + delete s; return nullptr; } - auto s = new state_aplay_wasapi(); IMMDeviceEnumerator *enumerator = nullptr; try { @@ -266,7 +267,7 @@ static void * audio_play_wasapi_init(const char *cfg) } } catch (ug_runtime_error &e) { LOG(LOG_LEVEL_ERROR) << MOD_NAME << e.what() << "\n"; - CoUninitialize(); + com_uninitialize(&s->com_initialized); delete s; s = nullptr; } diff --git a/src/blackmagic_common.cpp b/src/blackmagic_common.cpp index a2b051ade..dcfebe0d9 100644 --- a/src/blackmagic_common.cpp +++ b/src/blackmagic_common.cpp @@ -3,7 +3,7 @@ * @author Martin Pulec */ /* - * Copyright (c) 2014-2021 CESNET, z. s. p. o. + * Copyright (c) 2014-2023 CESNET, z. s. p. o. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -147,7 +147,7 @@ IDeckLinkIterator *create_decklink_iterator(bool *com_initialized, bool verbose, IDeckLinkIterator *deckLinkIterator = nullptr; #ifdef WIN32 if (coinit) { - com_initialize(com_initialized); + com_initialize(com_initialized, "[BMD] "); } HRESULT result = CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void **) &deckLinkIterator); @@ -183,7 +183,7 @@ bool blackmagic_api_version_check() HRESULT result; bool com_initialized = false; - if (!com_initialize(&com_initialized)) { + if (!com_initialize(&com_initialized, "[BMD] ")) { goto cleanup; } #ifdef WIN32 @@ -230,11 +230,8 @@ void print_decklink_version() HRESULT result; #ifdef WIN32 - // Initialize COM on this thread - result = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if(FAILED(result)) { - fprintf(stderr, "Initialize of COM failed - result = " - "%08lx.\n", result); + bool com_initialized = false; + if (!com_initialize(&com_initialized, "[BMD] ")) { goto cleanup; } @@ -266,7 +263,7 @@ cleanup: APIInformation->Release(); } #ifdef WIN32 - CoUninitialize(); + com_uninitialize(&com_initialized); #endif } diff --git a/src/host.cpp b/src/host.cpp index c1555d672..b31bd3ff7 100644 --- a/src/host.cpp +++ b/src/host.cpp @@ -142,11 +142,7 @@ void common_cleanup(struct init_data *init) dlclose(a); } #endif -#ifdef _WIN32 - if (init->com_initialized) { - CoUninitialize(); - } -#endif + com_uninitialize(&init->com_initialized); } delete init; @@ -412,14 +408,7 @@ struct init_data *common_preinit(int argc, char *argv[]) // Initialize COM on main thread - otherwise Portaudio would initialize it as COINIT_APARTMENTTHREADED but MULTITHREADED // is perhaps better variant (Portaudio would accept that). - HRESULT result = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if (SUCCEEDED(result)) { - init.com_initialized = true; - } else if (result == RPC_E_CHANGED_MODE) { - log_msg(LOG_LEVEL_WARNING, "COM already intiialized in a different mode!\n"); - } else { - log_msg(LOG_LEVEL_ERROR, "Initialize of COM failed - %s\n", hresult_to_str(result)); - } + com_initialize(&init.com_initialized, nullptr); #endif if (strstr(argv[0], "run_tests") == nullptr) { diff --git a/src/utils/windows.cpp b/src/utils/windows.cpp index 558ca91ec..82ca6aa67 100644 --- a/src/utils/windows.cpp +++ b/src/utils/windows.cpp @@ -48,8 +48,11 @@ #include #include "debug.h" -bool com_initialize(bool *com_initialized) +bool com_initialize(bool *com_initialized, const char *err_prefix) { + if (err_prefix == nullptr) { + err_prefix = ""; + } *com_initialized = false; // Initialize COM on this thread HRESULT result = CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -58,10 +61,10 @@ bool com_initialize(bool *com_initialized) return true; } if (result == RPC_E_CHANGED_MODE) { - LOG(LOG_LEVEL_WARNING) << "COM already intiialized with a different mode!\n"; + LOG(LOG_LEVEL_WARNING) << err_prefix << "COM already intiialized with a different mode!\n"; return true; } - LOG(LOG_LEVEL_ERROR) << "Initialize of COM failed - " << hresult_to_str(result) << "\n"; + LOG(LOG_LEVEL_ERROR) << err_prefix << "Initialize of COM failed - " << hresult_to_str(result) << "\n"; return false; } @@ -105,7 +108,7 @@ const char *hresult_to_str(HRESULT res) { } } #else -bool com_initialize(bool *com_initialized [[maybe_unused]]) +bool com_initialize(bool *com_initialized [[maybe_unused]], const char *err_prefix [[maybe_unused]]) { return true; } diff --git a/src/utils/windows.h b/src/utils/windows.h index 1632b655f..3de7158c7 100644 --- a/src/utils/windows.h +++ b/src/utils/windows.h @@ -65,8 +65,11 @@ extern "C" { #endif -///< param pass a pointer to a bool that will be passed to com_uninintialize() -bool com_initialize(bool *com_initialized); +/** + * @param[out] com_initialize a pointer to a bool that will be passed to com_uninintialize() + * @param[in] err_prefix optional error prefix to be used for eventual error messges (may be NULL) + */ +bool com_initialize(bool *com_initialized, const char *err_prefix); ///< @param com_initialized - pointer passed to com_initialize (or create_com_iterator) void com_uninitialize(bool *com_initialized); diff --git a/src/video_capture/DirectShowGrabber.cpp b/src/video_capture/DirectShowGrabber.cpp index a01e91dff..7563bdc34 100644 --- a/src/video_capture/DirectShowGrabber.cpp +++ b/src/video_capture/DirectShowGrabber.cpp @@ -17,6 +17,7 @@ #include "tv.h" #include "utils/color_out.h" #include "utils/macros.h" +#include "utils/windows.h" #include "video.h" #include "video_capture.h" @@ -75,6 +76,7 @@ static int *yuv_clamp; class SampleGrabberCallback; struct vidcap_dshow_state { + bool com_initialized; int deviceNumber; char *deviceName; int modeNumber; @@ -216,7 +218,7 @@ static bool cleanup(struct vidcap_dshow_state *s) { */ // COM library uninitialization - CoUninitialize(); + com_uninitialize(&s->com_initialized); if (s->frame != NULL) vf_free(s->frame); if (s->grabBuffer != NULL) free(s->grabBuffer); @@ -266,10 +268,7 @@ static bool common_init(struct vidcap_dshow_state *s) { // Initialize COM library // COINIT_APARTMENTTHREADED is used because we do not expect any other thread to work with the object - res = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if (res != S_OK && res != S_FALSE && res != RPC_E_CHANGED_MODE) { - log_msg(LOG_LEVEL_ERROR, MOD_NAME "vidcap_dshow_init: COM library initialization failed.\n"); - ErrorDescription(res); + if (com_initialize(&s->com_initialized, "widcap_dshow_init: ")) { return false; } diff --git a/src/video_capture/decklink.cpp b/src/video_capture/decklink.cpp index fc43c5f81..59727713d 100644 --- a/src/video_capture/decklink.cpp +++ b/src/video_capture/decklink.cpp @@ -183,7 +183,7 @@ struct vidcap_decklink_state { void set_codec(codec_t c); vidcap_decklink_state() { - if (!com_initialize(&com_initialized)) { + if (!com_initialize(&com_initialized, MOD_NAME)) { throw 1; } }