Fix waiting for transition to complete with fixed duration transitions

This commit is contained in:
WarmUpTill
2022-05-08 03:49:22 +02:00
committed by WarmUpTill
parent 8cc7b65436
commit 70a3ae0245

View File

@@ -2,6 +2,8 @@
#include "headers/advanced-scene-switcher.hpp"
#include "headers/utility.hpp"
using namespace std::chrono_literals;
const std::string MacroActionSwitchScene::id = "scene_switch";
bool MacroActionSwitchScene::_registered = MacroActionFactory::Register(
@@ -9,7 +11,21 @@ bool MacroActionSwitchScene::_registered = MacroActionFactory::Register(
{MacroActionSwitchScene::Create, MacroActionSwitchSceneEdit::Create,
"AdvSceneSwitcher.action.switchScene"});
void waitForTransitionChange(int duration)
void waitForTransitionChange(OBSWeakSource &transition)
{
const auto time = 100ms;
obs_source_t *source = obs_weak_source_get_source(transition);
std::unique_lock<std::mutex> lock(switcher->m);
bool stillTransitioning = true;
while (stillTransitioning && !switcher->abortMacroWait) {
switcher->macroTransitionCv.wait_for(lock, time);
float t = obs_transition_get_time(source);
stillTransitioning = t < 1.0f && t > 0.0f;
}
obs_source_release(source);
}
void waitForTransitionChangeFixedDuration(int duration)
{
duration += 200; // It seems to be necessary to add a small buffer
auto time = std::chrono::high_resolution_clock::now() +
@@ -25,7 +41,7 @@ void waitForTransitionChange(int duration)
}
}
int getTransitionOverrideDuration(OBSWeakSource scene)
int getTransitionOverrideDuration(OBSWeakSource &scene)
{
int duration = 0;
obs_source_t *source = obs_weak_source_get_source(scene);
@@ -39,11 +55,41 @@ int getTransitionOverrideDuration(OBSWeakSource scene)
return duration;
}
int getExpectedTransitionDuration(OBSWeakSource scene, double duration)
bool isUsingFixedLengthTransition(OBSWeakSource &transition)
{
int overrideDuration = getTransitionOverrideDuration(scene);
if (overrideDuration && !switcher->transitionOverrideOverride) {
return overrideDuration;
obs_source_t *source = obs_weak_source_get_source(transition);
bool ret = obs_transition_fixed(source);
obs_source_release(source);
return ret;
}
OBSWeakSource getOverrideTransition(OBSWeakSource &scene)
{
OBSWeakSource transition;
obs_source_t *source = obs_weak_source_get_source(scene);
obs_data_t *data = obs_source_get_private_settings(source);
transition = GetWeakTransitionByName(
obs_data_get_string(data, "transition"));
obs_data_release(data);
obs_source_release(source);
return transition;
}
int getExpectedTransitionDuration(OBSWeakSource &scene, OBSWeakSource &t,
double duration)
{
OBSWeakSource transition = t;
if (!switcher->transitionOverrideOverride) {
auto overrideTransition = getOverrideTransition(scene);
if (overrideTransition) {
transition = overrideTransition;
if (!isUsingFixedLengthTransition(transition)) {
return getTransitionOverrideDuration(scene);
}
}
}
if (isUsingFixedLengthTransition(transition)) {
return -1; // no API is available to access the fixed duration
}
if (duration != 0) {
return duration * 1000;
@@ -54,12 +100,19 @@ int getExpectedTransitionDuration(OBSWeakSource scene, double duration)
bool MacroActionSwitchScene::PerformAction()
{
auto scene = _scene.GetScene();
switchScene({scene, _transition.GetTransition(),
(int)(_duration.seconds * 1000)},
auto transition = _transition.GetTransition();
switchScene({scene, transition, (int)(_duration.seconds * 1000)},
obs_frontend_preview_program_mode_active());
if (_blockUntilTransitionDone && scene) {
waitForTransitionChange(getExpectedTransitionDuration(
scene, _duration.seconds));
const int expectedTransitionDuration =
getExpectedTransitionDuration(scene, transition,
_duration.seconds);
if (expectedTransitionDuration < 0) {
waitForTransitionChange(transition);
} else {
waitForTransitionChangeFixedDuration(
expectedTransitionDuration);
}
return !switcher->abortMacroWait;
}
return true;