DeckLink: continue if CoInit fails on diff. mode

This commit is contained in:
Martin Pulec
2023-02-24 11:18:18 +01:00
parent faafa640a2
commit c1d6bb84b0
5 changed files with 48 additions and 26 deletions

View File

@@ -78,6 +78,7 @@ struct state_decklink {
int output_audio_channel_count;
PlaybackDelegate *delegate;
bool com_initialized;
IDeckLink *deckLink;
IDeckLinkOutput *deckLinkOutput;
IDeckLinkMutableVideoFrame *deckLinkFrame;
@@ -143,7 +144,8 @@ static void audio_play_decklink_help(const char *driver_name)
UNUSED(driver_name);
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
deckLinkIterator = create_decklink_iterator(true);
bool com_initialized = false;
deckLinkIterator = create_decklink_iterator(&com_initialized, true);
if (deckLinkIterator == NULL)
{
return;
@@ -174,7 +176,7 @@ static void audio_play_decklink_help(const char *driver_name)
}
deckLinkIterator->Release();
decklink_uninitialize();
decklink_uninitialize(&com_initialized);
// If no DeckLink cards were found in the system, inform the user
if (numDevices == 0)
@@ -244,7 +246,7 @@ static void *audio_play_decklink_init(const char *cfg)
"\"-d decklink -r analog\" instead.\n");
// Initialize the DeckLink API
deckLinkIterator = create_decklink_iterator(true);
deckLinkIterator = create_decklink_iterator(&s->com_initialized, true);
if (!deckLinkIterator) {
goto error;
}
@@ -452,8 +454,8 @@ static void audio_play_decklink_done(void *state)
s->deckLinkFrame->Release();
s->deckLink->Release();
s->deckLinkOutput->Release();
decklink_uninitialize(&s->com_initialized);
free(s);
decklink_uninitialize();
}
static const struct audio_playback_info aplay_decklink_info = {

View File

@@ -142,21 +142,22 @@ std::string get_str_from_bmd_api_str(BMD_STR string)
* should be followed by decklink_uninitialize() when done with DeckLink (not when releasing
* IDeckLinkIterator!), typically on application shutdown.
*/
IDeckLinkIterator *create_decklink_iterator(bool verbose, bool coinit)
IDeckLinkIterator *create_decklink_iterator(bool *com_initialized, bool verbose, bool coinit)
{
IDeckLinkIterator *deckLinkIterator = nullptr;
#ifdef WIN32
if (coinit) {
decklink_initialize();
decklink_initialize(com_initialized);
}
HRESULT result = CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
IID_IDeckLinkIterator, (void **) &deckLinkIterator);
if (FAILED(result)) {
CoUninitialize();
decklink_uninitialize(com_initialized);
deckLinkIterator = nullptr;
}
#else
UNUSED(coinit);
*com_initialized = false;
deckLinkIterator = CreateDeckLinkIteratorInstance();
#endif
@@ -171,12 +172,18 @@ IDeckLinkIterator *create_decklink_iterator(bool verbose, bool coinit)
}
/// called automatically by create_decklink_iterator() if second parameter is true (default)
bool decklink_initialize()
bool decklink_initialize(bool *com_initialized)
{
*com_initialized = false;
#ifdef WIN32
// Initialize COM on this thread
HRESULT result = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(result)) {
*com_initialized = true;
return true;
}
if (result == RPC_E_CHANGED_MODE) {
LOG(LOG_LEVEL_WARNING) << "[BMD] COM already intiialized with a different mode!\n";
return true;
}
log_msg(LOG_LEVEL_ERROR, "Initialize of COM failed - result = "
@@ -187,8 +194,12 @@ bool decklink_initialize()
#endif
}
void decklink_uninitialize()
void decklink_uninitialize(bool *com_initialized)
{
if (!*com_initialized) {
return;
}
*com_initialized = false;
#ifdef WIN32
CoUninitialize();
#endif

View File

@@ -98,9 +98,12 @@ void release_bmd_api_str(BMD_STR string);
std::string get_str_from_bmd_api_str(BMD_STR string);
#endif
IDeckLinkIterator *create_decklink_iterator(bool verbose = true, bool coinit = true);
bool decklink_initialize();
void decklink_uninitialize();
///< @param[out] com_initialized - pass a pointer to bool
IDeckLinkIterator *create_decklink_iterator(bool *com_initialized, bool verbose = true, bool coinit = true);
///< param pass a pointer to a bool that will be passed to decklink_uninintialize()
bool decklink_initialize(bool *com_initialized);
///< @param com_initialized - pointer passed to decklink_initialize (or create_decklink_iterator)
void decklink_uninitialize(bool *com_initialized);
bool blackmagic_api_version_check();
void print_decklink_version(void);

View File

@@ -146,6 +146,7 @@ struct device_state {
};
struct vidcap_decklink_state {
bool com_initialized = true;
vector <struct device_state> state{vector <struct device_state>(1)};
int devices_cnt = 1;
string mode;
@@ -181,12 +182,12 @@ struct vidcap_decklink_state {
void set_codec(codec_t c);
vidcap_decklink_state() {
if (!decklink_initialize()) {
if (!decklink_initialize(&com_initialized)) {
throw 1;
}
}
~vidcap_decklink_state() {
decklink_uninitialize();
decklink_uninitialize(&com_initialized);
}
};
@@ -563,7 +564,8 @@ decklink_help(bool full)
cout << "\n";
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
IDeckLinkIterator *deckLinkIterator = create_decklink_iterator();
bool com_initialized = false;
IDeckLinkIterator *deckLinkIterator = create_decklink_iterator(&com_initialized);
if (deckLinkIterator == NULL) {
return 0;
}
@@ -596,7 +598,7 @@ decklink_help(bool full)
deckLinkIterator->Release();
decklink_uninitialize();
decklink_uninitialize(&com_initialized);
// If no DeckLink cards were found in the system, inform the user
if (numDevices == 0)
@@ -792,7 +794,8 @@ static void vidcap_decklink_probe(device_info **available_cards, int *card_count
int numDevices = 0;
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
deckLinkIterator = create_decklink_iterator(false);
bool com_initialized = false;
deckLinkIterator = create_decklink_iterator(&com_initialized, false);
if (deckLinkIterator == nullptr) {
return;
}
@@ -889,7 +892,7 @@ static void vidcap_decklink_probe(device_info **available_cards, int *card_count
}
deckLinkIterator->Release();
decklink_uninitialize();
decklink_uninitialize(&com_initialized);
*available_cards = cards;
}
@@ -1058,8 +1061,9 @@ bool device_state::init(struct vidcap_decklink_state *s, struct tile *t, BMDAudi
tile = t;
int dnum = 0;
bool com_initialized = false;
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
IDeckLinkIterator *deckLinkIterator = create_decklink_iterator(true, false);
IDeckLinkIterator *deckLinkIterator = create_decklink_iterator(&com_initialized, true, false);
if (deckLinkIterator == NULL) {
return false;
}

View File

@@ -321,6 +321,7 @@ struct device_state {
struct state_decklink {
uint32_t magic = DECKLINK_MAGIC;
chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
bool com_initialized = false;
vector<struct device_state> state;
@@ -428,7 +429,8 @@ static void show_help(bool full)
col() << "\nDevices:\n";
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
deckLinkIterator = create_decklink_iterator(true);
bool com_initialized = false;
deckLinkIterator = create_decklink_iterator(&com_initialized, true);
if (deckLinkIterator == NULL) {
return;
}
@@ -460,7 +462,7 @@ static void show_help(bool full)
deckLinkIterator->Release();
decklink_uninitialize();
decklink_uninitialize(&com_initialized);
// If no DeckLink cards were found in the system, inform the user
if (numDevices == 0)
@@ -897,7 +899,8 @@ static void display_decklink_probe(struct device_info **available_cards, int *co
*count = 0;
*available_cards = nullptr;
deckLinkIterator = create_decklink_iterator(false);
bool com_initialized = false;
deckLinkIterator = create_decklink_iterator(&com_initialized, false);
if (deckLinkIterator == NULL) {
return;
}
@@ -926,7 +929,7 @@ static void display_decklink_probe(struct device_info **available_cards, int *co
}
deckLinkIterator->Release();
decklink_uninitialize();
decklink_uninitialize(&com_initialized);
}
static auto parse_devices(const char *devices_str, vector<string> *cardId) {
@@ -1129,7 +1132,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
}
// Initialize the DeckLink API
deckLinkIterator = create_decklink_iterator(true);
deckLinkIterator = create_decklink_iterator(&s->com_initialized, true);
if (!deckLinkIterator)
{
delete s;
@@ -1380,9 +1383,8 @@ static void display_decklink_done(void *state)
delete s->timecode;
decklink_uninitialize(&s->com_initialized);
delete s;
decklink_uninitialize();
}
/**