Moved screen grabber code to _tick function
Moved the screen grabbing and texture generation to the _tick function in order to keep _render fast. Migrated xshm video source to the new plugin api.
This commit is contained in:
parent
820de55ae2
commit
c00d9e3b4e
@ -10,9 +10,7 @@ set(linux_SOURCES
|
||||
xshm-input.c
|
||||
)
|
||||
set(linux_HEADERS
|
||||
linux.h
|
||||
xcursor.h
|
||||
xshm-input.h
|
||||
)
|
||||
|
||||
add_library(linux MODULE
|
||||
|
@ -1,25 +1,11 @@
|
||||
#include <obs.h>
|
||||
#include "linux.h"
|
||||
#include <obs-module.h>
|
||||
|
||||
const char *inputs[] = {
|
||||
"xshm_input"
|
||||
};
|
||||
OBS_DECLARE_MODULE()
|
||||
|
||||
uint32_t module_version(uint32_t in_version)
|
||||
extern struct obs_source_info xshm_input;
|
||||
|
||||
bool obs_module_load(uint32_t obs_version)
|
||||
{
|
||||
return LIBOBS_API_VER;
|
||||
}
|
||||
|
||||
bool enum_inputs(size_t idx, const char **name)
|
||||
{
|
||||
if (idx >= (sizeof(inputs)/sizeof(const char*)))
|
||||
return false;
|
||||
|
||||
*name = inputs[idx];
|
||||
obs_register_source(&xshm_input);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool enum_filters(size_t idx, const char **name)
|
||||
{
|
||||
return false;
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <util/c99defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
EXPORT uint32_t module_version(uint32_t in_version);
|
||||
EXPORT bool enum_inputs(size_t idx, const char **name);
|
||||
EXPORT bool enum_filters(size_t idx, const char **name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -50,6 +50,9 @@ xcursor_t *xcursor_init(Display *dpy) {
|
||||
|
||||
data->dpy = dpy;
|
||||
|
||||
// initialize texture so we don't crash
|
||||
xcursor_tick(data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -59,7 +62,7 @@ void xcursor_destroy(xcursor_t *data) {
|
||||
bfree(data);
|
||||
}
|
||||
|
||||
void xcursor_render(xcursor_t *data) {
|
||||
void xcursor_tick(xcursor_t *data) {
|
||||
// get cursor data
|
||||
XFixesCursorImage *xc = XFixesGetCursorImage(data->dpy);
|
||||
|
||||
@ -67,6 +70,14 @@ void xcursor_render(xcursor_t *data) {
|
||||
if (!data->tex || data->last_serial != xc->cursor_serial)
|
||||
xcursor_create(data, xc);
|
||||
|
||||
// update cursor position
|
||||
data->pos_x = -1.0 * (xc->x - xc->xhot);
|
||||
data->pos_y = -1.0 * (xc->y - xc->yhot);
|
||||
|
||||
XFree(xc);
|
||||
}
|
||||
|
||||
void xcursor_render(xcursor_t *data) {
|
||||
// TODO: why do i need effects ?
|
||||
effect_t effect = gs_geteffect();
|
||||
eparam_t diffuse = effect_getparambyname(effect, "diffuse");
|
||||
@ -77,8 +88,8 @@ void xcursor_render(xcursor_t *data) {
|
||||
|
||||
// move cursor to the right position
|
||||
gs_matrix_translate3f(
|
||||
-1.0 * (xc->x - xc->xhot),
|
||||
-1.0 * (xc->y - xc->yhot),
|
||||
data->pos_x,
|
||||
data->pos_y,
|
||||
0
|
||||
);
|
||||
|
||||
@ -89,6 +100,4 @@ void xcursor_render(xcursor_t *data) {
|
||||
gs_enable_blending(False);
|
||||
|
||||
gs_matrix_pop();
|
||||
|
||||
XFree(xc);
|
||||
}
|
@ -8,14 +8,18 @@ extern "C" {
|
||||
|
||||
typedef struct {
|
||||
Display *dpy;
|
||||
float pos_x;
|
||||
float pos_y;
|
||||
unsigned long last_serial;
|
||||
short unsigned int last_width;
|
||||
short unsigned int last_height;
|
||||
unsigned short int last_width;
|
||||
unsigned short int last_height;
|
||||
texture_t tex;
|
||||
} xcursor_t;
|
||||
|
||||
/**
|
||||
* Initializes the xcursor object
|
||||
*
|
||||
* This needs to be executed within a valid render context
|
||||
*/
|
||||
xcursor_t *xcursor_init(Display *dpy);
|
||||
|
||||
@ -24,6 +28,13 @@ xcursor_t *xcursor_init(Display *dpy);
|
||||
*/
|
||||
void xcursor_destroy(xcursor_t *data);
|
||||
|
||||
/**
|
||||
* Update the cursor texture
|
||||
*
|
||||
* This needs to be executed within a valid render context
|
||||
*/
|
||||
void xcursor_tick(xcursor_t *data);
|
||||
|
||||
/**
|
||||
* Draw the cursor
|
||||
*
|
||||
|
@ -4,15 +4,14 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include <obs.h>
|
||||
#include "xcursor.h"
|
||||
#include "xshm-input.h"
|
||||
|
||||
#define XSHM_DATA(voidptr) struct xshm_data *data = voidptr;
|
||||
|
||||
struct xshm_data {
|
||||
Display *dpy;
|
||||
Screen *screen;
|
||||
Window root_window;
|
||||
Visual *visual;
|
||||
int depth;
|
||||
uint32_t width, height;
|
||||
int shm_attached;
|
||||
XShmSegmentInfo shm_info;
|
||||
@ -21,12 +20,50 @@ struct xshm_data {
|
||||
xcursor_t *cursor;
|
||||
};
|
||||
|
||||
const char* xshm_input_getname(const char* locale)
|
||||
static const char* xshm_input_getname(const char* locale)
|
||||
{
|
||||
return "X11 Shared Memory Screen Input";
|
||||
}
|
||||
|
||||
struct xshm_data *xshm_input_create(const char *settings, obs_source_t source)
|
||||
static void xshm_input_destroy(void *vptr)
|
||||
{
|
||||
XSHM_DATA(vptr);
|
||||
|
||||
if (data) {
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
texture_destroy(data->texture);
|
||||
xcursor_destroy(data->cursor);
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
// detach xshm
|
||||
if (data->shm_attached)
|
||||
XShmDetach(data->dpy, &data->shm_info);
|
||||
|
||||
// detach shared memory
|
||||
if (data->shm_info.shmaddr != (char *) -1) {
|
||||
shmdt(data->shm_info.shmaddr);
|
||||
data->shm_info.shmaddr = (char *) -1;
|
||||
}
|
||||
|
||||
// remove shared memory
|
||||
if (data->shm_info.shmid != -1)
|
||||
shmctl(data->shm_info.shmid, IPC_RMID, NULL);
|
||||
|
||||
// destroy image
|
||||
if (data->image)
|
||||
XDestroyImage(data->image);
|
||||
|
||||
// close display
|
||||
if (data->dpy)
|
||||
XCloseDisplay(data->dpy);
|
||||
|
||||
bfree(data);
|
||||
}
|
||||
}
|
||||
|
||||
static void *xshm_input_create(obs_data_t settings, obs_source_t source)
|
||||
{
|
||||
// create data structure
|
||||
struct xshm_data *data = bmalloc(sizeof(struct xshm_data));
|
||||
@ -37,19 +74,19 @@ struct xshm_data *xshm_input_create(const char *settings, obs_source_t source)
|
||||
if (!data->dpy)
|
||||
goto fail;
|
||||
|
||||
data->screen = XDefaultScreenOfDisplay(data->dpy);
|
||||
data->width = WidthOfScreen(data->screen);
|
||||
data->height = HeightOfScreen(data->screen);
|
||||
data->root_window = XRootWindowOfScreen(data->screen);
|
||||
data->visual = DefaultVisualOfScreen(data->screen);
|
||||
data->depth = DefaultDepthOfScreen(data->screen);
|
||||
Screen *screen = XDefaultScreenOfDisplay(data->dpy);
|
||||
data->width = WidthOfScreen(screen);
|
||||
data->height = HeightOfScreen(screen);
|
||||
data->root_window = XRootWindowOfScreen(screen);
|
||||
Visual *visual = DefaultVisualOfScreen(screen);
|
||||
int depth = DefaultDepthOfScreen(screen);
|
||||
|
||||
// query for shm extension
|
||||
if (!XShmQueryExtension(data->dpy))
|
||||
goto fail;
|
||||
|
||||
// create xshm image
|
||||
data->image = XShmCreateImage(data->dpy, data->visual, data->depth,
|
||||
data->image = XShmCreateImage(data->dpy, visual, depth,
|
||||
ZPixmap, NULL, &data->shm_info,
|
||||
data->width, data->height);
|
||||
if (!data->image)
|
||||
@ -98,70 +135,59 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xshm_input_destroy(struct xshm_data *data)
|
||||
static void xshm_input_video_tick(void *vptr, float seconds)
|
||||
{
|
||||
if (data) {
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
texture_destroy(data->texture);
|
||||
xcursor_destroy(data->cursor);
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
// detach xshm
|
||||
if (data->shm_attached)
|
||||
XShmDetach(data->dpy, &data->shm_info);
|
||||
|
||||
// detach shared memory
|
||||
if (data->shm_info.shmaddr != (char *) -1) {
|
||||
shmdt(data->shm_info.shmaddr);
|
||||
data->shm_info.shmaddr = (char *) -1;
|
||||
}
|
||||
|
||||
// remove shared memory
|
||||
if (data->shm_info.shmid != -1)
|
||||
shmctl(data->shm_info.shmid, IPC_RMID, NULL);
|
||||
|
||||
// destroy image
|
||||
if (data->image)
|
||||
XDestroyImage(data->image);
|
||||
|
||||
// close display
|
||||
if (data->dpy)
|
||||
XCloseDisplay(data->dpy);
|
||||
|
||||
bfree(data);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t xshm_input_get_output_flags(struct xshm_data *data)
|
||||
{
|
||||
return SOURCE_VIDEO | SOURCE_DEFAULT_EFFECT;
|
||||
}
|
||||
|
||||
void xshm_input_video_render(struct xshm_data *data, obs_source_t filter_target)
|
||||
{
|
||||
// update texture
|
||||
XSHM_DATA(vptr);
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
// update screen texture
|
||||
XShmGetImage(data->dpy, data->root_window, data->image, 0, 0, AllPlanes);
|
||||
texture_setimage(data->texture, (void *) data->image->data,
|
||||
data->width * 4, False);
|
||||
|
||||
effect_t effect = gs_geteffect();
|
||||
eparam_t diffuse = effect_getparambyname(effect, "diffuse");
|
||||
// update mouse cursor
|
||||
xcursor_tick(data->cursor);
|
||||
|
||||
gs_leavecontext();
|
||||
}
|
||||
|
||||
static void xshm_input_video_render(void *vptr, effect_t effect)
|
||||
{
|
||||
XSHM_DATA(vptr);
|
||||
|
||||
eparam_t diffuse = effect_getparambyname(effect, "diffuse");
|
||||
effect_settexture(effect, diffuse, data->texture);
|
||||
|
||||
gs_draw_sprite(data->texture, 0, 0, 0);
|
||||
|
||||
// render the cursor
|
||||
xcursor_render(data->cursor);
|
||||
}
|
||||
|
||||
uint32_t xshm_input_getwidth(struct xshm_data *data)
|
||||
static uint32_t xshm_input_getwidth(void *vptr)
|
||||
{
|
||||
XSHM_DATA(vptr);
|
||||
|
||||
return texture_getwidth(data->texture);
|
||||
}
|
||||
|
||||
uint32_t xshm_input_getheight(struct xshm_data *data)
|
||||
static uint32_t xshm_input_getheight(void *vptr)
|
||||
{
|
||||
XSHM_DATA(vptr);
|
||||
|
||||
return texture_getheight(data->texture);
|
||||
}
|
||||
|
||||
struct obs_source_info xshm_input = {
|
||||
.id = "xshm_input",
|
||||
.type = OBS_SOURCE_TYPE_INPUT,
|
||||
.output_flags = OBS_SOURCE_VIDEO,
|
||||
.getname = xshm_input_getname,
|
||||
.create = xshm_input_create,
|
||||
.destroy = xshm_input_destroy,
|
||||
.video_tick = xshm_input_video_tick,
|
||||
.video_render = xshm_input_video_render,
|
||||
.getwidth = xshm_input_getwidth,
|
||||
.getheight = xshm_input_getheight
|
||||
};
|
||||
|
@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <obs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// forward declare struct, so we don't have to include X11 headers here
|
||||
struct xshm_data;
|
||||
|
||||
EXPORT const char *xshm_input_getname(const char *locale);
|
||||
|
||||
EXPORT struct xshm_data *xshm_input_create(const char *settings,
|
||||
obs_source_t source);
|
||||
EXPORT void xshm_input_destroy(struct xshm_data *data);
|
||||
EXPORT uint32_t xshm_input_get_output_flags(struct xshm_data *data);
|
||||
|
||||
EXPORT void xshm_input_video_render(struct xshm_data *data,
|
||||
obs_source_t filter_target);
|
||||
|
||||
EXPORT uint32_t xshm_input_getwidth(struct xshm_data *data);
|
||||
EXPORT uint32_t xshm_input_getheight(struct xshm_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user