mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-20 19:40:14 +00:00
Split screen capture module
Split screen capture modules into platform specific files (X11 and OS X).
This commit is contained in:
@@ -1668,9 +1668,14 @@ esac
|
||||
|
||||
if test $screen_cap = yes
|
||||
then
|
||||
AC_DEFINE([HAVE_SCREEN_CAP], [1], [Build with screen_capture])
|
||||
AC_DEFINE([HAVE_SCREEN_CAP], [1], [Build with screen capture])
|
||||
AC_SUBST(SCREEN_CAP_LIB_TARGET, "lib/ultragrid/vidcap_screen.so.$video_capture_abi_version")
|
||||
SCREEN_CAP_OBJ="src/video_capture/screen.o"
|
||||
if test $system = MacOSX; then
|
||||
SCREEN_CAP_OBJ="src/video_capture/screen_osx.o"
|
||||
else if test $system = Linux; then
|
||||
SCREEN_CAP_OBJ="src/video_capture/screen_x11.o"
|
||||
fi
|
||||
fi
|
||||
LIB_TARGETS="$LIB_TARGETS $SCREEN_CAP_LIB_TARGET"
|
||||
LIB_OBJS="$LIB_OBJS $SCREEN_CAP_OBJ"
|
||||
fi
|
||||
|
||||
@@ -75,7 +75,8 @@
|
||||
#include "video_capture/linsys.h"
|
||||
#include "video_capture/null.h"
|
||||
#include "video_capture/quicktime.h"
|
||||
#include "video_capture/screen.h"
|
||||
#include "video_capture/screen_osx.h"
|
||||
#include "video_capture/screen_x11.h"
|
||||
#include "video_capture/swmix.h"
|
||||
#include "video_capture/testcard.h"
|
||||
#include "video_capture/testcard2.h"
|
||||
@@ -217,10 +218,17 @@ struct vidcap_device_api vidcap_device_table[] = {
|
||||
/* The screen capture card */
|
||||
0,
|
||||
"screen",
|
||||
MK_NAME(vidcap_screen_probe),
|
||||
MK_NAME(vidcap_screen_init),
|
||||
MK_NAME(vidcap_screen_done),
|
||||
MK_NAME(vidcap_screen_grab),
|
||||
#ifdef HAVE_LINUX
|
||||
MK_NAME(vidcap_screen_x11_probe),
|
||||
MK_NAME(vidcap_screen_x11_init),
|
||||
MK_NAME(vidcap_screen_x11_done),
|
||||
MK_NAME(vidcap_screen_x11_grab),
|
||||
#else
|
||||
MK_NAME(vidcap_screen_osx_probe),
|
||||
MK_NAME(vidcap_screen_osx_init),
|
||||
MK_NAME(vidcap_screen_osx_done),
|
||||
MK_NAME(vidcap_screen_osx_grab),
|
||||
#endif // ! defined HAVE_LINUX
|
||||
NULL
|
||||
},
|
||||
#endif /* HAVE_SCREEN */
|
||||
|
||||
234
src/video_capture/screen_osx.c
Normal file
234
src/video_capture/screen_osx.c
Normal file
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
* @file screen_osx.c
|
||||
* @author Martin Pulec <pulec@cesnet.cz>
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2012-2013 CESNET, z.s.p.o.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of CESNET nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#include "config_unix.h"
|
||||
#include "config_win32.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "debug.h"
|
||||
#include "host.h"
|
||||
#include "video.h"
|
||||
#include "video_capture.h"
|
||||
|
||||
#include "tv.h"
|
||||
|
||||
#include "video_capture/screen_osx.h"
|
||||
#include "audio/audio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
/* prototypes of functions defined in this module */
|
||||
static void show_help(void);
|
||||
|
||||
static void show_help()
|
||||
{
|
||||
printf("Screen capture\n");
|
||||
printf("Usage\n");
|
||||
printf("\t-t screen[:fps=<fps>]\n");
|
||||
printf("\t\t<fps> - preferred grabbing fps (otherwise unlimited)\n");
|
||||
}
|
||||
|
||||
struct vidcap_screen_osx_state {
|
||||
struct video_frame *frame;
|
||||
struct tile *tile;
|
||||
int frames;
|
||||
struct timeval t, t0;
|
||||
CGDirectDisplayID display;
|
||||
|
||||
struct timeval prev_time;
|
||||
|
||||
double fps;
|
||||
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
static void initialize(struct vidcap_screen_osx_state *s) {
|
||||
s->frame = vf_alloc(1);
|
||||
s->tile = vf_get_tile(s->frame, 0);
|
||||
|
||||
s->display = CGMainDisplayID();
|
||||
CGImageRef image = CGDisplayCreateImage(s->display);
|
||||
|
||||
s->tile->width = CGImageGetWidth(image);
|
||||
s->tile->height = CGImageGetHeight(image);
|
||||
CFRelease(image);
|
||||
|
||||
s->frame->color_spec = RGBA;
|
||||
if(s->fps > 0.0) {
|
||||
s->frame->fps = s->fps;
|
||||
} else {
|
||||
s->frame->fps = 30;
|
||||
}
|
||||
s->frame->interlacing = PROGRESSIVE;
|
||||
s->tile->data_len = vc_get_linesize(s->tile->width, s->frame->color_spec) * s->tile->height;
|
||||
|
||||
s->tile->data = (char *) malloc(s->tile->data_len);
|
||||
|
||||
return;
|
||||
|
||||
goto error; // dummy use (otherwise compiler would complain about unreachable code (Mac)
|
||||
error:
|
||||
fprintf(stderr, "[Screen cap.] Initialization failed!\n");
|
||||
exit_uv(128);
|
||||
}
|
||||
|
||||
struct vidcap_type * vidcap_screen_osx_probe(void)
|
||||
{
|
||||
struct vidcap_type* vt;
|
||||
|
||||
vt = (struct vidcap_type *) malloc(sizeof(struct vidcap_type));
|
||||
if (vt != NULL) {
|
||||
vt->id = VIDCAP_SCREEN_ID;
|
||||
vt->name = "screen";
|
||||
vt->description = "Grabbing screen";
|
||||
}
|
||||
return vt;
|
||||
}
|
||||
|
||||
void * vidcap_screen_osx_init(const struct vidcap_params *params)
|
||||
{
|
||||
struct vidcap_screen_osx_state *s;
|
||||
|
||||
printf("vidcap_screen_init\n");
|
||||
|
||||
s = (struct vidcap_screen_osx_state *) malloc(sizeof(struct vidcap_screen_osx_state));
|
||||
if(s == NULL) {
|
||||
printf("Unable to allocate screen capture state\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s->initialized = false;
|
||||
|
||||
gettimeofday(&s->t0, NULL);
|
||||
|
||||
s->fps = 0.0;
|
||||
|
||||
s->frame = NULL;
|
||||
s->tile = NULL;
|
||||
|
||||
s->prev_time.tv_sec =
|
||||
s->prev_time.tv_usec = 0;
|
||||
|
||||
s->frames = 0;
|
||||
|
||||
if(vidcap_params_get_fmt(params)) {
|
||||
if (strcmp(vidcap_params_get_fmt(params), "help") == 0) {
|
||||
show_help();
|
||||
return &vidcap_init_noerr;
|
||||
} else if (strncasecmp(vidcap_params_get_fmt(params), "fps=", strlen("fps=")) == 0) {
|
||||
s->fps = atoi(vidcap_params_get_fmt(params) + strlen("fps="));
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void vidcap_screen_osx_done(void *state)
|
||||
{
|
||||
struct vidcap_screen_osx_state *s = (struct vidcap_screen_osx_state *) state;
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
if(s->tile) {
|
||||
free(s->tile->data);
|
||||
}
|
||||
vf_free(s->frame);
|
||||
free(s);
|
||||
}
|
||||
|
||||
struct video_frame * vidcap_screen_osx_grab(void *state, struct audio_frame **audio)
|
||||
{
|
||||
struct vidcap_screen_osx_state *s = (struct vidcap_screen_osx_state *) state;
|
||||
|
||||
if (!s->initialized) {
|
||||
initialize(s);
|
||||
s->initialized = true;
|
||||
}
|
||||
|
||||
*audio = NULL;
|
||||
|
||||
CGImageRef image = CGDisplayCreateImage(s->display);
|
||||
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(image));
|
||||
const unsigned char *pixels = CFDataGetBytePtr(data);
|
||||
|
||||
int linesize = s->tile->width * 4;
|
||||
int y;
|
||||
unsigned char *dst = (unsigned char *) s->tile->data;
|
||||
const unsigned char *src = (const unsigned char *) pixels;
|
||||
for(y = 0; y < (int) s->tile->height; ++y) {
|
||||
vc_copylineRGBA (dst, src, linesize, 16, 8, 0);
|
||||
src += linesize;
|
||||
dst += linesize;
|
||||
}
|
||||
|
||||
CFRelease(data);
|
||||
CFRelease(image);
|
||||
|
||||
if(s->fps > 0.0) {
|
||||
struct timeval cur_time;
|
||||
|
||||
gettimeofday(&cur_time, NULL);
|
||||
while(tv_diff_usec(cur_time, s->prev_time) < 1000000.0 / s->frame->fps) {
|
||||
gettimeofday(&cur_time, NULL);
|
||||
}
|
||||
s->prev_time = cur_time;
|
||||
}
|
||||
|
||||
gettimeofday(&s->t, NULL);
|
||||
double seconds = tv_diff(s->t, s->t0);
|
||||
if (seconds >= 5) {
|
||||
float fps = s->frames / seconds;
|
||||
fprintf(stderr, "[screen capture] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps);
|
||||
s->t0 = s->t;
|
||||
s->frames = 0;
|
||||
}
|
||||
|
||||
s->frames++;
|
||||
|
||||
return s->frame;
|
||||
}
|
||||
|
||||
@@ -1,32 +1,23 @@
|
||||
/**
|
||||
* @file screen_osx.h
|
||||
* @author Martin Pulec <pulec@cesnet.cz>
|
||||
*/
|
||||
/*
|
||||
* FILE: screen.h
|
||||
* AUTHORS: Martin Benes <martinbenesh@gmail.com>
|
||||
* Lukas Hejtmanek <xhejtman@ics.muni.cz>
|
||||
* Petr Holub <hopet@ics.muni.cz>
|
||||
* Milos Liska <xliska@fi.muni.cz>
|
||||
* Jiri Matela <matela@ics.muni.cz>
|
||||
* Dalibor Matura <255899@mail.muni.cz>
|
||||
* Ian Wesley-Smith <iwsmith@cct.lsu.edu>
|
||||
*
|
||||
* Copyright (c) 2005-2010 CESNET z.s.p.o.
|
||||
* Copyright (c) 2012-2013 CESNET, z.s.p.o.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by CESNET z.s.p.o.
|
||||
*
|
||||
* 4. Neither the name of the CESNET nor the names of its contributors may be
|
||||
*
|
||||
* 3. Neither the name of CESNET nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
@@ -42,12 +33,12 @@
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define VIDCAP_SCREEN_ID 0x5645ba22
|
||||
|
||||
struct vidcap_type *vidcap_screen_probe(void);
|
||||
void *vidcap_screen_init(const struct vidcap_params *params);
|
||||
void vidcap_screen_done(void *state);
|
||||
struct video_frame *vidcap_screen_grab(void *state, struct audio_frame **audio);
|
||||
struct vidcap_type *vidcap_screen_osx_probe(void);
|
||||
void *vidcap_screen_osx_init(const struct vidcap_params *params);
|
||||
void vidcap_screen_osx_done(void *state);
|
||||
struct video_frame *vidcap_screen_osx_grab(void *state, struct audio_frame **audio);
|
||||
|
||||
@@ -1,32 +1,23 @@
|
||||
/**
|
||||
* @file screen_x11.c
|
||||
* @author Martin Pulec <pulec@cesnet.cz>
|
||||
*/
|
||||
/*
|
||||
* FILE: screen.c
|
||||
* AUTHORS: Martin Benes <martinbenesh@gmail.com>
|
||||
* Lukas Hejtmanek <xhejtman@ics.muni.cz>
|
||||
* Petr Holub <hopet@ics.muni.cz>
|
||||
* Milos Liska <xliska@fi.muni.cz>
|
||||
* Jiri Matela <matela@ics.muni.cz>
|
||||
* Dalibor Matura <255899@mail.muni.cz>
|
||||
* Ian Wesley-Smith <iwsmith@cct.lsu.edu>
|
||||
*
|
||||
* Copyright (c) 2005-2010 CESNET z.s.p.o.
|
||||
* Copyright (c) 2012-2013 CESNET, z.s.p.o.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
*
|
||||
* This product includes software developed by CESNET z.s.p.o.
|
||||
*
|
||||
* 4. Neither the name of the CESNET nor the names of its contributors may be
|
||||
*
|
||||
* 3. Neither the name of CESNET nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
@@ -42,11 +33,8 @@
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "host.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#include "config_unix.h"
|
||||
@@ -60,37 +48,25 @@
|
||||
|
||||
#include "tv.h"
|
||||
|
||||
#include "video_capture/screen.h"
|
||||
#include "video_capture/screen_x11.h"
|
||||
#include "audio/audio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef HAVE_MACOSX
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#else
|
||||
#include <X11/Xlib.h>
|
||||
#ifdef HAVE_XFIXES
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#endif // HAVE_XFIXES
|
||||
#include <X11/Xutil.h>
|
||||
#include "x11_common.h"
|
||||
#endif
|
||||
|
||||
#define QUEUE_SIZE_MAX 3
|
||||
|
||||
/* prototypes of functions defined in this module */
|
||||
static void show_help(void);
|
||||
#ifdef HAVE_LINUX
|
||||
static void *grab_thread(void *args);
|
||||
#endif // HAVE_LINUX
|
||||
|
||||
static volatile bool should_exit = false;
|
||||
|
||||
static void show_help()
|
||||
{
|
||||
@@ -100,25 +76,18 @@ static void show_help()
|
||||
printf("\t\t<fps> - preferred grabbing fps (otherwise unlimited)\n");
|
||||
}
|
||||
|
||||
static struct vidcap_screen_state *state;
|
||||
|
||||
#ifdef HAVE_LINUX
|
||||
struct grabbed_data;
|
||||
|
||||
struct grabbed_data {
|
||||
XImage *data;
|
||||
struct grabbed_data *next;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct vidcap_screen_state {
|
||||
struct vidcap_screen_x11_state {
|
||||
struct video_frame *frame;
|
||||
struct tile *tile;
|
||||
int frames;
|
||||
struct timeval t, t0;
|
||||
#ifdef HAVE_MACOSX
|
||||
CGDirectDisplayID display;
|
||||
#else
|
||||
Display *dpy;
|
||||
Window root;
|
||||
|
||||
@@ -134,24 +103,18 @@ struct vidcap_screen_state {
|
||||
volatile bool should_exit_worker;
|
||||
|
||||
pthread_t worker_id;
|
||||
#endif
|
||||
|
||||
struct timeval prev_time;
|
||||
|
||||
double fps;
|
||||
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
pthread_once_t initialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void initialize() {
|
||||
struct vidcap_screen_state *s = (struct vidcap_screen_state *) state;
|
||||
|
||||
static void initialize(struct vidcap_screen_x11_state *s) {
|
||||
s->frame = vf_alloc(1);
|
||||
s->tile = vf_get_tile(s->frame, 0);
|
||||
|
||||
|
||||
#ifndef HAVE_MACOSX
|
||||
XWindowAttributes wa;
|
||||
|
||||
x11_lock();
|
||||
@@ -178,15 +141,6 @@ static void initialize() {
|
||||
|
||||
s->should_exit_worker = false;
|
||||
|
||||
#else
|
||||
s->display = CGMainDisplayID();
|
||||
CGImageRef image = CGDisplayCreateImage(s->display);
|
||||
|
||||
s->tile->width = CGImageGetWidth(image);
|
||||
s->tile->height = CGImageGetHeight(image);
|
||||
CFRelease(image);
|
||||
#endif
|
||||
|
||||
s->frame->color_spec = RGB;
|
||||
if(s->fps > 0.0) {
|
||||
s->frame->fps = s->fps;
|
||||
@@ -196,13 +150,9 @@ static void initialize() {
|
||||
s->frame->interlacing = PROGRESSIVE;
|
||||
s->tile->data_len = vc_get_linesize(s->tile->width, s->frame->color_spec) * s->tile->height;
|
||||
|
||||
#ifndef HAVE_MACOSX
|
||||
s->tile->data = (char *) malloc(s->tile->data_len);
|
||||
|
||||
pthread_create(&s->worker_id, NULL, grab_thread, s);
|
||||
#else
|
||||
s->tile->data = (char *) malloc(s->tile->data_len);
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
@@ -213,10 +163,9 @@ error:
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LINUX
|
||||
static void *grab_thread(void *args)
|
||||
{
|
||||
struct vidcap_screen_state *s = args;
|
||||
struct vidcap_screen_x11_state *s = args;
|
||||
|
||||
while(!s->should_exit_worker) {
|
||||
struct grabbed_data *new_item = malloc(sizeof(struct grabbed_data));
|
||||
@@ -285,9 +234,8 @@ static void *grab_thread(void *args)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif // HAVE_LINUX
|
||||
|
||||
struct vidcap_type * vidcap_screen_probe(void)
|
||||
struct vidcap_type * vidcap_screen_x11_probe(void)
|
||||
{
|
||||
struct vidcap_type* vt;
|
||||
|
||||
@@ -300,17 +248,18 @@ struct vidcap_type * vidcap_screen_probe(void)
|
||||
return vt;
|
||||
}
|
||||
|
||||
void * vidcap_screen_init(const struct vidcap_params *params)
|
||||
void * vidcap_screen_x11_init(const struct vidcap_params *params)
|
||||
{
|
||||
struct vidcap_screen_state *s;
|
||||
struct vidcap_screen_x11_state *s;
|
||||
|
||||
printf("vidcap_screen_init\n");
|
||||
|
||||
state = s = (struct vidcap_screen_state *) malloc(sizeof(struct vidcap_screen_state));
|
||||
s = (struct vidcap_screen_x11_state *) malloc(sizeof(struct vidcap_screen_x11_state));
|
||||
if(s == NULL) {
|
||||
printf("Unable to allocate screen capture state\n");
|
||||
return NULL;
|
||||
}
|
||||
s->initialized = false;
|
||||
|
||||
gettimeofday(&s->t0, NULL);
|
||||
|
||||
@@ -319,17 +268,14 @@ void * vidcap_screen_init(const struct vidcap_params *params)
|
||||
s->frame = NULL;
|
||||
s->tile = NULL;
|
||||
|
||||
#ifdef HAVE_LINUX
|
||||
s->worker_id = 0;
|
||||
#ifndef HAVE_XFIXES
|
||||
fprintf(stderr, "[Screen capture] Compiled without XFixes library, cursor won't be shown!\n");
|
||||
#endif // ! HAVE_XFIXES
|
||||
#endif // HAVE_LINUX
|
||||
|
||||
s->prev_time.tv_sec =
|
||||
s->prev_time.tv_usec = 0;
|
||||
|
||||
|
||||
s->frames = 0;
|
||||
|
||||
if(vidcap_params_get_fmt(params)) {
|
||||
@@ -344,13 +290,11 @@ void * vidcap_screen_init(const struct vidcap_params *params)
|
||||
return s;
|
||||
}
|
||||
|
||||
static void vidcap_screen_finish(void *state)
|
||||
static void vidcap_screen_x11_finish(void *state)
|
||||
{
|
||||
struct vidcap_screen_state *s = (struct vidcap_screen_state *) state;
|
||||
struct vidcap_screen_x11_state *s = (struct vidcap_screen_x11_state *) state;
|
||||
|
||||
assert(s != NULL);
|
||||
should_exit = true;
|
||||
#ifdef HAVE_LINUX
|
||||
pthread_mutex_lock(&s->lock);
|
||||
if(s->boss_waiting) {
|
||||
pthread_cond_signal(&s->boss_cv);
|
||||
@@ -366,18 +310,16 @@ static void vidcap_screen_finish(void *state)
|
||||
if(s->worker_id) {
|
||||
pthread_join(s->worker_id, NULL);
|
||||
}
|
||||
#endif // HAVE_LINUX
|
||||
}
|
||||
|
||||
void vidcap_screen_done(void *state)
|
||||
void vidcap_screen_x11_done(void *state)
|
||||
{
|
||||
struct vidcap_screen_state *s = (struct vidcap_screen_state *) state;
|
||||
struct vidcap_screen_x11_state *s = (struct vidcap_screen_x11_state *) state;
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
vidcap_screen_finish(state);
|
||||
vidcap_screen_x11_finish(state);
|
||||
|
||||
#ifdef HAVE_LINUX
|
||||
pthread_mutex_lock(&s->lock);
|
||||
{
|
||||
while(s->queue_len > 0) {
|
||||
@@ -392,27 +334,22 @@ void vidcap_screen_done(void *state)
|
||||
|
||||
if(s->tile)
|
||||
free(s->tile->data);
|
||||
#endif
|
||||
|
||||
if(s->tile) {
|
||||
#ifdef HAVE_MACOS_X
|
||||
free(s->tile->data);
|
||||
#endif
|
||||
}
|
||||
vf_free(s->frame);
|
||||
free(s);
|
||||
}
|
||||
|
||||
struct video_frame * vidcap_screen_grab(void *state, struct audio_frame **audio)
|
||||
struct video_frame * vidcap_screen_x11_grab(void *state, struct audio_frame **audio)
|
||||
{
|
||||
struct vidcap_screen_state *s = (struct vidcap_screen_state *) state;
|
||||
struct vidcap_screen_x11_state *s = (struct vidcap_screen_x11_state *) state;
|
||||
|
||||
pthread_once(&initialized, initialize);
|
||||
if (!s->initialized) {
|
||||
initialize(s);
|
||||
s->initialized = true;
|
||||
}
|
||||
|
||||
*audio = NULL;
|
||||
|
||||
#ifndef HAVE_MACOSX
|
||||
|
||||
struct grabbed_data *item = NULL;
|
||||
|
||||
pthread_mutex_lock(&s->lock);
|
||||
@@ -444,25 +381,6 @@ struct video_frame * vidcap_screen_grab(void *state, struct audio_frame **audio)
|
||||
|
||||
XDestroyImage(item->data);
|
||||
free(item);
|
||||
#else
|
||||
CGImageRef image = CGDisplayCreateImage(s->display);
|
||||
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(image));
|
||||
const unsigned char *pixels = CFDataGetBytePtr(data);
|
||||
|
||||
int linesize = s->tile->width * 4;
|
||||
int y;
|
||||
unsigned char *dst = (unsigned char *) s->tile->data;
|
||||
const unsigned char *src = (const unsigned char *) pixels;
|
||||
for(y = 0; y < (int) s->tile->height; ++y) {
|
||||
vc_copylineRGBA (dst, src, linesize, 16, 8, 0);
|
||||
src += linesize;
|
||||
dst += linesize;
|
||||
}
|
||||
|
||||
CFRelease(data);
|
||||
CFRelease(image);
|
||||
|
||||
#endif
|
||||
|
||||
if(s->fps > 0.0) {
|
||||
struct timeval cur_time;
|
||||
44
src/video_capture/screen_x11.h
Normal file
44
src/video_capture/screen_x11.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file screen_x11.h
|
||||
* @author Martin Pulec <pulec@cesnet.cz>
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2012-2013 CESNET, z.s.p.o.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, is permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of CESNET nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define VIDCAP_SCREEN_ID 0x5645ba22
|
||||
|
||||
struct vidcap_type *vidcap_screen_x11_probe(void);
|
||||
void *vidcap_screen_x11_init(const struct vidcap_params *params);
|
||||
void vidcap_screen_x11_done(void *state);
|
||||
struct video_frame *vidcap_screen_x11_grab(void *state, struct audio_frame **audio);
|
||||
|
||||
Reference in New Issue
Block a user