diff --git a/libobs/audio-monitoring/win32/wasapi-output.c b/libobs/audio-monitoring/win32/wasapi-output.c index 750f9b58a..b6956b370 100644 --- a/libobs/audio-monitoring/win32/wasapi-output.c +++ b/libobs/audio-monitoring/win32/wasapi-output.c @@ -165,7 +165,10 @@ static void on_audio_playback(void *param, obs_source_t *source, UINT32 pad = 0; monitor->client->lpVtbl->GetCurrentPadding(monitor->client, &pad); - if (monitor->source_has_video) { + bool decouple_audio = + source->async_unbuffered && source->async_decoupled; + + if (monitor->source_has_video && !decouple_audio) { uint64_t ts = audio_data->timestamp - ts_offset; if (!process_audio_delay(monitor, (float**)(&resample_data[0]), diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 0e9d3f484..aee6a3c38 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -610,6 +610,7 @@ struct obs_source { bool async_active; bool async_update_texture; bool async_unbuffered; + bool async_decoupled; struct obs_source_frame *async_preload_frame; DARRAY(struct async_frame) async_cache; DARRAY(struct obs_source_frame*)async_frames; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 2f33f0bbd..b374def5d 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -1675,9 +1675,13 @@ static void obs_source_update_async_video(obs_source_t *source) source->async_rendered = true; if (frame) { - source->timing_adjust = - obs->video.video_time - frame->timestamp; - source->timing_set = true; + if (!source->async_decoupled || + !source->async_unbuffered) { + source->timing_adjust = + obs->video.video_time - + frame->timestamp; + source->timing_set = true; + } if (source->async_update_texture) { update_async_texture(source, frame, @@ -4069,3 +4073,23 @@ obs_data_t *obs_source_get_private_settings(obs_source_t *source) obs_data_addref(source->private_settings); return source->private_settings; } + +void obs_source_set_async_decoupled(obs_source_t *source, bool decouple) +{ + if (!obs_ptr_valid(source, "obs_source_set_async_decoupled")) + return; + + source->async_decoupled = decouple; + if (decouple) { + pthread_mutex_lock(&source->audio_buf_mutex); + source->timing_set = false; + reset_audio_data(source, 0); + pthread_mutex_unlock(&source->audio_buf_mutex); + } +} + +bool obs_source_async_decoupled(const obs_source_t *source) +{ + return obs_source_valid(source, "obs_source_async_decoupled") ? + source->async_decoupled : false; +} diff --git a/libobs/obs.h b/libobs/obs.h index 152dc9102..9a62872b1 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -1118,6 +1118,12 @@ EXPORT void obs_source_set_async_unbuffered(obs_source_t *source, bool unbuffered); EXPORT bool obs_source_async_unbuffered(const obs_source_t *source); +/** Used to decouple audio from video so that audio doesn't attempt to sync up + * with video. I.E. Audio acts independently. Only works when in unbuffered + * mode. */ +EXPORT void obs_source_set_async_decoupled(obs_source_t *source, bool decouple); +EXPORT bool obs_source_async_decoupled(const obs_source_t *source); + /* ------------------------------------------------------------------------- */ /* Transition-specific functions */ enum obs_transition_target {