mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-14 23:34:08 +00:00
libobs: Add ability to queue audio task
This is mostly framework for allowing the ability to wait for certain threads
This commit is contained in:
parent
e4f0c21252
commit
cf492ca271
|
@ -442,6 +442,23 @@ static inline void release_audio_sources(struct obs_core_audio *audio)
|
|||
obs_source_release(audio->render_order.array[i]);
|
||||
}
|
||||
|
||||
static inline void execute_audio_tasks(void)
|
||||
{
|
||||
struct obs_core_audio *audio = &obs->audio;
|
||||
bool tasks_remaining = true;
|
||||
|
||||
while (tasks_remaining) {
|
||||
pthread_mutex_lock(&audio->task_mutex);
|
||||
if (audio->tasks.size) {
|
||||
struct obs_task_info info;
|
||||
circlebuf_pop_front(&audio->tasks, &info, sizeof(info));
|
||||
info.task(info.param);
|
||||
}
|
||||
tasks_remaining = !!audio->tasks.size;
|
||||
pthread_mutex_unlock(&audio->task_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
bool audio_callback(void *param, uint64_t start_ts_in, uint64_t end_ts_in,
|
||||
uint64_t *out_ts, uint32_t mixers,
|
||||
struct audio_output_data *mixes)
|
||||
|
@ -591,6 +608,8 @@ bool audio_callback(void *param, uint64_t start_ts_in, uint64_t end_ts_in,
|
|||
return false;
|
||||
}
|
||||
|
||||
execute_audio_tasks();
|
||||
|
||||
UNUSED_PARAMETER(param);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -339,6 +339,9 @@ struct obs_core_audio {
|
|||
DARRAY(struct audio_monitor *) monitors;
|
||||
char *monitoring_device_name;
|
||||
char *monitoring_device_id;
|
||||
|
||||
pthread_mutex_t task_mutex;
|
||||
struct circlebuf tasks;
|
||||
};
|
||||
|
||||
/* user sources, output channels, and displays */
|
||||
|
|
34
libobs/obs.c
34
libobs/obs.c
|
@ -560,6 +560,8 @@ static void obs_free_graphics(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void set_audio_thread(void *unused);
|
||||
|
||||
static bool obs_init_audio(struct audio_output_info *ai)
|
||||
{
|
||||
struct obs_core_audio *audio = &obs->audio;
|
||||
|
@ -569,6 +571,11 @@ static bool obs_init_audio(struct audio_output_info *ai)
|
|||
|
||||
if (pthread_mutex_init_recursive(&audio->monitoring_mutex) != 0)
|
||||
return false;
|
||||
if (pthread_mutex_init(&audio->task_mutex, NULL) != 0)
|
||||
return false;
|
||||
|
||||
struct obs_task_info audio_init = {.task = set_audio_thread};
|
||||
circlebuf_push_back(&audio->tasks, &audio_init, sizeof(audio_init));
|
||||
|
||||
audio->user_volume = 1.0f;
|
||||
|
||||
|
@ -609,6 +616,8 @@ static void obs_free_audio(void)
|
|||
da_free(audio->monitors);
|
||||
bfree(audio->monitoring_device_name);
|
||||
bfree(audio->monitoring_device_id);
|
||||
circlebuf_free(&audio->tasks);
|
||||
pthread_mutex_destroy(&audio->task_mutex);
|
||||
pthread_mutex_destroy(&audio->monitoring_mutex);
|
||||
|
||||
memset(audio, 0, sizeof(struct obs_core_audio));
|
||||
|
@ -838,6 +847,7 @@ static bool obs_init(const char *locale, const char *module_config_path,
|
|||
obs = bzalloc(sizeof(struct obs_core));
|
||||
|
||||
pthread_mutex_init_value(&obs->audio.monitoring_mutex);
|
||||
pthread_mutex_init_value(&obs->audio.task_mutex);
|
||||
pthread_mutex_init_value(&obs->video.gpu_encoder_mutex);
|
||||
pthread_mutex_init_value(&obs->video.task_mutex);
|
||||
|
||||
|
@ -2511,11 +2521,19 @@ struct task_wait_info {
|
|||
static void task_wait_callback(void *param)
|
||||
{
|
||||
struct task_wait_info *info = param;
|
||||
info->task(info->param);
|
||||
if (info->task)
|
||||
info->task(info->param);
|
||||
os_event_signal(info->event);
|
||||
}
|
||||
|
||||
THREAD_LOCAL bool is_graphics_thread = false;
|
||||
THREAD_LOCAL bool is_audio_thread = false;
|
||||
|
||||
static void set_audio_thread(void *unused)
|
||||
{
|
||||
is_audio_thread = true;
|
||||
UNUSED_PARAMETER(unused);
|
||||
}
|
||||
|
||||
static bool in_task_thread(enum obs_task_type type)
|
||||
{
|
||||
|
@ -2523,6 +2541,8 @@ static bool in_task_thread(enum obs_task_type type)
|
|||
|
||||
if (type == OBS_TASK_GRAPHICS)
|
||||
return is_graphics_thread;
|
||||
else if (type == OBS_TASK_AUDIO)
|
||||
return is_audio_thread;
|
||||
|
||||
assert(false);
|
||||
return false;
|
||||
|
@ -2541,6 +2561,7 @@ void obs_queue_task(enum obs_task_type type, obs_task_t task, void *param,
|
|||
} else {
|
||||
if (in_task_thread(type)) {
|
||||
task(param);
|
||||
|
||||
} else if (wait) {
|
||||
struct task_wait_info info = {
|
||||
.task = task,
|
||||
|
@ -2551,13 +2572,22 @@ void obs_queue_task(enum obs_task_type type, obs_task_t task, void *param,
|
|||
obs_queue_task(type, task_wait_callback, &info, false);
|
||||
os_event_wait(info.event);
|
||||
os_event_destroy(info.event);
|
||||
} else {
|
||||
|
||||
} else if (type == OBS_TASK_GRAPHICS) {
|
||||
struct obs_core_video *video = &obs->video;
|
||||
struct obs_task_info info = {task, param};
|
||||
|
||||
pthread_mutex_lock(&video->task_mutex);
|
||||
circlebuf_push_back(&video->tasks, &info, sizeof(info));
|
||||
pthread_mutex_unlock(&video->task_mutex);
|
||||
|
||||
} else if (type == OBS_TASK_AUDIO) {
|
||||
struct obs_core_audio *audio = &obs->audio;
|
||||
struct obs_task_info info = {task, param};
|
||||
|
||||
pthread_mutex_lock(&audio->task_mutex);
|
||||
circlebuf_push_back(&audio->tasks, &info, sizeof(info));
|
||||
pthread_mutex_unlock(&audio->task_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -796,6 +796,7 @@ typedef void (*obs_task_t)(void *param);
|
|||
enum obs_task_type {
|
||||
OBS_TASK_UI,
|
||||
OBS_TASK_GRAPHICS,
|
||||
OBS_TASK_AUDIO,
|
||||
};
|
||||
|
||||
EXPORT void obs_queue_task(enum obs_task_type type, obs_task_t task,
|
||||
|
|
Loading…
Reference in a new issue