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)master
parent
2a89306420
commit
4aa4858ac7
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue