mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-29 20:35:40 +00:00
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:
parent
3ca4fff48a
commit
2614bc1a48
3 changed files with 173 additions and 17 deletions
15
ChangeLog
15
ChangeLog
|
@ -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),
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue