提交 12e1855e 编写于 作者: F fryshorts

added linux test module with first implementation of a screengrabber using the...

added linux test module with first implementation of a screengrabber using the xshm extension for x11
上级 3aedfdfb
......@@ -8,3 +8,7 @@ endif()
if(APPLE AND UNIX)
add_subdirectory(osx)
endif()
if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
add_subdirectory(linux)
endif()
\ No newline at end of file
project(linux)
find_package(X11 REQUIRED)
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs")
#include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs-opengl")
set(linux_SOURCES
linux.c
xshm-input.c
)
set(linux_HEADERS
linux.h
xshm-input.h
)
add_library(linux MODULE
${linux_SOURCES}
${linux_HEADERS}
)
target_link_libraries(linux
libobs
${X11_LIBRARIES}
${X11_XShm_LIB}
)
install_obs_plugin(linux)
#obs_fixup_install_target(xshm-input PATH ${Libx264_LIBRARIES})
#include <obs.h>
#include "linux.h"
const char *inputs[] = {
"xshm_input"
};
uint32_t module_version(uint32_t in_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];
return true;
}
bool enum_filters(size_t idx, const char **name)
{
return false;
}
\ No newline at end of file
#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
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/XShm.h>
#include "xshm-input.h"
struct xshm_data {
Display *dpy;
Screen *screen;
Window root_window;
Visual *visual;
int depth;
uint32_t width, height;
int shm_attached;
XShmSegmentInfo shm_info;
XImage *image;
texture_t texture;
};
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)
{
// create data structure
struct xshm_data *data = bmalloc(sizeof(struct xshm_data));
memset(data, 0, sizeof(struct xshm_data));
// try to open display and all the good stuff
data->dpy = XOpenDisplay(NULL);
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);
// query for shm extension
if (!XShmQueryExtension(data->dpy))
goto fail;
// create xshm image
data->image = XShmCreateImage(data->dpy, data->visual, data->depth,
ZPixmap, NULL, &data->shm_info,
data->width, data->height);
if (!data->image)
goto fail;
printf("Image size: %dx%d\n", data->image->width, data->image->height);
// create shared memory
data->shm_info.shmid = shmget(IPC_PRIVATE, data->image->bytes_per_line *
data->image->height, IPC_CREAT | 0700);
if (data->shm_info.shmid < 0) {
printf("Failed to create shared memory !\n");
goto fail;
}
// attach shared memory
data->shm_info.shmaddr = data->image->data
= (char *) shmat(data->shm_info.shmid, 0, 0);
if (data->shm_info.shmaddr == (char *) -1) {
printf("Failed to attach shared memory !\n");
goto fail;
}
// set shared memory as read only
data->shm_info.readOnly = False;
// attach shm
if (!XShmAttach(data->dpy, &data->shm_info)) {
printf("Failed to attach to XShm !\n");
goto fail;
}
data->shm_attached = 1;
// get image
if (!XShmGetImage(data->dpy, data->root_window, data->image,
0, 0, AllPlanes)) {
printf("Failed to get image data !\n");
goto fail;
}
// create obs texture
gs_entercontext(obs_graphics());
data->texture = gs_create_texture(data->width, data->height, GS_BGRA, 1,
(const void**) &data->image->data,
GS_DYNAMIC);
gs_leavecontext();
if (!data->texture)
goto fail;
return data;
fail:
// clean up and return null
xshm_input_destroy(data);
return NULL;
}
void xshm_input_destroy(struct xshm_data *data)
{
if (data) {
gs_entercontext(obs_graphics());
texture_destroy(data->texture);
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
if (!XShmGetImage(data->dpy, data->root_window, data->image,
0, 0, AllPlanes)) {
printf("Failed to get image !\n");
}
texture_setimage(data->texture, (void *) data->image->data,
data->width * 4, False);
//effect_t effect = gs_geteffect();
//eparam_t diffuse = effect_getparambyname(effect, "diffuse");
//effect_settexture(effect, diffuse, data->texture);
gs_draw_sprite(data->texture, 0, 0, 0);
}
uint32_t xshm_input_getwidth(struct xshm_data *data)
{
return texture_getwidth(data->texture);
}
uint32_t xshm_input_getheight(struct xshm_data *data)
{
return texture_getheight(data->texture);
}
#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
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册