win-wasapi: Don't reconnect when inactive

Unnecessary reconnect attempts may cause noticeable hitches.
This commit is contained in:
jpark37
2022-09-30 21:50:33 -07:00
committed by Jim
parent ddff584b46
commit cbb910a99c

View File

@@ -182,7 +182,7 @@ class WASAPISource {
std::atomic<bool> isDefaultDevice = false;
bool previouslyFailed = false;
WinHandle reconnectThread;
WinHandle reconnectThread = NULL;
class CallbackStartCapture : public ARtwqAsyncCallback {
public:
@@ -238,6 +238,7 @@ class WASAPISource {
WinHandle stopSignal;
WinHandle receiveSignal;
WinHandle restartSignal;
WinHandle reconnectExitSignal;
WinHandle exitSignal;
WinHandle initSignal;
DWORD reconnectDuration = 0;
@@ -298,6 +299,9 @@ public:
void Update(obs_data_t *settings);
void OnWindowChanged(obs_data_t *settings);
void Activate();
void Deactivate();
void SetDefaultDevice(EDataFlow flow, ERole role, LPCWSTR id);
void OnStartCapture();
@@ -390,6 +394,10 @@ WASAPISource::WASAPISource(obs_data_t *settings, obs_source_t *source_,
if (!restartSignal.Valid())
throw "Could not create restart signal";
reconnectExitSignal = CreateEvent(nullptr, true, false, nullptr);
if (!reconnectExitSignal.Valid())
throw "Could not create reconnect exit signal";
exitSignal = CreateEvent(nullptr, true, false, nullptr);
if (!exitSignal.Valid())
throw "Could not create exit signal";
@@ -402,11 +410,6 @@ WASAPISource::WASAPISource(obs_data_t *settings, obs_source_t *source_,
if (!reconnectSignal.Valid())
throw "Could not create reconnect signal";
reconnectThread = CreateThread(
nullptr, 0, WASAPISource::ReconnectThread, this, 0, nullptr);
if (!reconnectThread.Valid())
throw "Failed to create reconnect thread";
notify = new WASAPINotify(this);
if (!notify)
throw "Could not create WASAPINotify";
@@ -525,6 +528,9 @@ void WASAPISource::Start()
void WASAPISource::Stop()
{
if (!reconnectThread.Valid())
WaitForSingleObject(reconnectSignal, INFINITE);
SetEvent(stopSignal);
blog(LOG_INFO, "WASAPI: Device '%s' Terminated", device_name.c_str());
@@ -532,11 +538,15 @@ void WASAPISource::Stop()
if (rtwq_supported)
SetEvent(receiveSignal);
WaitForSingleObject(idleSignal, INFINITE);
if (reconnectThread.Valid())
WaitForSingleObject(idleSignal, INFINITE);
SetEvent(exitSignal);
WaitForSingleObject(reconnectThread, INFINITE);
if (reconnectThread.Valid()) {
SetEvent(reconnectExitSignal);
WaitForSingleObject(reconnectThread, INFINITE);
}
if (rtwq_supported)
rtwq_unlock_work_queue(sampleReady.GetQueueId());
@@ -657,6 +667,25 @@ void WASAPISource::OnWindowChanged(obs_data_t *settings)
SetEvent(restartSignal);
}
void WASAPISource::Activate()
{
if (!reconnectThread.Valid()) {
ResetEvent(reconnectExitSignal);
reconnectThread = CreateThread(nullptr, 0,
WASAPISource::ReconnectThread,
this, 0, nullptr);
}
}
void WASAPISource::Deactivate()
{
if (reconnectThread.Valid()) {
SetEvent(reconnectExitSignal);
WaitForSingleObject(reconnectThread, INFINITE);
reconnectThread = NULL;
}
}
ComPtr<IMMDevice> WASAPISource::InitDevice(IMMDeviceEnumerator *enumerator,
bool isDefaultDevice,
SourceType type,
@@ -1005,10 +1034,15 @@ DWORD WINAPI WASAPISource::ReconnectThread(LPVOID param)
WASAPISource *source = (WASAPISource *)param;
const HANDLE sigs[] = {
source->exitSignal,
source->reconnectExitSignal,
source->reconnectSignal,
};
const HANDLE reconnect_sigs[] = {
source->reconnectExitSignal,
source->stopSignal,
};
bool exit = false;
while (!exit) {
const DWORD ret = WaitForMultipleObjects(_countof(sigs), sigs,
@@ -1020,8 +1054,10 @@ DWORD WINAPI WASAPISource::ReconnectThread(LPVOID param)
default:
assert(ret == (WAIT_OBJECT_0 + 1));
if (source->reconnectDuration > 0) {
WaitForSingleObject(source->stopSignal,
source->reconnectDuration);
WaitForMultipleObjects(
_countof(reconnect_sigs),
reconnect_sigs, false,
source->reconnectDuration);
}
source->Start();
}
@@ -1426,6 +1462,16 @@ static void UpdateWASAPISource(void *obj, obs_data_t *settings)
static_cast<WASAPISource *>(obj)->Update(settings);
}
static void ActivateWASAPISource(void *obj)
{
static_cast<WASAPISource *>(obj)->Activate();
}
static void DeactivateWASAPISource(void *obj)
{
static_cast<WASAPISource *>(obj)->Deactivate();
}
static bool UpdateWASAPIMethod(obs_properties_t *props, obs_property_t *,
obs_data_t *settings)
{
@@ -1542,6 +1588,8 @@ void RegisterWASAPIInput()
info.create = CreateWASAPIInput;
info.destroy = DestroyWASAPISource;
info.update = UpdateWASAPISource;
info.activate = ActivateWASAPISource;
info.deactivate = DeactivateWASAPISource;
info.get_defaults = GetWASAPIDefaultsInput;
info.get_properties = GetWASAPIPropertiesInput;
info.icon_type = OBS_ICON_TYPE_AUDIO_INPUT;
@@ -1559,6 +1607,8 @@ void RegisterWASAPIDeviceOutput()
info.create = CreateWASAPIDeviceOutput;
info.destroy = DestroyWASAPISource;
info.update = UpdateWASAPISource;
info.activate = ActivateWASAPISource;
info.deactivate = DeactivateWASAPISource;
info.get_defaults = GetWASAPIDefaultsDeviceOutput;
info.get_properties = GetWASAPIPropertiesDeviceOutput;
info.icon_type = OBS_ICON_TYPE_AUDIO_OUTPUT;
@@ -1576,6 +1626,8 @@ void RegisterWASAPIProcessOutput()
info.create = CreateWASAPIProcessOutput;
info.destroy = DestroyWASAPISource;
info.update = UpdateWASAPISource;
info.activate = ActivateWASAPISource;
info.deactivate = DeactivateWASAPISource;
info.get_defaults = GetWASAPIDefaultsProcessOutput;
info.get_properties = GetWASAPIPropertiesProcessOutput;
info.icon_type = OBS_ICON_TYPE_PROCESS_AUDIO_OUTPUT;