diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 78f731bbf..f4fe36be3 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -540,6 +540,7 @@ struct obs_source { bool audio_pending; bool user_muted; bool muted; + bool resync_audio_with_video; struct obs_source *next_audio_source; struct obs_source **prev_next_audio_source; uint64_t audio_ts; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index c5bf54148..78bed1e20 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -1143,11 +1143,34 @@ static void source_output_audio_data(obs_source_t *source, in.timestamp += source->timing_adjust; if (source->next_audio_sys_ts_min == in.timestamp) { - push_back = true; - } else { - diff = uint64_diff(source->next_audio_sys_ts_min, in.timestamp); - if (diff < TS_SMOOTHING_THRESHOLD) + if (source->resync_audio_with_video) + source->resync_audio_with_video = false; + else push_back = true; + + } else if (source->next_audio_sys_ts_min) { + diff = uint64_diff(source->next_audio_sys_ts_min, in.timestamp); + + if (diff < TS_SMOOTHING_THRESHOLD) { + if (source->resync_audio_with_video) + source->resync_audio_with_video = false; + else + push_back = true; + + /* This only happens if used with async video when audio/video + * start transitioning in to a timestamp jump. Audio will + * typically have a timestamp jump, and then video will have a + * timestamp jump. It's important to not just push back the + * next non-reset audio data after this happens, as that will + * be the video re-syncing. */ + } else if (in.timestamp < source->next_audio_sys_ts_min || + diff > MAX_TS_VAR) { + reset_audio_timing(source, data->timestamp, + source->next_audio_sys_ts_min); + push_back = true; + source->resync_audio_with_video = true; + in.timestamp = data->timestamp + source->timing_adjust; + } } sync_offset = source->sync_offset;