sys/: Our

Original commit message from CVS:
2004-01-28  Julien MOUTTE  <julien@moutte.net>

* sys/ximage/ximagesink.c: (gst_ximagesink_handle_xerror),
(gst_ximagesink_check_xshm_calls), (gst_ximagesink_ximage_destroy),
(gst_ximagesink_xcontext_get), (gst_ximagesink_class_init):
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_handle_xerror),
(gst_xvimagesink_check_xshm_calls),
(gst_xvimagesink_xvimage_destroy), (gst_xvimagesink_xcontext_get): Our
X plugins are now able to detect that XShm calls will fail even if the
server claims that it has XShm support (remote displays most of the
time). We then log the error as a GST_DEBUG and set use_shm to FALSE
so that we use non XShm functions. This feature is almost useless for
xvimagesink as Xv is not supported on remote displays anyway, but
it might happen than even on the local display XShm calls fail.
This commit is contained in:
Julien Moutte 2004-01-28 00:29:42 +00:00
parent 3ca4fff48a
commit 2614bc1a48
3 changed files with 173 additions and 17 deletions

View file

@ -1,3 +1,18 @@
2004-01-28 Julien MOUTTE <julien@moutte.net>
* sys/ximage/ximagesink.c: (gst_ximagesink_handle_xerror),
(gst_ximagesink_check_xshm_calls), (gst_ximagesink_ximage_destroy),
(gst_ximagesink_xcontext_get), (gst_ximagesink_class_init):
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_handle_xerror),
(gst_xvimagesink_check_xshm_calls),
(gst_xvimagesink_xvimage_destroy), (gst_xvimagesink_xcontext_get): Our
X plugins are now able to detect that XShm calls will fail even if the
server claims that it has XShm support (remote displays most of the
time). We then log the error as a GST_DEBUG and set use_shm to FALSE
so that we use non XShm functions. This feature is almost useless for
xvimagesink as Xv is not supported on remote displays anyway, but
it might happen than even on the local display XShm calls fail.
2004-01-27 David Schleef <ds@schleef.org>
* ext/esd/esdsink.c: (gst_esdsink_class_init), (gst_esdsink_init),

View file

@ -59,6 +59,7 @@ enum {
};
static GstVideoSinkClass *parent_class = NULL;
static gboolean error_catched = FALSE;
/* ============================================================= */
/* */
@ -68,6 +69,71 @@ static GstVideoSinkClass *parent_class = NULL;
/* X11 stuff */
static int
gst_ximagesink_handle_xerror (Display *display, XErrorEvent *xevent)
{
char error_msg [1024];
XGetErrorText (display, xevent->error_code, error_msg, 1024);
GST_DEBUG ("ximagesink failed to use XShm calls. error: %s",
error_msg);
error_catched = TRUE;
return 0;
}
/* This function checks that it is actually really possible to create an image
using XShm */
static gboolean
gst_ximagesink_check_xshm_calls (GstXContext *xcontext)
{
GstXImage *ximage = NULL;
int (*handler)(Display *, XErrorEvent *);
g_return_val_if_fail (xcontext != NULL, FALSE);
#ifdef HAVE_XSHM
ximage = g_new0 (GstXImage, 1);
/* Setting an error handler to catch failure */
handler = XSetErrorHandler (gst_ximagesink_handle_xerror);
ximage->size = (xcontext->bpp / 8);
/* Trying to create a 1x1 picture */
ximage->ximage = XShmCreateImage (xcontext->disp, xcontext->visual,
xcontext->depth, ZPixmap, NULL,
&ximage->SHMInfo, 1, 1);
ximage->SHMInfo.shmid = shmget (IPC_PRIVATE, ximage->size, IPC_CREAT | 0777);
ximage->SHMInfo.shmaddr = shmat (ximage->SHMInfo.shmid, 0, 0);
ximage->ximage->data = ximage->SHMInfo.shmaddr;
ximage->SHMInfo.readOnly = FALSE;
XShmAttach (xcontext->disp, &ximage->SHMInfo);
error_catched = FALSE;
XSync(xcontext->disp, 0);
XSetErrorHandler (handler);
if (error_catched)
{ /* Failed, detaching shared memory, destroying image and telling we can't
use XShm */
error_catched = FALSE;
XDestroyImage (ximage->ximage);
shmdt (ximage->SHMInfo.shmaddr);
shmctl (ximage->SHMInfo.shmid, IPC_RMID, 0);
g_free (ximage);
XSync(xcontext->disp, 0);
return FALSE;
}
else
#endif /* HAVE_XSHM */
{
return TRUE;
}
}
/* This function handles GstXImage creation depending on XShm availability */
static GstXImage *
gst_ximagesink_ximage_new (GstXImageSink *ximagesink, gint width, gint height)
@ -171,7 +237,9 @@ gst_ximagesink_ximage_destroy (GstXImageSink *ximagesink, GstXImage *ximage)
if (ximage->ximage)
XDestroyImage (ximage->ximage);
}
XSync(ximagesink->xcontext->disp, 0);
g_mutex_unlock (ximagesink->x_lock);
g_free (ximage);
@ -486,7 +554,8 @@ gst_ximagesink_xcontext_get (GstXImageSink *ximagesink)
#ifdef HAVE_XSHM
/* Search for XShm extension support */
if (XQueryExtension (xcontext->disp, "MIT-SHM", &i, &i, &i))
if (XShmQueryExtension (xcontext->disp) &&
gst_ximagesink_check_xshm_calls (xcontext))
{
xcontext->use_xshm = TRUE;
GST_DEBUG ("ximagesink is using XShm extension");
@ -1216,7 +1285,7 @@ gst_ximagesink_class_init (GstXImageSinkClass *klass)
gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_VIDEOSINK);
g_object_class_install_property (gobject_class, ARG_DISPLAY,
g_param_spec_string ("display", "Display", "X Display name",
NULL, G_PARAM_READWRITE));

