提交 ae3cecf0 编写于 作者: J jp9000

make data access in the threads a bit more safe (note: probably will need some...

make data access in the threads a bit more safe (note: probably will need some more safety measures later on)
上级 ebbf4175
...@@ -110,11 +110,10 @@ int gs_create(graphics_t *pgraphics, const char *module, ...@@ -110,11 +110,10 @@ int gs_create(graphics_t *pgraphics, const char *module,
struct gs_init_data *data) struct gs_init_data *data)
{ {
int errcode = GS_ERROR_FAIL; int errcode = GS_ERROR_FAIL;
pthread_mutex_t mutex_init = PTHREAD_MUTEX_INITIALIZER;
graphics_t graphics = bmalloc(sizeof(struct graphics_subsystem)); graphics_t graphics = bmalloc(sizeof(struct graphics_subsystem));
memset(graphics, 0, 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); graphics->module = os_dlopen(module);
if (!graphics->module) { if (!graphics->module) {
......
...@@ -62,17 +62,18 @@ struct obs_data { ...@@ -62,17 +62,18 @@ struct obs_data {
/* TODO: sound output stuff */ /* TODO: sound output stuff */
/* media */ /* media */
media_t media; media_t media;
video_t video; video_t video;
audio_t audio; audio_t audio;
uint32_t output_width; uint32_t output_width;
uint32_t output_height; uint32_t output_height;
/* threading */ /* threading */
pthread_t video_thread; pthread_t video_thread;
pthread_mutex_t source_mutex;
bool thread_initialized; bool thread_initialized;
pthread_mutex_t source_list_mutex;
pthread_mutex_t display_list_mutex;
obs_source_t primary_source; obs_source_t primary_source;
}; };
......
...@@ -84,7 +84,10 @@ void obs_source_init(struct obs_source *source) ...@@ -84,7 +84,10 @@ void obs_source_init(struct obs_source *source)
dstr_init(&source->settings); dstr_init(&source->settings);
da_init(source->filters); da_init(source->filters);
pthread_mutex_lock(&obs->source_list_mutex);
da_push_back(obs->sources, &source); 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, 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, ...@@ -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) void obs_source_destroy(obs_source_t source)
{ {
if (source) { if (source) {
da_free(source->filters); pthread_mutex_lock(&obs->source_list_mutex);
da_erase_item(obs->sources, &source); da_erase_item(obs->sources, &source);
pthread_mutex_unlock(&obs->source_list_mutex);
da_free(source->filters);
source->callbacks.destroy(source->data); source->callbacks.destroy(source->data);
dstr_free(&source->settings); dstr_free(&source->settings);
bfree(source); bfree(source);
......
...@@ -36,38 +36,17 @@ static void tick_sources(uint64_t cur_time, uint64_t *last_time) ...@@ -36,38 +36,17 @@ static void tick_sources(uint64_t cur_time, uint64_t *last_time)
*last_time = cur_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; struct vec4 clear_color;
vec4_set(&clear_color, 0.3f, 0.0f, 0.0f, 1.0f); uint32_t width, height;
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);
cx = gs_getwidth(); gs_load_swapchain(display ? display->swap : NULL);
cy = gs_getheight();
gs_getsize(&width, &height);
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_beginscene(); 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, gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH | GS_CLEAR_STENCIL,
&clear_color, 1.0f, 0); &clear_color, 1.0f, 0);
...@@ -75,10 +54,8 @@ static inline void render_displays(void) ...@@ -75,10 +54,8 @@ static inline void render_displays(void)
gs_enable_blending(false); gs_enable_blending(false);
gs_setcullmode(GS_NEITHER); gs_setcullmode(GS_NEITHER);
gs_ortho(0.0f, (float)obs->output_width, gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f);
0.0f, (float)obs->output_height, gs_setviewport(0, 0, width, height);
-100.0f, 100.0f);
gs_setviewport(0, 0, obs->output_width, obs->output_height);
if (obs->primary_source) if (obs->primary_source)
obs_source_video_render(obs->primary_source); obs_source_video_render(obs->primary_source);
...@@ -87,6 +64,23 @@ static inline void render_displays(void) ...@@ -87,6 +64,23 @@ static inline void render_displays(void)
gs_present(); 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) static bool swap_frame(uint64_t timestamp)
{ {
stagesurf_t last_surface = obs->copy_surfaces[obs->cur_texture]; stagesurf_t last_surface = obs->copy_surfaces[obs->cur_texture];
......
...@@ -64,7 +64,9 @@ static bool obs_init_media(struct video_info *vi, struct audio_info *ai) ...@@ -64,7 +64,9 @@ static bool obs_init_media(struct video_info *vi, struct audio_info *ai)
static bool obs_init_threading(void) 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; return false;
if (pthread_create(&obs->video_thread, NULL, obs_video_thread, if (pthread_create(&obs->video_thread, NULL, obs_video_thread,
obs) != 0) obs) != 0)
...@@ -78,12 +80,11 @@ static bool obs_init(const char *graphics_module, ...@@ -78,12 +80,11 @@ static bool obs_init(const char *graphics_module,
struct gs_init_data *graphics_data, struct gs_init_data *graphics_data,
struct video_info *vi, struct audio_info *ai) struct video_info *vi, struct audio_info *ai)
{ {
pthread_mutex_t pthread_init_val = PTHREAD_MUTEX_INITIALIZER;
obs = bmalloc(sizeof(struct obs_data)); obs = bmalloc(sizeof(struct obs_data));
memset(obs, 0, 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)) if (!obs_init_graphics(graphics_module, graphics_data, vi))
return false; return false;
...@@ -127,7 +128,8 @@ static inline void obs_free_threading(void) ...@@ -127,7 +128,8 @@ static inline void obs_free_threading(void)
video_output_stop(obs->video); video_output_stop(obs->video);
if (obs->thread_initialized) if (obs->thread_initialized)
pthread_join(obs->video_thread, &thread_ret); 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) static void obs_destroy(void)
......
...@@ -46,6 +46,13 @@ ...@@ -46,6 +46,13 @@
extern "C" { extern "C" {
#endif #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 { struct event_data {
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t cond; pthread_cond_t cond;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册