libobs: Fix audio issues with async video/audio looping

This fixes an age-old issue where audio samples could be lost or audio
could temporarily go out of sync in the case of looping videos.  When
audio/video data is looping, there's a window between when the audio
data resets its timestamp value and when the video data resets its
timestamp value.  This method simply pushes back the audio data while in
that window and does not modify sync, and when it detects that its out
of the loop window it simply forces a resync of the audio data in the
circular buffer.

This ensures that minimal audio data is lost in the loop process, and
minimizes the likelihood of any sort of sync issues associated with
looping.
master
jp9000 2016-01-16 10:45:49 -08:00
parent 41fa9c1bdb
commit ce0a189228
2 changed files with 28 additions and 4 deletions

View File

@ -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;

View File

@ -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;