Beispiel #1
0
static void add_audio_buffering(struct obs_core_audio *audio,
		size_t sample_rate, struct ts_info *ts, uint64_t min_ts)
{
	struct ts_info new_ts;
	uint64_t offset;
	uint64_t frames;
	int ticks;

	if (audio->total_buffering_ticks == MAX_BUFFERING_TICKS)
		return;

	if (!audio->buffering_wait_ticks)
		audio->buffered_ts = ts->start;

	offset = ts->start - min_ts;
	frames = ns_to_audio_frames(sample_rate, offset);
	ticks = (int)((frames + AUDIO_OUTPUT_FRAMES - 1) / AUDIO_OUTPUT_FRAMES);

	audio->total_buffering_ticks += ticks;

	if (audio->total_buffering_ticks >= MAX_BUFFERING_TICKS) {
		ticks -= audio->total_buffering_ticks - MAX_BUFFERING_TICKS;
		audio->total_buffering_ticks = MAX_BUFFERING_TICKS;
		blog(LOG_WARNING, "Max audio buffering reached!");
	}

	blog(LOG_INFO, "adding %d ticks of buffering, total buffering is "
			"now %d", ticks, audio->total_buffering_ticks);
#if DEBUG_AUDIO == 1
	blog(LOG_DEBUG, "min_ts (%"PRIu64") < start timestamp "
			"(%"PRIu64")", min_ts, ts->start);
	blog(LOG_DEBUG, "old buffered ts: %"PRIu64"-%"PRIu64,
			ts->start, ts->end);
#endif

	new_ts.start = audio->buffered_ts - audio_frames_to_ns(sample_rate,
			audio->buffering_wait_ticks * AUDIO_OUTPUT_FRAMES);

	while (ticks--) {
		int 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;
}
Beispiel #2
0
static void *audio_thread(void *param)
{
	struct audio_output *audio = param;
	size_t rate = audio->info.samples_per_sec;
	uint64_t samples = 0;
	uint64_t start_time = os_gettime_ns();
	uint64_t prev_time = start_time;
	uint64_t audio_time = prev_time;
	uint32_t audio_wait_time =
		(uint32_t)(audio_frames_to_ns(rate, AUDIO_OUTPUT_FRAMES) /
				1000000);

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

	const char *audio_thread_name =
		profile_store_name(obs_get_profiler_name_store(),
				"audio_thread(%s)", audio->info.name);

	while (os_event_try(audio->stop_event) == EAGAIN) {
		uint64_t cur_time;

		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;
		}

		profile_end(audio_thread_name);

		profile_reenable_thread();
	}

	return NULL;
}