Improve multi instance support for osx desktop capture
Fixes behavior with multiple desktop captures in the same scene Also create the dispatch_queue without a name to prevent name collisions
This commit is contained in:
@@ -13,8 +13,13 @@ extern "C" {
|
||||
struct desktop_tex {
|
||||
samplerstate_t sampler;
|
||||
effect_t whatever;
|
||||
|
||||
CGDisplayStreamRef disp;
|
||||
uint32_t width, height;
|
||||
|
||||
texture_t tex;
|
||||
pthread_mutex_t mutex;
|
||||
IOSurfaceRef current, prev;
|
||||
};
|
||||
|
||||
EXPORT const char *osx_desktop_test_getname(const char *locale);
|
||||
|
@@ -20,7 +20,8 @@ static IOSurfaceRef current = NULL,
|
||||
static texture_t tex = NULL;
|
||||
static pthread_mutex_t c_mutex;
|
||||
|
||||
struct desktop_tex *osx_desktop_test_create(const char *settings, obs_source_t source)
|
||||
struct desktop_tex *osx_desktop_test_create(const char *settings,
|
||||
obs_source_t source)
|
||||
{
|
||||
struct desktop_tex *rt = bmalloc(sizeof(struct desktop_tex));
|
||||
char *effect_file;
|
||||
@@ -59,9 +60,7 @@ struct desktop_tex *osx_desktop_test_create(const char *settings, obs_source_t s
|
||||
rt->width = frame.size.width;
|
||||
rt->height = frame.size.height;
|
||||
|
||||
printf("%u %u\n", rt->width, rt->height);
|
||||
|
||||
pthread_mutex_init(&c_mutex, NULL);
|
||||
pthread_mutex_init(&rt->mutex, NULL);
|
||||
|
||||
NSDictionary *dict = @{
|
||||
(__bridge NSString*)kCGDisplayStreamSourceRect:
|
||||
@@ -73,25 +72,25 @@ struct desktop_tex *osx_desktop_test_create(const char *settings, obs_source_t s
|
||||
rt->disp = CGDisplayStreamCreateWithDispatchQueue(CGMainDisplayID(),
|
||||
rt->width, rt->height, 'BGRA',
|
||||
(__bridge CFDictionaryRef)dict,
|
||||
dispatch_queue_create("dispstream", NULL),
|
||||
dispatch_queue_create(NULL, NULL),
|
||||
^(CGDisplayStreamFrameStatus status, uint64_t
|
||||
displayTime, IOSurfaceRef frameSurface,
|
||||
CGDisplayStreamUpdateRef updateRef)
|
||||
{
|
||||
if (!frameSurface ||
|
||||
pthread_mutex_trylock(&c_mutex))
|
||||
pthread_mutex_trylock(&rt->mutex))
|
||||
return;
|
||||
|
||||
if (current) {
|
||||
IOSurfaceDecrementUseCount(current);
|
||||
CFRelease(current);
|
||||
current = NULL;
|
||||
if (rt->current) {
|
||||
IOSurfaceDecrementUseCount(rt->current);
|
||||
CFRelease(rt->current);
|
||||
rt->current = NULL;
|
||||
}
|
||||
|
||||
current = frameSurface;
|
||||
CFRetain(current);
|
||||
IOSurfaceIncrementUseCount(current);
|
||||
pthread_mutex_unlock(&c_mutex);
|
||||
rt->current = frameSurface;
|
||||
CFRetain(rt->current);
|
||||
IOSurfaceIncrementUseCount(rt->current);
|
||||
pthread_mutex_unlock(&rt->mutex);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -108,23 +107,23 @@ struct desktop_tex *osx_desktop_test_create(const char *settings, obs_source_t s
|
||||
void osx_desktop_test_destroy(struct desktop_tex *rt)
|
||||
{
|
||||
if (rt) {
|
||||
pthread_mutex_lock(&c_mutex);
|
||||
pthread_mutex_lock(&rt->mutex);
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
if (current) {
|
||||
IOSurfaceDecrementUseCount(current);
|
||||
CFRelease(current);
|
||||
IOSurfaceDecrementUseCount(rt->current);
|
||||
CFRelease(rt->current);
|
||||
}
|
||||
if (rt->sampler)
|
||||
samplerstate_destroy(rt->sampler);
|
||||
if (tex)
|
||||
texture_destroy(tex);
|
||||
texture_destroy(rt->tex);
|
||||
CGDisplayStreamStop(rt->disp);
|
||||
effect_destroy(rt->whatever);
|
||||
bfree(rt);
|
||||
|
||||
gs_leavecontext();
|
||||
pthread_mutex_unlock(&c_mutex);
|
||||
pthread_mutex_unlock(&rt->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,32 +135,33 @@ uint32_t osx_desktop_test_get_output_flags(struct desktop_tex *rt)
|
||||
void osx_desktop_test_video_render(struct desktop_tex *rt,
|
||||
obs_source_t filter_target)
|
||||
{
|
||||
pthread_mutex_lock(&c_mutex);
|
||||
pthread_mutex_lock(&rt->mutex);
|
||||
|
||||
if (prev != current) {
|
||||
if (rt->prev != rt->current) {
|
||||
if (tex)
|
||||
texture_rebind_iosurface(tex, current);
|
||||
texture_rebind_iosurface(rt->tex, rt->current);
|
||||
else
|
||||
tex = gs_create_texture_from_iosurface(current);
|
||||
prev = current;
|
||||
rt->tex = gs_create_texture_from_iosurface(
|
||||
rt->current);
|
||||
rt->prev = rt->current;
|
||||
}
|
||||
|
||||
if (!tex) goto fail;
|
||||
if (!rt->tex) goto fail;
|
||||
|
||||
gs_load_samplerstate(rt->sampler, 0);
|
||||
technique_t tech = effect_gettechnique(rt->whatever, "Default");
|
||||
effect_settexture(rt->whatever, effect_getparambyidx(rt->whatever, 1),
|
||||
tex);
|
||||
rt->tex);
|
||||
technique_begin(tech);
|
||||
technique_beginpass(tech, 0);
|
||||
|
||||
gs_draw_sprite(tex, 0, 0, 0);
|
||||
gs_draw_sprite(rt->tex, 0, 0, 0);
|
||||
|
||||
technique_endpass(tech);
|
||||
technique_end(tech);
|
||||
|
||||
fail:
|
||||
pthread_mutex_unlock(&c_mutex);
|
||||
pthread_mutex_unlock(&rt->mutex);
|
||||
}
|
||||
|
||||
uint32_t osx_desktop_test_getwidth(struct desktop_tex *rt)
|
||||
|
Reference in New Issue
Block a user