Commit 02c8a569 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

screen_xcb: run in a thread - remove input control latency

parent 075a0342
......@@ -91,11 +91,14 @@ vlc_module_end ()
/*
* Local prototypes
*/
static int Demux (demux_t *);
static void *Thread (void *);
static int Control (demux_t *, int, va_list);
struct demux_sys_t
{
/* WARNING: Control() is concurrent with Thread()/Demux().
* Currently, the thread owns everything in read/write, if it exists.
* We destroy it on pause, and re-create it on resume. */
xcb_connection_t *conn;
es_out_id_t *es;
es_format_t fmt;
......@@ -103,6 +106,10 @@ struct demux_sys_t
xcb_window_t root, window;
int16_t x, y;
uint16_t w, h;
/* Thread does not use. This is for input thread only: */
vlc_thread_t thread;
bool running;
};
/**
......@@ -115,7 +122,8 @@ static int Open (vlc_object_t *obj)
if (p_sys == NULL)
return VLC_ENOMEM;
demux->p_sys = p_sys;
demux->p_sys = p_sys;
p_sys->running = false;
/* Connect to X server */
char *display = var_CreateGetNonEmptyString (obj, "x11-display");
......@@ -237,9 +245,12 @@ static int Open (vlc_object_t *obj)
p_sys->fmt.video.i_frame_rate_base = 1000;
p_sys->es = NULL;
p_sys->pts = VLC_TS_INVALID;
if (vlc_clone (&p_sys->thread, Thread, demux, VLC_THREAD_PRIORITY_INPUT))
goto error;
p_sys->running = true;
/* Initializes demux */
demux->pf_demux = Demux;
demux->pf_demux = NULL;
demux->pf_control = Control;
return VLC_SUCCESS;
......@@ -257,6 +268,11 @@ static void Close (vlc_object_t *obj)
demux_t *demux = (demux_t *)obj;
demux_sys_t *p_sys = demux->p_sys;
if (p_sys->running)
{
vlc_cancel (p_sys->thread);
vlc_join (p_sys->thread, NULL);
}
xcb_disconnect (p_sys->conn);
free (p_sys);
}
......@@ -305,11 +321,23 @@ static int Control (demux_t *demux, int query, va_list args)
case DEMUX_SET_PAUSE_STATE:
{
bool pausing = va_arg (args, int);
if (pausing != p_sys->running)
return VLC_SUCCESS; /* No-op. FIXME: is it needed? */
if (!pausing)
{
p_sys->pts = VLC_TS_INVALID;
es_out_Control (demux->out, ES_OUT_RESET_PCR);
if (vlc_clone (&p_sys->thread, Thread, demux,
VLC_THREAD_PRIORITY_INPUT))
return VLC_EGENERIC;
}
else
{
vlc_cancel (p_sys->thread);
vlc_join (p_sys->thread, NULL);
}
p_sys->running = !pausing;
return VLC_SUCCESS;
}
......@@ -330,7 +358,7 @@ static int Control (demux_t *demux, int query, va_list args)
/**
* Processing callback
*/
static int Demux (demux_t *demux)
static void Demux (demux_t *demux)
{
demux_sys_t *p_sys = demux->p_sys;
xcb_connection_t *conn = p_sys->conn;
......@@ -341,6 +369,8 @@ static int Demux (demux_t *demux)
else
p_sys->pts = now;
int canc = vlc_savecancel ();
/* Update capture region (if needed) */
xcb_get_geometry_cookie_t gc = xcb_get_geometry (conn, p_sys->window);
int16_t x = p_sys->x, y = p_sys->y;
......@@ -354,7 +384,7 @@ static int Demux (demux_t *demux)
if (geo == NULL)
{
msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, p_sys->window);
return 0;
goto out;
}
uint16_t w = geo->width - x;
......@@ -380,7 +410,7 @@ static int Demux (demux_t *demux)
xcb_translate_coordinates_reply_t *coords =
xcb_translate_coordinates_reply (conn, tc, NULL);
if (coords == NULL)
return 1;
goto out;
x = coords->dst_x;
y = coords->dst_y;
free (coords);
......@@ -388,24 +418,31 @@ static int Demux (demux_t *demux)
/* Capture screen */
if (p_sys->es == NULL)
return 1;
goto out;
xcb_get_image_reply_t *img;
img = xcb_get_image_reply (conn,
xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, p_sys->root,
x, y, w, h, ~0), NULL);
if (img == NULL)
return 1;
goto out;
/* Send block - zero copy */
block_t *block = block_heap_Alloc (img, xcb_get_image_data (img),
xcb_get_image_data_length (img));
if (block == NULL)
return 0;
goto out;
block->i_pts = block->i_dts = now;
es_out_Control (demux->out, ES_OUT_SET_PCR, now);
es_out_Send (demux->out, p_sys->es, block);
p_sys->pts += p_sys->interval;
return 1;
out:
vlc_restorecancel (canc);
}
static void *Thread (void *data)
{
for (;;)
Demux (data);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment