|
@@ -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 */
|