From 4aa4858ac7f84e08a63b9e37625332f122512ab9 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Fri, 10 Jan 2014 19:03:21 -0700 Subject: [PATCH] Account for thread pauses for audio data - In the audio I/O code, if there's a pause in the program or its threads (especially the audio thread), it'll cause it to sample too much data, and increase line->base_timestamp to a potentially higher value than the next audio timestamp that may be added to the line. This would cause it to crash originally, because it expects audio data that is within the designated buffering limit. Because that audio data cannot be filled by that data anyway, just ignore the audio data until it goes back to the right timing (which it will as long as the code that is using the line accounts for its current system time) --- libobs/media-io/audio-io.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/libobs/media-io/audio-io.c b/libobs/media-io/audio-io.c index 3f6a6cfc6..495a1bb62 100644 --- a/libobs/media-io/audio-io.c +++ b/libobs/media-io/audio-io.c @@ -403,7 +403,7 @@ static inline void mul_vol_float(struct audio_line *line, float volume, vals[i] *= volume; } -static void audio_line_place_data(struct audio_line *line, +static void audio_line_place_data_pos(struct audio_line *line, const struct audio_data *data, size_t position) { size_t total_num = data->frames * line->audio->channels; @@ -432,6 +432,15 @@ static void audio_line_place_data(struct audio_line *line, total_size); } +static inline void audio_line_place_data(struct audio_line *line, + const struct audio_data *data) +{ + uint64_t time_offset = data->timestamp - line->base_timestamp; + size_t pos = convert_to_sample_offset(line->audio, time_offset); + + audio_line_place_data_pos(line, data, pos); +} + void audio_line_output(audio_line_t line, const struct audio_data *data) { /* TODO: prevent insertation of data too far away from expected @@ -442,12 +451,19 @@ void audio_line_output(audio_line_t line, const struct audio_data *data) if (!line->buffer.size) { line->base_timestamp = data->timestamp; - audio_line_place_data(line, data, 0); + audio_line_place_data_pos(line, data, 0); } else { - uint64_t time_offset = data->timestamp - line->base_timestamp; - size_t pos = convert_to_sample_offset(line->audio, time_offset); - audio_line_place_data(line, data, pos); + if (line->base_timestamp <= data->timestamp) + audio_line_place_data(line, data); + else + blog(LOG_DEBUG, "Bad timestamp for audio line '%s', " + "data->timestamp: %llu, " + "line->base_timestamp: %llu. " + "This can sometimes happen when " + "there's a pause in the threads.", + line->name, data->timestamp, + line->base_timestamp); } pthread_mutex_unlock(&line->mutex);