libobs: Make scenes mix audio of sub-sources

Mark scenes as composite sources and use audio_render to mix and output
the audio of their sub-sources.
This commit is contained in:
jp9000 2015-12-17 07:31:05 -08:00
parent 40d6f986e6
commit 247a42c2a1

View file

@ -482,15 +482,91 @@ static uint32_t scene_getheight(void *data)
return obs->video.base_height;
}
static inline void mix_audio(float *p_out, float *p_in,
size_t pos, size_t count)
{
register float *out = p_out;
register float *in = p_in + pos;
register float *end = in + count;
while (in < end)
*(out++) += *(in++);
}
static bool scene_audio_render(void *data, uint64_t *ts_out,
struct obs_source_audio_mix *audio_output, uint32_t mixers,
size_t channels, size_t sample_rate)
{
uint64_t timestamp = 0;
struct obs_source_audio_mix child_audio;
struct obs_scene *scene = data;
struct obs_scene_item *item;
audio_lock(scene);
item = scene->first_item;
while (item) {
if (!obs_source_audio_pending(item->source)) {
uint64_t source_ts =
obs_source_get_audio_timestamp(item->source);
if (!timestamp || source_ts < timestamp)
timestamp = source_ts;
}
item = item->next;
}
if (!timestamp) {
audio_unlock(scene);
return false;
}
item = scene->first_item;
while (item) {
uint64_t source_ts;
size_t pos, count;
if (obs_source_audio_pending(item->source)) {
item = item->next;
continue;
}
source_ts = obs_source_get_audio_timestamp(item->source);
pos = (size_t)ns_to_audio_frames(sample_rate,
source_ts - timestamp);
count = AUDIO_OUTPUT_FRAMES - pos;
obs_source_get_audio_mix(item->source, &child_audio);
for (size_t mix = 0; mix < MAX_AUDIO_MIXES; mix++) {
for (size_t ch = 0; ch < channels; ch++) {
float *out = audio_output->output[mix].data[ch];
float *in = child_audio.output[mix].data[ch];
mix_audio(out, in, pos, count);
}
}
item = item->next;
}
*ts_out = timestamp;
audio_unlock(scene);
return true;
}
const struct obs_source_info scene_info =
{
.id = "scene",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW,
.output_flags = OBS_SOURCE_VIDEO |
OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_COMPOSITE,
.get_name = scene_getname,
.create = scene_create,
.destroy = scene_destroy,
.video_render = scene_video_render,
.audio_render = scene_audio_render,
.get_width = scene_getwidth,
.get_height = scene_getheight,
.load = scene_load,