libobs: Split scene mutex to improve performance

Splits the scene mutex in to an audio/video mutex to allow video/audio
thread to use the same data at the same time without locking on each
other.
master
jp9000 2015-12-17 07:26:40 -08:00
parent c1dd156db8
commit 40d6f986e6
2 changed files with 60 additions and 35 deletions

View File

@ -62,8 +62,14 @@ static void *scene_create(obs_data_t *settings, struct obs_source *source)
goto fail;
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
goto fail;
if (pthread_mutex_init(&scene->mutex, &attr) != 0) {
blog(LOG_ERROR, "scene_create: Couldn't initialize mutex");
if (pthread_mutex_init(&scene->audio_mutex, &attr) != 0) {
blog(LOG_ERROR, "scene_create: Couldn't initialize audio "
"mutex");
goto fail;
}
if (pthread_mutex_init(&scene->video_mutex, &attr) != 0) {
blog(LOG_ERROR, "scene_create: Couldn't initialize video "
"mutex");
goto fail;
}
@ -76,11 +82,28 @@ fail:
return NULL;
}
#define audio_lock(scene) pthread_mutex_lock(&scene->audio_mutex)
#define video_lock(scene) pthread_mutex_lock(&scene->video_mutex)
#define audio_unlock(scene) pthread_mutex_unlock(&scene->audio_mutex)
#define video_unlock(scene) pthread_mutex_unlock(&scene->video_mutex)
static inline void full_lock(struct obs_scene *scene)
{
video_lock(scene);
audio_lock(scene);
}
static inline void full_unlock(struct obs_scene *scene)
{
audio_unlock(scene);
video_unlock(scene);
}
static void remove_all_items(struct obs_scene *scene)
{
struct obs_scene_item *item;
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
item = scene->first_item;
@ -91,7 +114,7 @@ static void remove_all_items(struct obs_scene *scene)
obs_sceneitem_remove(del_item);
}
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
}
static void scene_destroy(void *data)
@ -99,7 +122,8 @@ static void scene_destroy(void *data)
struct obs_scene *scene = data;
remove_all_items(scene);
pthread_mutex_destroy(&scene->mutex);
pthread_mutex_destroy(&scene->video_mutex);
pthread_mutex_destroy(&scene->audio_mutex);
bfree(scene);
}
@ -109,12 +133,13 @@ static void scene_enum_sources(void *data,
{
struct obs_scene *scene = data;
struct obs_scene_item *item;
struct obs_scene_item *next;
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
item = scene->first_item;
while (item) {
struct obs_scene_item *next = item->next;
next = item->next;
obs_sceneitem_addref(item);
if (item->visible)
@ -124,7 +149,7 @@ static void scene_enum_sources(void *data,
item = next;
}
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
}
static inline void detach_sceneitem(struct obs_scene_item *item)
@ -304,8 +329,7 @@ static void scene_video_render(void *data, gs_effect_t *effect)
struct obs_scene *scene = data;
struct obs_scene_item *item;
pthread_mutex_lock(&scene->mutex);
video_lock(scene);
item = scene->first_item;
gs_blend_state_push();
@ -335,7 +359,7 @@ static void scene_video_render(void *data, gs_effect_t *effect)
gs_blend_state_pop();
pthread_mutex_unlock(&scene->mutex);
video_unlock(scene);
UNUSED_PARAMETER(effect);
}
@ -432,7 +456,7 @@ static void scene_save(void *data, obs_data_t *settings)
obs_data_array_t *array = obs_data_array_create();
struct obs_scene_item *item;
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
item = scene->first_item;
while (item) {
@ -440,7 +464,7 @@ static void scene_save(void *data, obs_data_t *settings)
item = item->next;
}
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
obs_data_set_array(settings, "items", array);
obs_data_array_release(array);
@ -487,7 +511,7 @@ obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name)
struct obs_scene *new_scene = obs_scene_create(name);
struct obs_scene_item *item = scene->first_item;
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
while (item) {
struct obs_source *source = item->source;
@ -517,7 +541,7 @@ obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name)
item = item->next;
}
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
return new_scene;
}
@ -554,7 +578,7 @@ obs_sceneitem_t *obs_scene_find_source(obs_scene_t *scene, const char *name)
if (!scene)
return NULL;
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
item = scene->first_item;
while (item) {
@ -564,7 +588,7 @@ obs_sceneitem_t *obs_scene_find_source(obs_scene_t *scene, const char *name)
item = item->next;
}
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
return item;
}
@ -578,7 +602,7 @@ void obs_scene_enum_items(obs_scene_t *scene,
if (!scene || !callback)
return;
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
item = scene->first_item;
while (item) {
@ -596,7 +620,7 @@ void obs_scene_enum_items(obs_scene_t *scene,
item = next;
}
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
}
static obs_sceneitem_t *sceneitem_get_ref(obs_sceneitem_t *si)
@ -707,7 +731,7 @@ obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source)
obs_source_addref(source);
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
last = scene->first_item;
if (!last) {
@ -720,7 +744,7 @@ obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source)
item->prev = last;
}
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
init_hotkeys(scene, item, obs_source_get_name(source));
@ -768,11 +792,11 @@ void obs_sceneitem_remove(obs_sceneitem_t *item)
scene = item->parent;
if (scene)
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
if (item->removed) {
if (scene)
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
return;
}
@ -786,7 +810,7 @@ void obs_sceneitem_remove(obs_sceneitem_t *item)
signal_item_remove(item);
detach_sceneitem(item);
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
obs_sceneitem_release(item);
}
@ -880,7 +904,7 @@ void obs_sceneitem_set_order(obs_sceneitem_t *item,
struct obs_scene *scene = item->parent;
obs_scene_addref(scene);
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
next = item->next;
prev = item->prev;
@ -910,7 +934,7 @@ void obs_sceneitem_set_order(obs_sceneitem_t *item,
signal_reorder(item);
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
obs_scene_release(scene);
}
@ -923,7 +947,7 @@ void obs_sceneitem_set_order_position(obs_sceneitem_t *item,
struct obs_scene_item *next;
obs_scene_addref(scene);
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
detach_sceneitem(item);
next = scene->first_item;
@ -942,7 +966,7 @@ void obs_sceneitem_set_order_position(obs_sceneitem_t *item,
signal_reorder(item);
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
obs_scene_release(scene);
}
@ -1129,12 +1153,12 @@ bool obs_scene_reorder_items(obs_scene_t *scene,
return false;
obs_scene_addref(scene);
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
bool order_matches = true;
if (!sceneitems_match(scene, item_order, item_order_size,
&order_matches) || order_matches) {
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
obs_scene_release(scene);
return false;
}
@ -1154,7 +1178,7 @@ bool obs_scene_reorder_items(obs_scene_t *scene,
signal_reorder(scene->first_item);
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
obs_scene_release(scene);
return true;
}
@ -1166,8 +1190,8 @@ void obs_scene_atomic_update(obs_scene_t *scene,
return;
obs_scene_addref(scene);
pthread_mutex_lock(&scene->mutex);
full_lock(scene);
func(data, scene);
pthread_mutex_unlock(&scene->mutex);
full_unlock(scene);
obs_scene_release(scene);
}

View File

@ -59,6 +59,7 @@ struct obs_scene_item {
struct obs_scene {
struct obs_source *source;
pthread_mutex_t mutex;
pthread_mutex_t video_mutex;
pthread_mutex_t audio_mutex;
struct obs_scene_item *first_item;
};