mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
win-dshow: Allow synchronous create/update
Allows the ability to (optionally) synchronously create/update a directshow device source rather than always asynchronously update the device. This is useful if creating/destroying scenes/sources very quickly, and helps minimize the risk of creating new directshow sources that use the same device, yet may not activate because an existing source may already exist. To use, set "synchronous_activate" to true in its settings when updating or creating. Note that this setting will be erased after it's used, and will not be saved to user settings, so it must be set each time in order to be used. Closes obsproject/obs-studio#1228
This commit is contained in:
parent
e265fc92ed
commit
db06a1c12a
@ -150,6 +150,7 @@ public:
|
||||
enum class Action {
|
||||
None,
|
||||
Activate,
|
||||
ActivateBlock,
|
||||
Deactivate,
|
||||
Shutdown,
|
||||
ConfigVideo,
|
||||
@ -179,6 +180,7 @@ struct DShowInput {
|
||||
obs_source_audio audio;
|
||||
|
||||
WinHandle semaphore;
|
||||
WinHandle activated_event;
|
||||
WinHandle thread;
|
||||
CriticalSection mutex;
|
||||
vector<Action> actions;
|
||||
@ -190,6 +192,16 @@ struct DShowInput {
|
||||
ReleaseSemaphore(semaphore, 1, nullptr);
|
||||
}
|
||||
|
||||
inline void QueueActivate(obs_data_t *settings)
|
||||
{
|
||||
bool block = obs_data_get_bool(settings, "synchronous_activate");
|
||||
QueueAction(block ? Action::ActivateBlock : Action::Activate);
|
||||
if (block) {
|
||||
obs_data_erase(settings, "synchronous_activate");
|
||||
WaitForSingleObject(activated_event, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
inline DShowInput(obs_source_t *source_, obs_data_t *settings)
|
||||
: source (source_),
|
||||
device (InitGraph::False)
|
||||
@ -204,6 +216,10 @@ struct DShowInput {
|
||||
if (!semaphore)
|
||||
throw "Failed to create semaphore";
|
||||
|
||||
activated_event = CreateEvent(nullptr, false, false, nullptr);
|
||||
if (!activated_event)
|
||||
throw "Failed to create activated_event";
|
||||
|
||||
thread = CreateThread(nullptr, 0, DShowThread, this, 0,
|
||||
nullptr);
|
||||
if (!thread)
|
||||
@ -215,7 +231,7 @@ struct DShowInput {
|
||||
if (obs_data_get_bool(settings, "active")) {
|
||||
bool showing = obs_source_showing(source);
|
||||
if (!deactivateWhenNotShowing || showing)
|
||||
QueueAction(Action::Activate);
|
||||
QueueActivate(settings);
|
||||
|
||||
active = true;
|
||||
}
|
||||
@ -304,13 +320,18 @@ void DShowInput::DShowLoop()
|
||||
|
||||
switch (action) {
|
||||
case Action::Activate:
|
||||
case Action::ActivateBlock:
|
||||
{
|
||||
bool block = action == Action::ActivateBlock;
|
||||
|
||||
obs_data_t *settings;
|
||||
settings = obs_source_get_settings(source);
|
||||
if (!Activate(settings)) {
|
||||
obs_source_output_video(source,
|
||||
nullptr);
|
||||
}
|
||||
if (block)
|
||||
SetEvent(activated_event);
|
||||
obs_data_release(settings);
|
||||
break;
|
||||
}
|
||||
@ -1075,9 +1096,7 @@ static void UpdateDShowInput(void *data, obs_data_t *settings)
|
||||
{
|
||||
DShowInput *input = reinterpret_cast<DShowInput*>(data);
|
||||
if (input->active)
|
||||
input->QueueAction(Action::Activate);
|
||||
|
||||
UNUSED_PARAMETER(settings);
|
||||
input->QueueActivate(settings);
|
||||
}
|
||||
|
||||
static void GetDShowDefaults(obs_data_t *settings)
|
||||
|
Loading…
Reference in New Issue
Block a user