libobs: Add ability to use fixed audio buffering

This is in anticipation to adding low audio latency mode, will cause
audio buffering to be fixed rather than dynamically increasing. Having
fixed audio buffering means that audio latency always stays the same
rather than dynamically increasing.
This commit is contained in:
jp9000 2022-04-24 07:50:28 -07:00
parent 4b078b9296
commit e3bdb4ca7b
2 changed files with 69 additions and 4 deletions

View File

@ -292,6 +292,65 @@ static inline void discard_audio(struct obs_core_audio *audio,
source->audio_ts = ts->end;
}
static inline bool audio_buffering_maxed(struct obs_core_audio *audio)
{
return audio->total_buffering_ticks == MAX_BUFFERING_TICKS;
}
static void set_fixed_audio_buffering(struct obs_core_audio *audio,
size_t sample_rate, struct ts_info *ts)
{
struct ts_info new_ts;
size_t total_ms;
size_t ms;
int ticks;
if (audio_buffering_maxed(audio))
return;
if (!audio->buffering_wait_ticks)
audio->buffered_ts = ts->start;
ticks = MAX_BUFFERING_TICKS - audio->total_buffering_ticks;
audio->total_buffering_ticks += ticks;
ms = ticks * AUDIO_OUTPUT_FRAMES * 1000 / sample_rate;
total_ms = audio->total_buffering_ticks * AUDIO_OUTPUT_FRAMES * 1000 /
sample_rate;
blog(LOG_INFO,
"\n"
"enabling fixed audio buffering, total "
"audio buffering is now %d milliseconds"
"\n",
(int)total_ms);
new_ts.start =
audio->buffered_ts -
audio_frames_to_ns(sample_rate, audio->buffering_wait_ticks *
AUDIO_OUTPUT_FRAMES);
while (ticks--) {
const uint64_t cur_ticks = ++audio->buffering_wait_ticks;
new_ts.end = new_ts.start;
new_ts.start =
audio->buffered_ts -
audio_frames_to_ns(sample_rate,
cur_ticks * AUDIO_OUTPUT_FRAMES);
#if DEBUG_AUDIO == 1
blog(LOG_DEBUG, "add buffered ts: %" PRIu64 "-%" PRIu64,
new_ts.start, new_ts.end);
#endif
circlebuf_push_front(&audio->buffered_timestamps, &new_ts,
sizeof(new_ts));
}
*ts = new_ts;
}
static void add_audio_buffering(struct obs_core_audio *audio,
size_t sample_rate, struct ts_info *ts,
uint64_t min_ts, const char *buffering_name)
@ -303,7 +362,7 @@ static void add_audio_buffering(struct obs_core_audio *audio,
size_t ms;
int ticks;
if (audio->total_buffering_ticks == MAX_BUFFERING_TICKS)
if (audio_buffering_maxed(audio))
return;
if (!audio->buffering_wait_ticks)
@ -518,7 +577,7 @@ bool audio_callback(void *param, uint64_t start_ts_in, uint64_t end_ts_in,
/* if a source has gone backward in time and we can no
* longer buffer, drop some or all of its audio */
if (audio->total_buffering_ticks == MAX_BUFFERING_TICKS &&
if (audio_buffering_maxed(audio) &&
source->audio_ts < ts.start) {
if (source->info.audio_render) {
blog(LOG_DEBUG,
@ -556,10 +615,15 @@ bool audio_callback(void *param, uint64_t start_ts_in, uint64_t end_ts_in,
pthread_mutex_unlock(&data->audio_sources_mutex);
/* ------------------------------------------------ */
/* if a source has gone backward in time, buffer */
if (min_ts < ts.start)
/* if a source has gone backward in time, buffer */
if (audio->fixed_buffer) {
if (!audio_buffering_maxed(audio)) {
set_fixed_audio_buffering(audio, sample_rate, &ts);
}
} else if (min_ts < ts.start) {
add_audio_buffering(audio, sample_rate, &ts, min_ts,
buffering_name);
}
/* ------------------------------------------------ */
/* mix audio */

View File

@ -344,6 +344,7 @@ struct obs_core_audio {
struct circlebuf buffered_timestamps;
uint64_t buffering_wait_ticks;
int total_buffering_ticks;
bool fixed_buffer;
float user_volume;