Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions libobs/media-io/audio-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ static inline void clamp_audio_output(struct audio_output *audio, size_t bytes)
}
}

static void input_and_output(struct audio_output *audio, uint64_t audio_time,
static bool input_and_output(struct audio_output *audio, uint64_t audio_time,
uint64_t prev_time)
{
size_t bytes = AUDIO_OUTPUT_FRAMES * audio->block_size;
Expand Down Expand Up @@ -191,14 +191,16 @@ static void input_and_output(struct audio_output *audio, uint64_t audio_time,
success = audio->input_cb(audio->input_param, prev_time, audio_time,
&new_ts, active_mixes, data);
if (!success)
return;
return false;

/* clamps audio data to -1.0..1.0 */
clamp_audio_output(audio, bytes);

/* output */
for (size_t i = 0; i < MAX_AUDIO_MIXES; i++)
do_audio_output(audio, i, new_ts, AUDIO_OUTPUT_FRAMES);

return true;
}

static void *audio_thread(void *param)
Expand All @@ -217,6 +219,7 @@ static void *audio_thread(void *param)
uint32_t audio_wait_time =
(uint32_t)(audio_frames_to_ns(rate, AUDIO_OUTPUT_FRAMES) /
1000000);
int wait_cycles = 0;

os_set_thread_name("audio-io: audio thread");

Expand All @@ -227,18 +230,31 @@ static void *audio_thread(void *param)
while (os_event_try(audio->stop_event) == EAGAIN) {
uint64_t cur_time;

os_sleep_ms(audio_wait_time);
if (wait_cycles > 0) {
Copy link
Member

@PatTheMav PatTheMav Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand the purpose of these changes here:

  • At first the thread waits the normal amount of time and then calls input_and_output to check if the expected number of samples were provided by the audio source
  • If that is the case, the timestamps are updated and the thread continues as before
  • If that is not the case, the thread waits for half its usual cycle, then increments wait_cycles (should be 1 before the next iteration)
  • On the next iteration, the thread waits for half the cycle again, then decrements wait_cycles again (it should be 0 then).

As such it only seems to wait for half a circle to increment and decrement a single variable that otherwise has no impact on the code executed in the loop. Or am I missing something?

os_sleep_ms(audio_wait_time / 2);
wait_cycles--;
} else {
os_sleep_ms(audio_wait_time);
}

profile_start(audio_thread_name);

cur_time = os_gettime_ns();
while (audio_time <= cur_time) {
samples += AUDIO_OUTPUT_FRAMES;
audio_time =
start_time + audio_frames_to_ns(rate, samples);

input_and_output(audio, audio_time, prev_time);
prev_time = audio_time;
uint64_t new_samples = samples + AUDIO_OUTPUT_FRAMES;
uint64_t new_audio_time =
start_time +
audio_frames_to_ns(rate, new_samples);

if (input_and_output(audio, new_audio_time,
prev_time)) {
samples = new_samples;
audio_time = new_audio_time;
prev_time = audio_time;
} else {
os_sleep_ms(audio_wait_time / 2);
wait_cycles++;
}
}

profile_end(audio_thread_name);
Expand Down
6 changes: 5 additions & 1 deletion libobs/obs-audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ bool audio_callback(void *param, uint64_t start_ts_in, uint64_t end_ts_in,
struct ts_info ts = {start_ts_in, end_ts_in};
size_t audio_size;
uint64_t min_ts;
bool audio_pending = false;

da_resize(audio->render_order, 0);
da_resize(audio->root_nodes, 0);
Expand Down Expand Up @@ -516,6 +517,9 @@ bool audio_callback(void *param, uint64_t start_ts_in, uint64_t end_ts_in,
obs_source_audio_render(source, mixers, channels, sample_rate,
audio_size);

if (source->audio_pending && source->audio_ts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While chasing a different audio bug, I found that the changes in this file appear to negatively affect A-V sync for some jittery sources. Due to the nature of how difficult it is to reproduce this bug, I am unable to practically investigate any further.

audio_pending = true;

/* 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 &&
Expand Down Expand Up @@ -611,5 +615,5 @@ bool audio_callback(void *param, uint64_t start_ts_in, uint64_t end_ts_in,
execute_audio_tasks();

UNUSED_PARAMETER(param);
return true;
return !audio_pending;
}
2 changes: 1 addition & 1 deletion libobs/obs-source.c
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,7 @@ static void source_output_audio_data(obs_source_t *source,

source->last_audio_ts = in.timestamp;
source->next_audio_ts_min =
in.timestamp + conv_frames_to_time(sample_rate, in.frames);
data->timestamp + conv_frames_to_time(sample_rate, in.frames);

in.timestamp += source->timing_adjust;

Expand Down