diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/ximage/ximagesink.c | 110 | ||||
-rw-r--r-- | sys/xvimage/xvimagesink.c | 86 |
2 files changed, 149 insertions, 47 deletions
diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index 7ca9d6c8..06ec5486 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -202,7 +202,7 @@ gst_ximage_buffer_finalize (GstXImageBuffer * ximage) g_return_if_fail (ximage != NULL); ximagesink = ximage->ximagesink; - if (!ximagesink) { + if (G_UNLIKELY (ximagesink == NULL)) { GST_WARNING_OBJECT (ximagesink, "no sink found"); goto beach; } @@ -301,7 +301,7 @@ 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); + GST_DEBUG ("ximagesink triggered an XError. error: %s", error_msg); error_caught = TRUE; return 0; } @@ -406,6 +406,7 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps) GstXImageBuffer *ximage = NULL; GstStructure *structure = NULL; gboolean succeeded = FALSE; + int (*handler) (Display *, XErrorEvent *); g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), NULL); @@ -423,14 +424,22 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps) g_mutex_lock (ximagesink->x_lock); + /* Setting an error handler to catch failure */ + error_caught = FALSE; + handler = XSetErrorHandler (gst_ximagesink_handle_xerror); + #ifdef HAVE_XSHM if (ximagesink->xcontext->use_xshm) { ximage->ximage = XShmCreateImage (ximagesink->xcontext->disp, ximagesink->xcontext->visual, ximagesink->xcontext->depth, ZPixmap, NULL, &ximage->SHMInfo, ximage->width, ximage->height); - if (!ximage->ximage) { + if (!ximage->ximage || error_caught) { g_mutex_unlock (ximagesink->x_lock); + /* Reset error handler */ + error_caught = FALSE; + XSetErrorHandler (handler); + /* Push an error */ GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", ximage->width, ximage->height), @@ -494,8 +503,12 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps) ximagesink->xcontext->depth, ZPixmap, 0, NULL, ximage->width, ximage->height, ximagesink->xcontext->bpp, 0); - if (!ximage->ximage) { + if (!ximage->ximage || error_caught) { g_mutex_unlock (ximagesink->x_lock); + /* Reset error handler */ + error_caught = FALSE; + XSetErrorHandler (handler); + /* Push an error */ GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", ximage->width, ximage->height), @@ -510,6 +523,11 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps) XSync (ximagesink->xcontext->disp, FALSE); } + + /* Reset error handler */ + error_caught = FALSE; + XSetErrorHandler (handler); + succeeded = TRUE; GST_BUFFER_DATA (ximage) = (guchar *) ximage->ximage->data; @@ -536,14 +554,14 @@ gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink, g_return_if_fail (ximage != NULL); g_return_if_fail (GST_IS_XIMAGESINK (ximagesink)); + /* Hold the object lock to ensure the XContext doesn't disappear */ + GST_OBJECT_LOCK (ximagesink); + /* If the destroyed image is the current one we destroy our reference too */ if (ximagesink->cur_image == ximage) { ximagesink->cur_image = NULL; } - /* Hold the object lock to ensure the XContext doesn't disappear */ - GST_OBJECT_LOCK (ximagesink); - /* We might have some buffers destroyed after changing state to NULL */ if (!ximagesink->xcontext) { GST_DEBUG_OBJECT (ximagesink, "Destroying XImage after XContext"); @@ -640,6 +658,11 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage) concurrently from the data flow thread */ g_mutex_lock (ximagesink->flow_lock); + if (G_UNLIKELY (ximagesink->xwindow == NULL)) { + g_mutex_unlock (ximagesink->flow_lock); + return; + } + /* Draw borders when displaying the first frame. After this draw borders only on expose event. */ if (!ximagesink->cur_image) { @@ -875,10 +898,12 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink) /* Then we get all pointer motion events, only the last position is interesting. */ + g_mutex_lock (ximagesink->flow_lock); g_mutex_lock (ximagesink->x_lock); while (XCheckWindowEvent (ximagesink->xcontext->disp, ximagesink->xwindow->win, PointerMotionMask, &e)) { g_mutex_unlock (ximagesink->x_lock); + g_mutex_unlock (ximagesink->flow_lock); switch (e.type) { case MotionNotify: @@ -889,10 +914,11 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink) default: break; } - + g_mutex_lock (ximagesink->flow_lock); g_mutex_lock (ximagesink->x_lock); } g_mutex_unlock (ximagesink->x_lock); + g_mutex_unlock (ximagesink->flow_lock); if (pointer_moved) { GST_DEBUG ("ximagesink pointer moved over window at %d,%d", @@ -903,6 +929,7 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink) } /* We get all remaining events on our window to throw them upstream */ + g_mutex_lock (ximagesink->flow_lock); g_mutex_lock (ximagesink->x_lock); while (XCheckWindowEvent (ximagesink->xcontext->disp, ximagesink->xwindow->win, @@ -912,6 +939,7 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink) /* We lock only for the X function call */ g_mutex_unlock (ximagesink->x_lock); + g_mutex_unlock (ximagesink->flow_lock); switch (e.type) { case ButtonPress: @@ -949,17 +977,21 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink) GST_DEBUG_OBJECT (ximagesink, "ximagesink unhandled X event (%d)", e.type); } + g_mutex_lock (ximagesink->flow_lock); g_mutex_lock (ximagesink->x_lock); } g_mutex_unlock (ximagesink->x_lock); + g_mutex_unlock (ximagesink->flow_lock); { gboolean exposed = FALSE; + g_mutex_lock (ximagesink->flow_lock); g_mutex_lock (ximagesink->x_lock); while (XCheckWindowEvent (ximagesink->xcontext->disp, ximagesink->xwindow->win, ExposureMask, &e)) { g_mutex_unlock (ximagesink->x_lock); + g_mutex_unlock (ximagesink->flow_lock); switch (e.type) { case Expose: @@ -968,10 +1000,11 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink) default: break; } - + g_mutex_lock (ximagesink->flow_lock); g_mutex_lock (ximagesink->x_lock); } g_mutex_unlock (ximagesink->x_lock); + g_mutex_unlock (ximagesink->flow_lock); if (exposed) { gst_ximagesink_expose (GST_X_OVERLAY (ximagesink)); @@ -1335,17 +1368,28 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps) ximagesink->fps_d = gst_value_get_fraction_denominator (fps); /* Notify application to set xwindow id now */ + g_mutex_lock (ximagesink->flow_lock); if (!ximagesink->xwindow) { + g_mutex_unlock (ximagesink->flow_lock); gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (ximagesink)); + } else { + g_mutex_unlock (ximagesink->flow_lock); } /* Creating our window and our image */ - g_assert (GST_VIDEO_SINK_WIDTH (ximagesink) > 0); - g_assert (GST_VIDEO_SINK_HEIGHT (ximagesink) > 0); + if (GST_VIDEO_SINK_WIDTH (ximagesink) <= 0 || + GST_VIDEO_SINK_HEIGHT (ximagesink) <= 0) { + GST_ELEMENT_ERROR (ximagesink, CORE, NEGOTIATION, (NULL), + ("Invalid image size.")); + return FALSE; + } + + g_mutex_lock (ximagesink->flow_lock); if (!ximagesink->xwindow) { ximagesink->xwindow = gst_ximagesink_xwindow_new (ximagesink, GST_VIDEO_SINK_WIDTH (ximagesink), GST_VIDEO_SINK_HEIGHT (ximagesink)); } + g_mutex_unlock (ximagesink->flow_lock); /* If our ximage has changed we destroy it, next chain iteration will create a new one */ @@ -1402,6 +1446,10 @@ gst_ximagesink_change_state (GstElement * element, GstStateChange transition) g_mutex_unlock (ximagesink->x_lock); break; case GST_STATE_CHANGE_READY_TO_PAUSED: + g_mutex_lock (ximagesink->flow_lock); + if (ximagesink->xwindow) + gst_ximagesink_xwindow_clear (ximagesink, ximagesink->xwindow); + g_mutex_unlock (ximagesink->flow_lock); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; @@ -1417,8 +1465,6 @@ gst_ximagesink_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: - if (ximagesink->xwindow) - gst_ximagesink_xwindow_clear (ximagesink, ximagesink->xwindow); ximagesink->fps_n = 0; ximagesink->fps_d = 1; GST_VIDEO_SINK_WIDTH (ximagesink) = 0; @@ -1440,10 +1486,13 @@ gst_ximagesink_change_state (GstElement * element, GstStateChange transition) gst_ximagesink_bufferpool_clear (ximagesink); + g_mutex_lock (ximagesink->flow_lock); if (ximagesink->xwindow) { + gst_ximagesink_xwindow_clear (ximagesink, ximagesink->xwindow); gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow); ximagesink->xwindow = NULL; } + g_mutex_unlock (ximagesink->flow_lock); gst_ximagesink_xcontext_clear (ximagesink); break; @@ -1774,25 +1823,25 @@ gst_ximagesink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id) GstXWindow *xwindow = NULL; XWindowAttributes attr; + /* We acquire the stream lock while setting this window in the element. + We are basically cleaning tons of stuff replacing the old window, putting + images while we do that would surely crash */ + g_mutex_lock (ximagesink->flow_lock); + /* If we already use that window return */ - if (ximagesink->xwindow && (xwindow_id == ximagesink->xwindow->win)) + if (ximagesink->xwindow && (xwindow_id == ximagesink->xwindow->win)) { + g_mutex_unlock (ximagesink->flow_lock); return; + } /* If the element has not initialized the X11 context try to do so */ - if (!ximagesink->xcontext) - ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink); - - if (!ximagesink->xcontext) { - GST_WARNING_OBJECT (ximagesink, - "ximagesink was unable to obtain the X11 context."); + if (!ximagesink->xcontext && + !(ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink))) { + g_mutex_unlock (ximagesink->flow_lock); + /* we have thrown a GST_ELEMENT_ERROR now */ return; } - /* We acquire the stream lock while setting this window in the element. - We are basically cleaning tons of stuff replacing the old window, putting - images while we do that would surely crash */ - g_mutex_lock (ximagesink->flow_lock); - /* If a window is there already we destroy it */ if (ximagesink->xwindow) { gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow); @@ -1841,9 +1890,6 @@ gst_ximagesink_expose (GstXOverlay * overlay) { GstXImageSink *ximagesink = GST_XIMAGESINK (overlay); - if (!ximagesink->xwindow) - return; - gst_ximagesink_ximage_put (ximagesink, NULL); } @@ -1855,8 +1901,12 @@ gst_ximagesink_set_event_handling (GstXOverlay * overlay, ximagesink->handle_events = handle_events; - if (!ximagesink->xwindow) + g_mutex_lock (ximagesink->flow_lock); + + if (G_UNLIKELY (!ximagesink->xwindow)) { + g_mutex_unlock (ximagesink->flow_lock); return; + } g_mutex_lock (ximagesink->x_lock); @@ -1875,6 +1925,8 @@ gst_ximagesink_set_event_handling (GstXOverlay * overlay, } g_mutex_unlock (ximagesink->x_lock); + + g_mutex_unlock (ximagesink->flow_lock); } static void diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index 01efd4b0..0fbfb579 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -217,17 +217,18 @@ gst_xvimage_buffer_destroy (GstXvImageBuffer * xvimage) GST_DEBUG_OBJECT (xvimage, "Destroying buffer"); xvimagesink = xvimage->xvimagesink; - if (xvimagesink == NULL) + if (G_UNLIKELY (xvimagesink == NULL)) goto no_sink; g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink)); + GST_OBJECT_LOCK (xvimagesink); + /* If the destroyed image is the current one we destroy our reference too */ if (xvimagesink->cur_image == xvimage) xvimagesink->cur_image = NULL; /* We might have some buffers destroyed after changing state to NULL */ - GST_OBJECT_LOCK (xvimagesink); if (xvimagesink->xcontext == NULL) { GST_DEBUG_OBJECT (xvimagesink, "Destroying XvImage after Xcontext"); #ifdef HAVE_XSHM @@ -293,6 +294,8 @@ gst_xvimage_buffer_finalize (GstXvImageBuffer * xvimage) if (G_UNLIKELY (xvimagesink == NULL)) goto no_sink; + g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink)); + GST_OBJECT_LOCK (xvimagesink); running = xvimagesink->running; GST_OBJECT_UNLOCK (xvimagesink); @@ -389,7 +392,7 @@ 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); + GST_DEBUG ("xvimagesink triggered an XError. error: %s", error_msg); error_caught = TRUE; return 0; } @@ -499,6 +502,7 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps) GstXvImageBuffer *xvimage = NULL; GstStructure *structure = NULL; gboolean succeeded = FALSE; + int (*handler) (Display *, XErrorEvent *); g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), NULL); @@ -528,14 +532,22 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps) g_mutex_lock (xvimagesink->x_lock); + /* Setting an error handler to catch failure */ + error_caught = FALSE; + handler = XSetErrorHandler (gst_xvimagesink_handle_xerror); + #ifdef HAVE_XSHM if (xvimagesink->xcontext->use_xshm) { xvimage->xvimage = XvShmCreateImage (xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, xvimage->im_format, NULL, xvimage->width, xvimage->height, &xvimage->SHMInfo); - if (!xvimage->xvimage) { + if (!xvimage->xvimage || error_caught) { g_mutex_unlock (xvimagesink->x_lock); + /* Reset error handler */ + error_caught = FALSE; + XSetErrorHandler (handler); + /* Push an error */ GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", xvimage->width, xvimage->height), @@ -598,8 +610,12 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps) xvimage->xvimage = XvCreateImage (xvimagesink->xcontext->disp, xvimagesink->xcontext->xv_port_id, xvimage->im_format, NULL, xvimage->width, xvimage->height); - if (!xvimage->xvimage) { + if (!xvimage->xvimage || error_caught) { g_mutex_unlock (xvimagesink->x_lock); + /* Reset error handler */ + error_caught = FALSE; + XSetErrorHandler (handler); + /* Push an error */ GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE, ("Failed to create outputimage buffer of %dx%d pixels", xvimage->width, xvimage->height), @@ -614,6 +630,11 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps) XSync (xvimagesink->xcontext->disp, FALSE); } + + /* Reset error handler */ + error_caught = FALSE; + XSetErrorHandler (handler); + succeeded = TRUE; GST_BUFFER_DATA (xvimage) = (guchar *) xvimage->xvimage->data; @@ -675,12 +696,16 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, gboolean draw_border = FALSE; g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink)); - g_return_if_fail (xvimagesink->xwindow != NULL); /* We take the flow_lock. If expose is in there we don't want to run concurrently from the data flow thread */ g_mutex_lock (xvimagesink->flow_lock); + if (G_UNLIKELY (xvimagesink->xwindow == NULL)) { + g_mutex_unlock (xvimagesink->flow_lock); + return; + } + /* Draw borders when displaying the first frame. After this draw borders only on expose event. */ if (!xvimagesink->cur_image) { @@ -996,10 +1021,12 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink) /* We get all pointer motion events, only the last position is interesting. */ + g_mutex_lock (xvimagesink->flow_lock); g_mutex_lock (xvimagesink->x_lock); while (XCheckWindowEvent (xvimagesink->xcontext->disp, xvimagesink->xwindow->win, PointerMotionMask, &e)) { g_mutex_unlock (xvimagesink->x_lock); + g_mutex_unlock (xvimagesink->flow_lock); switch (e.type) { case MotionNotify: @@ -1010,10 +1037,11 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink) default: break; } - + g_mutex_lock (xvimagesink->flow_lock); g_mutex_lock (xvimagesink->x_lock); } g_mutex_unlock (xvimagesink->x_lock); + g_mutex_unlock (xvimagesink->flow_lock); if (pointer_moved) { GST_DEBUG ("xvimagesink pointer moved over window at %d,%d", @@ -1023,6 +1051,7 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink) } /* We get all events on our window to throw them upstream */ + g_mutex_lock (xvimagesink->flow_lock); g_mutex_lock (xvimagesink->x_lock); while (XCheckWindowEvent (xvimagesink->xcontext->disp, xvimagesink->xwindow->win, @@ -1032,6 +1061,7 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink) /* We lock only for the X function call */ g_mutex_unlock (xvimagesink->x_lock); + g_mutex_unlock (xvimagesink->flow_lock); switch (e.type) { case ButtonPress: @@ -1070,20 +1100,23 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink) default: GST_DEBUG ("xvimagesink unhandled X event (%d)", e.type); } - + g_mutex_lock (xvimagesink->flow_lock); g_mutex_lock (xvimagesink->x_lock); } g_mutex_unlock (xvimagesink->x_lock); + g_mutex_unlock (xvimagesink->flow_lock); /* Handle Expose */ { gboolean exposed = FALSE, configured = FALSE; + g_mutex_lock (xvimagesink->flow_lock); g_mutex_lock (xvimagesink->x_lock); while (XCheckWindowEvent (xvimagesink->xcontext->disp, xvimagesink->xwindow->win, ExposureMask | StructureNotifyMask, &e)) { g_mutex_unlock (xvimagesink->x_lock); + g_mutex_unlock (xvimagesink->flow_lock); switch (e.type) { case Expose: @@ -1094,10 +1127,11 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink) default: break; } - + g_mutex_lock (xvimagesink->flow_lock); g_mutex_lock (xvimagesink->x_lock); } g_mutex_unlock (xvimagesink->x_lock); + g_mutex_unlock (xvimagesink->flow_lock); if (exposed || configured) { gst_xvimagesink_expose (GST_X_OVERLAY (xvimagesink)); @@ -1862,8 +1896,12 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps) GST_VIDEO_SINK_WIDTH (xvimagesink), GST_VIDEO_SINK_HEIGHT (xvimagesink)); /* Notify application to set xwindow id now */ + g_mutex_lock (xvimagesink->flow_lock); if (!xvimagesink->xwindow) { + g_mutex_unlock (xvimagesink->flow_lock); gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (xvimagesink)); + } else { + g_mutex_unlock (xvimagesink->flow_lock); } /* Creating our window and our image with the display size in pixels */ @@ -1874,10 +1912,13 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps) return FALSE; } - if (!xvimagesink->xwindow) + g_mutex_lock (xvimagesink->flow_lock); + if (!xvimagesink->xwindow) { xvimagesink->xwindow = gst_xvimagesink_xwindow_new (xvimagesink, GST_VIDEO_SINK_WIDTH (xvimagesink), GST_VIDEO_SINK_HEIGHT (xvimagesink)); + } + g_mutex_unlock (xvimagesink->flow_lock); /* We renew our xvimage only if size or format changed; * the xvimage is the same size as the video pixel size */ @@ -1936,8 +1977,10 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition) gst_xvimagesink_update_colorbalance (xvimagesink); break; case GST_STATE_CHANGE_READY_TO_PAUSED: + g_mutex_lock (xvimagesink->flow_lock); if (xvimagesink->xwindow) gst_xvimagesink_xwindow_clear (xvimagesink, xvimagesink->xwindow); + g_mutex_unlock (xvimagesink->flow_lock); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; @@ -2325,17 +2368,21 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id) g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink)); + g_mutex_lock (xvimagesink->flow_lock); + /* If we already use that window return */ - if (xvimagesink->xwindow && (xwindow_id == xvimagesink->xwindow->win)) + if (xvimagesink->xwindow && (xwindow_id == xvimagesink->xwindow->win)) { + g_mutex_unlock (xvimagesink->flow_lock); return; + } /* If the element has not initialized the X11 context try to do so */ if (!xvimagesink->xcontext && - !(xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink))) + !(xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink))) { + g_mutex_unlock (xvimagesink->flow_lock); /* we have thrown a GST_ELEMENT_ERROR now */ return; - - g_mutex_lock (xvimagesink->flow_lock); + } gst_xvimagesink_update_colorbalance (xvimagesink); @@ -2399,9 +2446,6 @@ gst_xvimagesink_expose (GstXOverlay * overlay) { GstXvImageSink *xvimagesink = GST_XVIMAGESINK (overlay); - if (!xvimagesink->xwindow) - return; - gst_xvimagesink_xvimage_put (xvimagesink, NULL); } @@ -2413,8 +2457,12 @@ gst_xvimagesink_set_event_handling (GstXOverlay * overlay, xvimagesink->handle_events = handle_events; - if (!xvimagesink->xwindow) + g_mutex_lock (xvimagesink->flow_lock); + + if (G_UNLIKELY (!xvimagesink->xwindow)) { + g_mutex_unlock (xvimagesink->flow_lock); return; + } g_mutex_lock (xvimagesink->x_lock); @@ -2433,6 +2481,8 @@ gst_xvimagesink_set_event_handling (GstXOverlay * overlay, } g_mutex_unlock (xvimagesink->x_lock); + + g_mutex_unlock (xvimagesink->flow_lock); } static void |