From cb4595e512ca68526c7b44b73ef6d2708c8ab96a Mon Sep 17 00:00:00 2001 From: Palana Date: Sun, 11 May 2014 21:43:32 +0200 Subject: [PATCH] Reduce lock holding time for display stream and guarantee update With the previous locking strategy some display captures would sometimes not process multiple frames in a row if multiple display captures were active --- test/test-input/test-desktop.m | 61 ++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/test/test-input/test-desktop.m b/test/test-input/test-desktop.m index 2a1669eee..883ad9715 100644 --- a/test/test-input/test-desktop.m +++ b/test/test-input/test-desktop.m @@ -89,19 +89,20 @@ static inline void display_stream_update(struct display_capture *dc, return; } - if (!frame_surface || pthread_mutex_trylock(&dc->mutex)) - return; + IOSurfaceRef prev_current = NULL; - if (dc->current) { - IOSurfaceDecrementUseCount(dc->current); - CFRelease(dc->current); - dc->current = NULL; + if (frame_surface && !pthread_mutex_lock(&dc->mutex)) { + prev_current = dc->current; + dc->current = frame_surface; + CFRetain(dc->current); + IOSurfaceIncrementUseCount(dc->current); + pthread_mutex_unlock(&dc->mutex); } - dc->current = frame_surface; - CFRetain(dc->current); - IOSurfaceIncrementUseCount(dc->current); - pthread_mutex_unlock(&dc->mutex); + if (prev_current) { + IOSurfaceDecrementUseCount(prev_current); + CFRelease(prev_current); + } } static bool init_display_stream(struct display_capture *dc) @@ -200,26 +201,30 @@ static void display_capture_video_tick(void *data, float seconds) struct display_capture *dc = data; - pthread_mutex_lock(&dc->mutex); - - if (dc->current && dc->prev != dc->current) { - gs_entercontext(obs_graphics()); - if (dc->tex) - texture_rebind_iosurface(dc->tex, dc->current); - else - dc->tex = gs_create_texture_from_iosurface( - dc->current); - gs_leavecontext(); - - if (dc->prev) { - IOSurfaceDecrementUseCount(dc->prev); - CFRelease(dc->prev); - } - dc->prev = dc->current; - dc->current = NULL; - } + if (!dc->current) + return; + IOSurfaceRef prev_prev = dc->prev; + if (pthread_mutex_lock(&dc->mutex)) + return; + dc->prev = dc->current; + dc->current = NULL; pthread_mutex_unlock(&dc->mutex); + + if (prev_prev == dc->prev) + return; + + gs_entercontext(obs_graphics()); + if (dc->tex) + texture_rebind_iosurface(dc->tex, dc->prev); + else + dc->tex = gs_create_texture_from_iosurface(dc->prev); + gs_leavecontext(); + + if (prev_prev) { + IOSurfaceDecrementUseCount(prev_prev); + CFRelease(prev_prev); + } } static void display_capture_video_render(void *data, effect_t effect)