View file

@ -70,6 +70,7 @@ enum {
};
static GstVideoSinkClass *parent_class = NULL;
static gboolean error_catched = FALSE;
/* ============================================================= */
/* */
@ -79,6 +80,72 @@ static GstVideoSinkClass *parent_class = NULL;
/* X11 stuff */
static int
gst_xvimagesink_handle_xerror (Display *display, XErrorEvent *xevent)
{
char error_msg [1024];
XGetErrorText (display, xevent->error_code, error_msg, 1024);
GST_DEBUG ("xvimagesink failed to use XShm calls. error: %s",
error_msg);
error_catched = TRUE;
return 0;
}
/* This function checks that it is actually really possible to create an image
using XShm */
static gboolean
gst_xvimagesink_check_xshm_calls (GstXContext *xcontext)
{
GstXvImage *xvimage = NULL;
int (*handler)(Display *, XErrorEvent *);
g_return_val_if_fail (xcontext != NULL, FALSE);
#ifdef HAVE_XSHM
xvimage = g_new0 (GstXvImage, 1);
/* Setting an error handler to catch failure */
handler = XSetErrorHandler (gst_xvimagesink_handle_xerror);
xvimage->size = (xcontext->bpp / 8);
/* Trying to create a 1x1 picture */
xvimage->xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id,
xcontext->im_format, NULL, 1, 1,
&xvimage->SHMInfo);
xvimage->SHMInfo.shmid = shmget (IPC_PRIVATE, xvimage->size,
IPC_CREAT | 0777);
xvimage->SHMInfo.shmaddr = shmat (xvimage->SHMInfo.shmid, 0, 0);
xvimage->xvimage->data = xvimage->SHMInfo.shmaddr;
xvimage->SHMInfo.readOnly = FALSE;
XShmAttach (xcontext->disp, &xvimage->SHMInfo);
error_catched = FALSE;
XSync(xcontext->disp, 0);
XSetErrorHandler (handler);
if (error_catched)
{ /* Failed, detaching shared memory, destroying image and telling we can't
use XShm */
error_catched = FALSE;
XFree (xvimage->xvimage);
shmdt (xvimage->SHMInfo.shmaddr);
shmctl (xvimage->SHMInfo.shmid, IPC_RMID, 0);
g_free (xvimage);
XSync(xcontext->disp, 0);
return FALSE;
}
else
#endif /* HAVE_XSHM */
{
return TRUE;
}
}
/* This function handles GstXvImage creation depending on XShm availability */
static GstXvImage *
gst_xvimagesink_xvimage_new (GstXvImageSink *xvimagesink,
@ -183,6 +250,8 @@ gst_xvimagesink_xvimage_destroy (GstXvImageSink *xvimagesink,
XFree (xvimage->xvimage);
}
XSync(xvimagesink->xcontext->disp, 0);
g_mutex_unlock (xvimagesink->x_lock);
g_free (xvimage);
@ -669,20 +738,6 @@ gst_xvimagesink_xcontext_get (GstXvImageSink *xvimagesink)
xcontext->endianness = (ImageByteOrder (xcontext->disp) == LSBFirst) ? G_LITTLE_ENDIAN:G_BIG_ENDIAN;
#ifdef HAVE_XSHM
/* Search for XShm extension support */
if (XQueryExtension (xcontext->disp, "MIT-SHM", &i, &i, &i))
{
xcontext->use_xshm = TRUE;
GST_DEBUG ("xvimagesink is using XShm extension");
}
else
{
xcontext->use_xshm = FALSE;
GST_DEBUG ("xvimagesink is not using XShm extension");
}
#endif /* HAVE_XSHM */
/* our caps system handles 24/32bpp RGB as big-endian. */
if ((xcontext->bpp == 24 || xcontext->bpp == 32) &&
xcontext->endianness == G_LITTLE_ENDIAN) {
@ -707,6 +762,23 @@ gst_xvimagesink_xcontext_get (GstXvImageSink *xvimagesink)
return NULL;
}
#ifdef HAVE_XSHM
/* Search for XShm extension support */
if (XShmQueryExtension (xcontext->disp) &&
gst_xvimagesink_check_xshm_calls (xcontext))
{
xcontext->use_xshm = TRUE;
GST_DEBUG ("xvimagesink is using XShm extension");
g_message ("using XShm");
}
else
{
xcontext->use_xshm = FALSE;
GST_DEBUG ("xvimagesink is not using XShm extension");
g_message ("not using XShm");
}
#endif /* HAVE_XSHM */
xv_attr = XvQueryPortAttributes (xcontext->disp,
xcontext->xv_port_id,
&N_attr);