mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
ximagesrc: Gather and coalesce all damaged areas before retrieving.
These days the xserver seems to give us the same damage regions over and over for entire windows, and we retrieve them multiple times, which gives time for more damage to appear. Instead, just quickly gather all damaged areas into a region list and copy out once.
This commit is contained in:
parent
711b035137
commit
040467d118
1 changed files with 98 additions and 88 deletions
|
@ -536,6 +536,7 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||
if (ximagesrc->have_xdamage && ximagesrc->use_damage &&
|
||||
ximagesrc->last_ximage != NULL) {
|
||||
XEvent ev;
|
||||
gboolean have_damage = FALSE;
|
||||
|
||||
/* have_frame is TRUE when either the entire screen has been
|
||||
* grabbed or when the last image has been copied */
|
||||
|
@ -544,18 +545,27 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||
GST_DEBUG_OBJECT (ximagesrc, "Retrieving screen using XDamage");
|
||||
|
||||
do {
|
||||
XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *) (&ev);
|
||||
|
||||
XNextEvent (ximagesrc->xcontext->disp, &ev);
|
||||
|
||||
if (ev.type == ximagesrc->damage_event_base + XDamageNotify) {
|
||||
XserverRegion parts;
|
||||
if (ev.type == ximagesrc->damage_event_base + XDamageNotify &&
|
||||
damage_ev->level == XDamageReportNonEmpty) {
|
||||
|
||||
XDamageSubtract (ximagesrc->xcontext->disp, ximagesrc->damage, None,
|
||||
ximagesrc->damage_region);
|
||||
have_damage = TRUE;
|
||||
}
|
||||
} while (XPending (ximagesrc->xcontext->disp));
|
||||
|
||||
if (have_damage) {
|
||||
XRectangle *rects;
|
||||
int nrects;
|
||||
|
||||
parts = XFixesCreateRegion (ximagesrc->xcontext->disp, 0, 0);
|
||||
XDamageSubtract (ximagesrc->xcontext->disp, ximagesrc->damage, None,
|
||||
parts);
|
||||
/* Now copy out all of the damaged rectangles. */
|
||||
rects = XFixesFetchRegion (ximagesrc->xcontext->disp, parts, &nrects);
|
||||
rects =
|
||||
XFixesFetchRegion (ximagesrc->xcontext->disp,
|
||||
ximagesrc->damage_region, &nrects);
|
||||
if (rects != NULL) {
|
||||
int i;
|
||||
|
||||
|
@ -617,10 +627,9 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||
AllPlanes, ZPixmap, meta->ximage, rects[i].x, rects[i].y);
|
||||
}
|
||||
}
|
||||
free (rects);
|
||||
XFree (rects);
|
||||
}
|
||||
}
|
||||
} while (XPending (ximagesrc->xcontext->disp));
|
||||
if (!have_frame) {
|
||||
GST_LOG_OBJECT (ximagesrc,
|
||||
"Copying from last frame ximage->size: %" G_GSIZE_FORMAT,
|
||||
|
@ -757,9 +766,10 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||
iwidth = (cx + ximagesrc->cursor_image->width < ximagesrc->endx) ?
|
||||
cx + ximagesrc->cursor_image->width - startx :
|
||||
ximagesrc->endx - startx;
|
||||
iheight = (cy + ximagesrc->cursor_image->height < ximagesrc->endy) ?
|
||||
cy + ximagesrc->cursor_image->height - starty :
|
||||
ximagesrc->endy - starty;
|
||||
iheight =
|
||||
(cy + ximagesrc->cursor_image->height <
|
||||
ximagesrc->endy) ? cy + ximagesrc->cursor_image->height -
|
||||
starty : ximagesrc->endy - starty;
|
||||
}
|
||||
} else {
|
||||
startx = cx;
|
||||
|
@ -775,11 +785,11 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||
GUINT_TO_LE (ximagesrc->cursor_image->pixels[i]);
|
||||
/* copy those pixels across */
|
||||
for (j = starty;
|
||||
j < starty + iheight && j < ximagesrc->starty + ximagesrc->height;
|
||||
j++) {
|
||||
j < starty + iheight
|
||||
&& j < ximagesrc->starty + ximagesrc->height; j++) {
|
||||
for (i = startx;
|
||||
i < startx + iwidth && i < ximagesrc->startx + ximagesrc->width;
|
||||
i++) {
|
||||
i < startx + iwidth
|
||||
&& i < ximagesrc->startx + ximagesrc->width; i++) {
|
||||
guint8 *src, *dest;
|
||||
|
||||
src =
|
||||
|
@ -788,8 +798,8 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||
dest =
|
||||
(guint8 *) & (meta->ximage->data[((j -
|
||||
ximagesrc->starty) * ximagesrc->width + (i -
|
||||
ximagesrc->startx)) * (ximagesrc->xcontext->bpp /
|
||||
8)]);
|
||||
ximagesrc->startx)) *
|
||||
(ximagesrc->xcontext->bpp / 8)]);
|
||||
|
||||
composite_pixel (ximagesrc->xcontext, (guint8 *) dest,
|
||||
(guint8 *) src);
|
||||
|
@ -963,8 +973,8 @@ gst_ximage_src_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_ximage_src_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
gst_ximage_src_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstXImageSrc *src = GST_XIMAGE_SRC (object);
|
||||
|
||||
|
@ -1116,16 +1126,16 @@ gst_ximage_src_get_caps (GstBaseSrc * bs, GstCaps * filter)
|
|||
|
||||
format =
|
||||
gst_video_format_from_masks (xcontext->depth, xcontext->bpp,
|
||||
xcontext->endianness, xcontext->r_mask_output, xcontext->g_mask_output,
|
||||
xcontext->b_mask_output, alpha_mask);
|
||||
xcontext->endianness, xcontext->r_mask_output,
|
||||
xcontext->g_mask_output, xcontext->b_mask_output, alpha_mask);
|
||||
|
||||
return gst_caps_new_simple ("video/x-raw",
|
||||
"format", G_TYPE_STRING, gst_video_format_to_string (format),
|
||||
"width", G_TYPE_INT, width,
|
||||
"height", G_TYPE_INT, height,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1,
|
||||
"pixel-aspect-ratio", GST_TYPE_FRACTION, xcontext->par_n, xcontext->par_d,
|
||||
NULL);
|
||||
"pixel-aspect-ratio", GST_TYPE_FRACTION, xcontext->par_n,
|
||||
xcontext->par_d, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1186,8 +1196,8 @@ gst_ximage_src_class_init (GstXImageSrcClass * klass)
|
|||
gc->finalize = gst_ximage_src_finalize;
|
||||
|
||||
g_object_class_install_property (gc, PROP_DISPLAY_NAME,
|
||||
g_param_spec_string ("display-name", "Display", "X Display Name", NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_param_spec_string ("display-name", "Display", "X Display Name",
|
||||
NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gc, PROP_SHOW_POINTER,
|
||||
g_param_spec_boolean ("show-pointer", "Show Mouse Pointer",
|
||||
"Show mouse pointer (if XFixes extension enabled)", TRUE,
|
||||
|
|
Loading…
Reference in a new issue