From 534c553b233cf247fc4fe2d2ca3fef40a5eaba96 Mon Sep 17 00:00:00 2001 From: James Park Date: Fri, 5 Jul 2019 07:31:07 -0700 Subject: [PATCH 1/2] win-dshow: Decouple audio from video If a device produces video and audio timestamps atdifferent rates, this divergence can cause massive buffering on the audio side, leading to a capped audio buffer, and total sound loss. This change allows a hardcoded list of devices to use the existing decoupling logic. For now, only "GV-USB2" has been added. When combined with another fix, 5+ hours of stable audio without any buffering on my GV-USB2 where it used to drop sound completely after an hour or so. Partially fixes https://obsproject.com/mantis/view.php?id=1269 --- plugins/win-dshow/win-dshow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/win-dshow/win-dshow.cpp b/plugins/win-dshow/win-dshow.cpp index b6434abf2..b150e8d9b 100644 --- a/plugins/win-dshow/win-dshow.cpp +++ b/plugins/win-dshow/win-dshow.cpp @@ -800,6 +800,11 @@ static inline bool IsEncoded(const VideoConfig &config) wstrstri(config.name.c_str(), L"stream engine") != NULL; } +static inline bool IsDecoupled(const VideoConfig &config) +{ + return wstrstri(config.name.c_str(), L"GV-USB2") != NULL; +} + inline void DShowInput::SetupBuffering(obs_data_t *settings) { BufferingType bufType; @@ -813,6 +818,7 @@ inline void DShowInput::SetupBuffering(obs_data_t *settings) useBuffering = bufType == BufferingType::On; obs_source_set_async_unbuffered(source, !useBuffering); + obs_source_set_async_decoupled(source, IsDecoupled(videoConfig)); } static DStr GetVideoFormatName(VideoFormat format); From da87f08da45e3ceb2b386bc01ead51d96b2772d7 Mon Sep 17 00:00:00 2001 From: James Park Date: Fri, 5 Jul 2019 08:41:34 -0700 Subject: [PATCH 2/2] libobs: Buffer-smoothing enhancements If an audio source does not provide enough data at a steady pace, the timestamp update does not happen, and buffering increases until it maxes out. To counteract this, update the timestamp anyway. Another issue for decoupled audio sources is that timing is not adjusted for divergence from system time. Making this adjustment is better for timing stability. 5+ hours of stable audio without any buffering on my GV-USB2 where it used to add 21ms every 5 mintues or so. Fixes https://obsproject.com/mantis/view.php?id=1269 --- libobs/obs-audio.c | 1 + libobs/obs-source.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libobs/obs-audio.c b/libobs/obs-audio.c index f019f3cd1..c27237ede 100644 --- a/libobs/obs-audio.c +++ b/libobs/obs-audio.c @@ -211,6 +211,7 @@ static inline void discard_audio(struct obs_core_audio *audio, if (is_audio_source) blog(LOG_DEBUG, "can't discard, data still pending"); #endif + source->audio_ts = ts->end; return; } diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 34bb24671..87a061005 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -1267,8 +1267,11 @@ static void source_output_audio_data(obs_source_t *source, if (diff > MAX_TS_VAR && !using_direct_ts) handle_ts_jump(source, source->next_audio_ts_min, in.timestamp, diff, os_time); - else if (diff < TS_SMOOTHING_THRESHOLD) + else if (diff < TS_SMOOTHING_THRESHOLD) { + if (source->async_unbuffered && source->async_decoupled) + source->timing_adjust = os_time - in.timestamp; in.timestamp = source->next_audio_ts_min; + } } source->last_audio_ts = in.timestamp;