diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index d0c97f217cd6da29516c1165c0e86dcb5e280e7f..20c6cb2d517e9e178f0dbf8b63dd8b7ea17b2cca 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -110,11 +110,10 @@ int gs_create(graphics_t *pgraphics, const char *module, struct gs_init_data *data) { int errcode = GS_ERROR_FAIL; - pthread_mutex_t mutex_init = PTHREAD_MUTEX_INITIALIZER; graphics_t graphics = bmalloc(sizeof(struct graphics_subsystem)); memset(graphics, 0, sizeof(struct graphics_subsystem)); - graphics->mutex = mutex_init; + pthread_mutex_init_value(&graphics->mutex); graphics->module = os_dlopen(module); if (!graphics->module) { diff --git a/libobs/obs-data.h b/libobs/obs-data.h index 664cb4abec3c6907299f93b5010cc7307d7cc1ea..dd4497267aefd6cda8c679214ef01ca37e6647ba 100644 --- a/libobs/obs-data.h +++ b/libobs/obs-data.h @@ -62,17 +62,18 @@ struct obs_data { /* TODO: sound output stuff */ /* media */ - media_t media; - video_t video; - audio_t audio; + media_t media; + video_t video; + audio_t audio; uint32_t output_width; uint32_t output_height; /* threading */ pthread_t video_thread; - pthread_mutex_t source_mutex; bool thread_initialized; + pthread_mutex_t source_list_mutex; + pthread_mutex_t display_list_mutex; obs_source_t primary_source; }; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 4f6e67fd60ea3dc66bd20e5c4336c3cfe6f2c393..05bb5febebb89a225cc568603c49eb870808730c 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -84,7 +84,10 @@ void obs_source_init(struct obs_source *source) dstr_init(&source->settings); da_init(source->filters); + + pthread_mutex_lock(&obs->source_list_mutex); da_push_back(obs->sources, &source); + pthread_mutex_unlock(&obs->source_list_mutex); } obs_source_t obs_source_create(enum obs_source_type type, const char *name, @@ -125,9 +128,11 @@ obs_source_t obs_source_create(enum obs_source_type type, const char *name, void obs_source_destroy(obs_source_t source) { if (source) { - da_free(source->filters); + pthread_mutex_lock(&obs->source_list_mutex); da_erase_item(obs->sources, &source); + pthread_mutex_unlock(&obs->source_list_mutex); + da_free(source->filters); source->callbacks.destroy(source->data); dstr_free(&source->settings); bfree(source); diff --git a/libobs/obs-video.c b/libobs/obs-video.c index 38a1f0d448348d0faed55cec5877a52f58ddc631..3842bec8070e2d15acdd8933d904eb91a8630ff5 100644 --- a/libobs/obs-video.c +++ b/libobs/obs-video.c @@ -36,38 +36,17 @@ static void tick_sources(uint64_t cur_time, uint64_t *last_time) *last_time = cur_time; } -static inline void render_displays(void) +static inline void render_display(struct obs_display *display) { - size_t i; struct vec4 clear_color; - vec4_set(&clear_color, 0.3f, 0.0f, 0.0f, 1.0f); - - - for (i = 0; i < obs->displays.num; i++) { - uint32_t cx, cy; - obs_display_t display = obs->displays.array[i]; - - gs_load_swapchain(display->swap); + uint32_t width, height; - cx = gs_getwidth(); - cy = gs_getheight(); + gs_load_swapchain(display ? display->swap : NULL); - - gs_beginscene(); - gs_setviewport(0, 0, (int)cx, (int)cy); - gs_ortho(0.0f, (float)cx, 0.0f, (float)cy, -100.0f, 100.0f); - gs_setviewport(0, 0, obs->output_width, obs->output_height); - - if (display->source) - obs_source_video_render(display->source); - - gs_endscene(); - gs_present(); - } - - gs_load_swapchain(NULL); + gs_getsize(&width, &height); gs_beginscene(); + vec4_set(&clear_color, 0.3f, 0.0f, 0.0f, 1.0f); gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH | GS_CLEAR_STENCIL, &clear_color, 1.0f, 0); @@ -75,10 +54,8 @@ static inline void render_displays(void) gs_enable_blending(false); gs_setcullmode(GS_NEITHER); - gs_ortho(0.0f, (float)obs->output_width, - 0.0f, (float)obs->output_height, - -100.0f, 100.0f); - gs_setviewport(0, 0, obs->output_width, obs->output_height); + gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f); + gs_setviewport(0, 0, width, height); if (obs->primary_source) obs_source_video_render(obs->primary_source); @@ -87,6 +64,23 @@ static inline void render_displays(void) gs_present(); } +static inline void render_displays(void) +{ + size_t i; + + pthread_mutex_lock(&obs->display_list_mutex); + + for (i = 0; i < obs->displays.num; i++) { + struct obs_display *display = obs->displays.array[i]; + + render_display(display); + } + + pthread_mutex_unlock(&obs->display_list_mutex); + + render_display(NULL); +} + static bool swap_frame(uint64_t timestamp) { stagesurf_t last_surface = obs->copy_surfaces[obs->cur_texture]; diff --git a/libobs/obs.c b/libobs/obs.c index 0cb26038462424c46c63ef60cd1f3379db74cf76..851f9e7f5a49c41f8ddeb238c138a46f6970f6ba 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -64,7 +64,9 @@ static bool obs_init_media(struct video_info *vi, struct audio_info *ai) static bool obs_init_threading(void) { - if (pthread_mutex_init(&obs->source_mutex, NULL) != 0) + if (pthread_mutex_init(&obs->source_list_mutex, NULL) != 0) + return false; + if (pthread_mutex_init(&obs->display_list_mutex, NULL) != 0) return false; if (pthread_create(&obs->video_thread, NULL, obs_video_thread, obs) != 0) @@ -78,12 +80,11 @@ static bool obs_init(const char *graphics_module, struct gs_init_data *graphics_data, struct video_info *vi, struct audio_info *ai) { - pthread_mutex_t pthread_init_val = PTHREAD_MUTEX_INITIALIZER; - obs = bmalloc(sizeof(struct obs_data)); memset(obs, 0, sizeof(struct obs_data)); - obs->source_mutex = pthread_init_val; + pthread_mutex_init_value(&obs->source_list_mutex); + pthread_mutex_init_value(&obs->display_list_mutex); if (!obs_init_graphics(graphics_module, graphics_data, vi)) return false; @@ -127,7 +128,8 @@ static inline void obs_free_threading(void) video_output_stop(obs->video); if (obs->thread_initialized) pthread_join(obs->video_thread, &thread_ret); - pthread_mutex_destroy(&obs->source_mutex); + pthread_mutex_destroy(&obs->source_list_mutex); + pthread_mutex_destroy(&obs->display_list_mutex); } static void obs_destroy(void) diff --git a/libobs/util/threading.h b/libobs/util/threading.h index ae63a112b0436c0fc8590f267f100f515106e215..167b9f68364a8d80ea65eb26746df002510d97d0 100644 --- a/libobs/util/threading.h +++ b/libobs/util/threading.h @@ -46,6 +46,13 @@ extern "C" { #endif +/* this may seem strange, but you can't use it unless it's an initializer */ +static inline void pthread_mutex_init_value(pthread_mutex_t *mutex) +{ + pthread_mutex_t init_val = PTHREAD_MUTEX_INITIALIZER; + *mutex = init_val; +} + struct event_data { pthread_mutex_t mutex; pthread_cond_t cond;