ximagesink: Don't access structures of EMPTY caps
[platform/upstream/gstreamer.git] / sys / ximage / ximagesink.c
index 21156a2..aaf7223 100644 (file)
@@ -13,8 +13,8 @@
  *
  * You should have received a copy of the GNU Library General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 /**
 /* Debugging category */
 #include <gst/gstinfo.h>
 
-#include "gst/glib-compat-private.h"
-
 /* for XkbKeycodeToKeysym */
 #include <X11/XKBlib.h>
 
@@ -230,17 +228,17 @@ gst_ximagesink_xwindow_draw_borders (GstXImageSink * ximagesink,
 static gboolean
 gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
 {
-  GstXImageMeta *meta;
+  GstXImageMemory *mem;
   GstVideoCropMeta *crop;
   GstVideoRectangle src, dst, result;
   gboolean draw_border = FALSE;
 
   /* 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 (ximagesink->flow_lock);
+  g_mutex_lock (&ximagesink->flow_lock);
 
   if (G_UNLIKELY (ximagesink->xwindow == NULL)) {
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
     return FALSE;
   }
 
@@ -266,33 +264,33 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
     if (ximagesink->cur_image) {
       ximage = ximagesink->cur_image;
     } else {
-      g_mutex_unlock (ximagesink->flow_lock);
+      g_mutex_unlock (&ximagesink->flow_lock);
       return TRUE;
     }
   }
 
-  meta = gst_buffer_get_ximage_meta (ximage);
+  mem = (GstXImageMemory *) gst_buffer_peek_memory (ximage, 0);
   crop = gst_buffer_get_video_crop_meta (ximage);
 
   if (crop) {
-    src.x = crop->x + meta->x;
-    src.y = crop->y + meta->y;
+    src.x = crop->x + mem->x;
+    src.y = crop->y + mem->y;
     src.w = crop->width;
     src.h = crop->height;
     GST_LOG_OBJECT (ximagesink,
         "crop %dx%d-%dx%d", crop->x, crop->y, crop->width, crop->height);
   } else {
-    src.x = meta->x;
-    src.y = meta->y;
-    src.w = meta->width;
-    src.h = meta->height;
+    src.x = mem->x;
+    src.y = mem->y;
+    src.w = mem->width;
+    src.h = mem->height;
   }
   dst.w = ximagesink->xwindow->width;
   dst.h = ximagesink->xwindow->height;
 
   gst_video_sink_center_rect (src, dst, &result, FALSE);
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
 
   if (draw_border) {
     gst_ximagesink_xwindow_draw_borders (ximagesink, ximagesink->xwindow,
@@ -306,7 +304,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
         ximage, 0, 0, result.x, result.y, result.w, result.h,
         ximagesink->xwindow->width, ximagesink->xwindow->height);
     XShmPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
-        ximagesink->xwindow->gc, meta->ximage, src.x, src.y, result.x, result.y,
+        ximagesink->xwindow->gc, mem->ximage, src.x, src.y, result.x, result.y,
         result.w, result.h, FALSE);
   } else
 #endif /* HAVE_XSHM */
@@ -316,15 +314,15 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
         ximage, 0, 0, result.x, result.y, result.w, result.h,
         ximagesink->xwindow->width, ximagesink->xwindow->height);
     XPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
-        ximagesink->xwindow->gc, meta->ximage, src.x, src.y, result.x, result.y,
+        ximagesink->xwindow->gc, mem->ximage, src.x, src.y, result.x, result.y,
         result.w, result.h);
   }
 
   XSync (ximagesink->xcontext->disp, FALSE);
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
-  g_mutex_unlock (ximagesink->flow_lock);
+  g_mutex_unlock (&ximagesink->flow_lock);
 
   return TRUE;
 }
@@ -339,12 +337,12 @@ gst_ximagesink_xwindow_decorate (GstXImageSink * ximagesink,
   g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), FALSE);
   g_return_val_if_fail (window != NULL, FALSE);
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
 
   hints_atom = XInternAtom (ximagesink->xcontext->disp, "_MOTIF_WM_HINTS",
       True);
   if (hints_atom == None) {
-    g_mutex_unlock (ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
     return FALSE;
   }
 
@@ -359,7 +357,7 @@ gst_ximagesink_xwindow_decorate (GstXImageSink * ximagesink,
 
   XSync (ximagesink->xcontext->disp, FALSE);
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
   g_free (hints);
 
@@ -422,7 +420,7 @@ gst_ximagesink_xwindow_new (GstXImageSink * ximagesink, gint width, gint height)
   xwindow->height = height;
   xwindow->internal = TRUE;
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
 
   xwindow->win = XCreateSimpleWindow (ximagesink->xcontext->disp,
       ximagesink->xcontext->root,
@@ -457,7 +455,7 @@ gst_ximagesink_xwindow_new (GstXImageSink * ximagesink, gint width, gint height)
 
   XSync (ximagesink->xcontext->disp, FALSE);
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
   gst_ximagesink_xwindow_decorate (ximagesink, xwindow);
 
@@ -475,7 +473,7 @@ gst_ximagesink_xwindow_destroy (GstXImageSink * ximagesink,
   g_return_if_fail (xwindow != NULL);
   g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
 
   /* If we did not create that window we just free the GC and let it live */
   if (xwindow->internal)
@@ -487,7 +485,7 @@ gst_ximagesink_xwindow_destroy (GstXImageSink * ximagesink,
 
   XSync (ximagesink->xcontext->disp, FALSE);
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
   g_free (xwindow);
 }
@@ -501,9 +499,9 @@ gst_ximagesink_xwindow_update_geometry (GstXImageSink * ximagesink)
   g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
 
   /* Update the window geometry */
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
   if (G_UNLIKELY (ximagesink->xwindow == NULL)) {
-    g_mutex_unlock (ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
     return;
   }
 
@@ -516,7 +514,7 @@ gst_ximagesink_xwindow_update_geometry (GstXImageSink * ximagesink)
   ximagesink->xwindow->width = attr.width;
   ximagesink->xwindow->height = attr.height;
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
   if (reconfigure)
     gst_pad_push_event (GST_BASE_SINK (ximagesink)->sinkpad,
@@ -529,7 +527,7 @@ gst_ximagesink_xwindow_clear (GstXImageSink * ximagesink, GstXWindow * xwindow)
   g_return_if_fail (xwindow != NULL);
   g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
 
   XSetForeground (ximagesink->xcontext->disp, xwindow->gc,
       ximagesink->xcontext->black);
@@ -539,7 +537,7 @@ gst_ximagesink_xwindow_clear (GstXImageSink * ximagesink, GstXWindow * xwindow)
 
   XSync (ximagesink->xcontext->disp, FALSE);
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 }
 
 /* This function handles XEvents that might be in the queue. It generates
@@ -557,12 +555,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);
+  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);
+    g_mutex_unlock (&ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
 
     switch (e.type) {
       case MotionNotify:
@@ -573,21 +571,21 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
       default:
         break;
     }
-    g_mutex_lock (ximagesink->flow_lock);
-    g_mutex_lock (ximagesink->x_lock);
+    g_mutex_lock (&ximagesink->flow_lock);
+    g_mutex_lock (&ximagesink->x_lock);
   }
 
   if (pointer_moved) {
-    g_mutex_unlock (ximagesink->x_lock);
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
 
     GST_DEBUG ("ximagesink pointer moved over window at %d,%d",
         pointer_x, pointer_y);
     gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink),
         "mouse-move", 0, pointer_x, pointer_y);
 
-    g_mutex_lock (ximagesink->flow_lock);
-    g_mutex_lock (ximagesink->x_lock);
+    g_mutex_lock (&ximagesink->flow_lock);
+    g_mutex_lock (&ximagesink->x_lock);
   }
 
   /* We get all remaining events on our window to throw them upstream */
@@ -599,8 +597,8 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
     const char *key_str = NULL;
 
     /* We lock only for the X function call */
-    g_mutex_unlock (ximagesink->x_lock);
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
 
     switch (e.type) {
       case ButtonPress:
@@ -621,7 +619,7 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
       case KeyRelease:
         /* Key pressed/released over our window. We send upstream
            events for interactivity/navigation */
-        g_mutex_lock (ximagesink->x_lock);
+        g_mutex_lock (&ximagesink->x_lock);
         keysym = XkbKeycodeToKeysym (ximagesink->xcontext->disp,
             e.xkey.keycode, 0, 0);
         if (keysym != NoSymbol) {
@@ -629,7 +627,7 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
         } else {
           key_str = "unknown";
         }
-        g_mutex_unlock (ximagesink->x_lock);
+        g_mutex_unlock (&ximagesink->x_lock);
         GST_DEBUG_OBJECT (ximagesink,
             "key %d pressed over window at %d,%d (%s)",
             e.xkey.keycode, e.xkey.x, e.xkey.y, key_str);
@@ -640,8 +638,8 @@ 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_lock (&ximagesink->flow_lock);
+    g_mutex_lock (&ximagesink->x_lock);
   }
 
   /* Handle Expose */
@@ -652,9 +650,9 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
         exposed = TRUE;
         break;
       case ConfigureNotify:
-        g_mutex_unlock (ximagesink->x_lock);
+        g_mutex_unlock (&ximagesink->x_lock);
         gst_ximagesink_xwindow_update_geometry (ximagesink);
-        g_mutex_lock (ximagesink->x_lock);
+        g_mutex_lock (&ximagesink->x_lock);
         configured = TRUE;
         break;
       default:
@@ -663,13 +661,13 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
   }
 
   if (ximagesink->handle_expose && (exposed || configured)) {
-    g_mutex_unlock (ximagesink->x_lock);
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
 
     gst_ximagesink_expose (GST_VIDEO_OVERLAY (ximagesink));
 
-    g_mutex_lock (ximagesink->flow_lock);
-    g_mutex_lock (ximagesink->x_lock);
+    g_mutex_lock (&ximagesink->flow_lock);
+    g_mutex_lock (&ximagesink->x_lock);
   }
 
   /* Handle Display events */
@@ -687,10 +685,10 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
           GST_ELEMENT_ERROR (ximagesink, RESOURCE, NOT_FOUND,
               ("Output window was closed"), (NULL));
 
-          g_mutex_unlock (ximagesink->x_lock);
+          g_mutex_unlock (&ximagesink->x_lock);
           gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
           ximagesink->xwindow = NULL;
-          g_mutex_lock (ximagesink->x_lock);
+          g_mutex_lock (&ximagesink->x_lock);
         }
         break;
       }
@@ -699,8 +697,8 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
     }
   }
 
-  g_mutex_unlock (ximagesink->x_lock);
-  g_mutex_unlock (ximagesink->flow_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->flow_lock);
 }
 
 static gpointer
@@ -839,12 +837,12 @@ gst_ximagesink_xcontext_get (GstXImageSink * ximagesink)
 
   xcontext = g_new0 (GstXContext, 1);
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
 
   xcontext->disp = XOpenDisplay (ximagesink->display_name);
 
   if (!xcontext->disp) {
-    g_mutex_unlock (ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
     g_free (xcontext);
     GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
         ("Could not initialise X output"), ("Could not open display"));
@@ -874,7 +872,7 @@ gst_ximagesink_xcontext_get (GstXImageSink * ximagesink)
 
   if (!px_formats) {
     XCloseDisplay (xcontext->disp);
-    g_mutex_unlock (ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
     g_free (xcontext->par);
     g_free (xcontext);
     GST_ELEMENT_ERROR (ximagesink, RESOURCE, SETTINGS,
@@ -933,7 +931,7 @@ gst_ximagesink_xcontext_get (GstXImageSink * ximagesink)
         GST_TYPE_FRACTION, nom, den, NULL);
   }
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
   return xcontext;
 
@@ -976,11 +974,11 @@ gst_ximagesink_xcontext_clear (GstXImageSink * ximagesink)
   if (xcontext->last_caps)
     gst_caps_replace (&xcontext->last_caps, NULL);
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
 
   XCloseDisplay (xcontext->disp);
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
   g_free (xcontext);
 }
@@ -996,7 +994,7 @@ gst_ximagesink_getcaps (GstBaseSink * bsink, GstCaps * filter)
 
   ximagesink = GST_XIMAGESINK (bsink);
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
   if (ximagesink->xcontext) {
     GstCaps *caps;
 
@@ -1011,6 +1009,11 @@ gst_ximagesink_getcaps (GstBaseSink * bsink, GstCaps * filter)
       caps = intersection;
     }
 
+    if (gst_caps_is_empty (caps)) {
+      g_mutex_unlock (&ximagesink->x_lock);
+      return caps;
+    }
+
     if (ximagesink->xwindow && ximagesink->xwindow->width) {
       GstStructure *s0, *s1;
 
@@ -1038,10 +1041,10 @@ gst_ximagesink_getcaps (GstBaseSink * bsink, GstCaps * filter)
       }
     }
 
-    g_mutex_unlock (ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
     return caps;
   }
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
   /* get a template copy and add the pixel aspect ratio */
   caps = gst_pad_get_pad_template_caps (GST_BASE_SINK (ximagesink)->sinkpad);
@@ -1079,7 +1082,7 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
   GstBufferPool *newpool, *oldpool;
   const GValue *par;
   gint size;
-  static GstAllocationParams params = { 0, 0, 0, 15, };
+  static GstAllocationParams params = { 0, 15, 0, 0, };
 
   ximagesink = GST_XIMAGESINK (bsink);
 
@@ -1121,12 +1124,12 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
   ximagesink->fps_d = info.fps_d;
 
   /* Notify application to set xwindow id now */
-  g_mutex_lock (ximagesink->flow_lock);
+  g_mutex_lock (&ximagesink->flow_lock);
   if (!ximagesink->xwindow) {
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
     gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (ximagesink));
   } else {
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
   }
 
   /* Creating our window and our image */
@@ -1134,7 +1137,7 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
       GST_VIDEO_SINK_HEIGHT (ximagesink) <= 0)
     goto invalid_size;
 
-  g_mutex_lock (ximagesink->flow_lock);
+  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));
@@ -1159,7 +1162,7 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
    * has configured the pool. If downstream does not want our pool we will
    * activate it when we render into it */
   ximagesink->pool = newpool;
-  g_mutex_unlock (ximagesink->flow_lock);
+  g_mutex_unlock (&ximagesink->flow_lock);
 
   /* unref the old sink */
   if (oldpool) {
@@ -1195,7 +1198,7 @@ invalid_size:
 config_failed:
   {
     GST_ERROR_OBJECT (ximagesink, "failed to set config.");
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
     return FALSE;
   }
 }
@@ -1227,16 +1230,16 @@ gst_ximagesink_change_state (GstElement * element, GstStateChange transition)
       /* call XSynchronize with the current value of synchronous */
       GST_DEBUG_OBJECT (ximagesink, "XSynchronize called with %s",
           ximagesink->synchronous ? "TRUE" : "FALSE");
-      g_mutex_lock (ximagesink->x_lock);
+      g_mutex_lock (&ximagesink->x_lock);
       XSynchronize (ximagesink->xcontext->disp, ximagesink->synchronous);
-      g_mutex_unlock (ximagesink->x_lock);
+      g_mutex_unlock (&ximagesink->x_lock);
       gst_ximagesink_manage_event_thread (ximagesink);
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
-      g_mutex_lock (ximagesink->flow_lock);
+      g_mutex_lock (&ximagesink->flow_lock);
       if (ximagesink->xwindow)
         gst_ximagesink_xwindow_clear (ximagesink, ximagesink->xwindow);
-      g_mutex_unlock (ximagesink->flow_lock);
+      g_mutex_unlock (&ximagesink->flow_lock);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       break;
@@ -1254,10 +1257,10 @@ gst_ximagesink_change_state (GstElement * element, GstStateChange transition)
       ximagesink->fps_d = 1;
       GST_VIDEO_SINK_WIDTH (ximagesink) = 0;
       GST_VIDEO_SINK_HEIGHT (ximagesink) = 0;
-      g_mutex_lock (ximagesink->flow_lock);
+      g_mutex_lock (&ximagesink->flow_lock);
       if (ximagesink->pool)
         gst_buffer_pool_set_active (ximagesink->pool, FALSE);
-      g_mutex_unlock (ximagesink->flow_lock);
+      g_mutex_unlock (&ximagesink->flow_lock);
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       gst_ximagesink_reset (ximagesink);
@@ -1297,14 +1300,15 @@ gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 {
   GstFlowReturn res;
   GstXImageSink *ximagesink;
-  GstXImageMeta *meta;
+  GstXImageMemory *mem;
   GstBuffer *to_put = NULL;
 
   ximagesink = GST_XIMAGESINK (vsink);
 
-  meta = gst_buffer_get_ximage_meta (buf);
-
-  if (meta && meta->sink == ximagesink) {
+  if (gst_buffer_n_memory (buf) == 1
+      && (mem = (GstXImageMemory *) gst_buffer_peek_memory (buf, 0))
+      && g_strcmp0 (mem->parent.allocator->mem_type, "ximage") == 0
+      && mem->sink == ximagesink) {
     /* If this buffer has been allocated using our buffer management we simply
        put the ximage which is in the PRIVATE pointer */
     GST_LOG_OBJECT (ximagesink, "buffer from our pool, writing directly");
@@ -1312,6 +1316,7 @@ gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
     res = GST_FLOW_OK;
   } else {
     GstVideoFrame src, dest;
+    GstBufferPoolAcquireParams params = { 0, };
 
     /* Else we have to copy the data into our private image, */
     /* if we have one... */
@@ -1324,8 +1329,11 @@ gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
     if (!gst_buffer_pool_set_active (ximagesink->pool, TRUE))
       goto activate_failed;
 
-    /* take a buffer from our pool */
-    res = gst_buffer_pool_acquire_buffer (ximagesink->pool, &to_put, NULL);
+    /* take a buffer from our pool, if there is no buffer in the pool something
+     * is seriously wrong, waiting for the pool here might deadlock when we try
+     * to go to PAUSED because we never flush the pool. */
+    params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
+    res = gst_buffer_pool_acquire_buffer (ximagesink->pool, &to_put, &params);
     if (res != GST_FLOW_OK)
       goto no_buffer;
 
@@ -1367,12 +1375,12 @@ no_buffer:
   {
     /* No image available. That's very bad ! */
     GST_WARNING_OBJECT (ximagesink, "could not create image");
-    return res;
+    return GST_FLOW_OK;
   }
 invalid_buffer:
   {
     /* No Window available to put our image into */
-    GST_WARNING_OBJECT (ximagesink, "could map image");
+    GST_WARNING_OBJECT (ximagesink, "could not map image");
     res = GST_FLOW_OK;
     goto done;
   }
@@ -1434,10 +1442,10 @@ gst_ximagesink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
   if (caps == NULL)
     goto no_caps;
 
-  g_mutex_lock (ximagesink->flow_lock);
+  g_mutex_lock (&ximagesink->flow_lock);
   if ((pool = ximagesink->pool))
     gst_object_ref (pool);
-  g_mutex_unlock (ximagesink->flow_lock);
+  g_mutex_unlock (&ximagesink->flow_lock);
 
   if (pool != NULL) {
     GstCaps *pcaps;
@@ -1459,12 +1467,12 @@ gst_ximagesink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
   if (pool == NULL && need_pool) {
     GstVideoInfo info;
 
-    GST_DEBUG_OBJECT (ximagesink, "create new pool");
-    pool = gst_ximage_buffer_pool_new (ximagesink);
-
     if (!gst_video_info_from_caps (&info, caps))
       goto invalid_caps;
 
+    GST_DEBUG_OBJECT (ximagesink, "create new pool");
+    pool = gst_ximage_buffer_pool_new (ximagesink);
+
     /* the normal size of a frame */
     size = info.size;
 
@@ -1473,14 +1481,15 @@ gst_ximagesink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
     if (!gst_buffer_pool_set_config (pool, config))
       goto config_failed;
   }
-  /* we need at least 2 buffer because we hold on to the last one */
-  gst_query_add_allocation_pool (query, pool, size, 2, 0);
+  if (pool) {
+    /* we need at least 2 buffer because we hold on to the last one */
+    gst_query_add_allocation_pool (query, pool, size, 2, 0);
+    gst_object_unref (pool);
+  }
 
   /* we also support various metadata */
-  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE);
-  gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE);
-
-  gst_object_unref (pool);
+  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
+  gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL);
 
   return TRUE;
 
@@ -1498,6 +1507,7 @@ invalid_caps:
 config_failed:
   {
     GST_DEBUG_OBJECT (bsink, "failed setting config");
+    gst_object_unref (pool);
     return FALSE;
   }
 }
@@ -1522,17 +1532,17 @@ gst_ximagesink_navigation_send_event (GstNavigation * navigation,
      is centered in the window.  */
 
   /* We take the flow_lock while we look at the window */
-  g_mutex_lock (ximagesink->flow_lock);
+  g_mutex_lock (&ximagesink->flow_lock);
 
   if (!ximagesink->xwindow) {
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
     return;
   }
 
   x_offset = ximagesink->xwindow->width - GST_VIDEO_SINK_WIDTH (ximagesink);
   y_offset = ximagesink->xwindow->height - GST_VIDEO_SINK_HEIGHT (ximagesink);
 
-  g_mutex_unlock (ximagesink->flow_lock);
+  g_mutex_unlock (&ximagesink->flow_lock);
 
   if (x_offset > 0 && gst_structure_get_double (structure, "pointer_x", &x)) {
     x -= x_offset / 2;
@@ -1569,18 +1579,18 @@ gst_ximagesink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
   /* 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);
+  g_mutex_lock (&ximagesink->flow_lock);
 
   /* If we already use that window return */
   if (ximagesink->xwindow && (xwindow_id == ximagesink->xwindow->win)) {
-    g_mutex_unlock (ximagesink->flow_lock);
+    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))) {
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
     /* we have thrown a GST_ELEMENT_ERROR now */
     return;
   }
@@ -1607,7 +1617,7 @@ gst_ximagesink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
 
     /* We get window geometry, set the event we want to receive,
        and create a GC */
-    g_mutex_lock (ximagesink->x_lock);
+    g_mutex_lock (&ximagesink->x_lock);
     XGetWindowAttributes (ximagesink->xcontext->disp, xwindow->win, &attr);
     xwindow->width = attr.width;
     xwindow->height = attr.height;
@@ -1619,13 +1629,13 @@ gst_ximagesink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
     }
 
     xwindow->gc = XCreateGC (ximagesink->xcontext->disp, xwindow->win, 0, NULL);
-    g_mutex_unlock (ximagesink->x_lock);
+    g_mutex_unlock (&ximagesink->x_lock);
   }
 
   if (xwindow)
     ximagesink->xwindow = xwindow;
 
-  g_mutex_unlock (ximagesink->flow_lock);
+  g_mutex_unlock (&ximagesink->flow_lock);
 }
 
 static void
@@ -1645,14 +1655,14 @@ gst_ximagesink_set_event_handling (GstVideoOverlay * overlay,
 
   ximagesink->handle_events = handle_events;
 
-  g_mutex_lock (ximagesink->flow_lock);
+  g_mutex_lock (&ximagesink->flow_lock);
 
   if (G_UNLIKELY (!ximagesink->xwindow)) {
-    g_mutex_unlock (ximagesink->flow_lock);
+    g_mutex_unlock (&ximagesink->flow_lock);
     return;
   }
 
-  g_mutex_lock (ximagesink->x_lock);
+  g_mutex_lock (&ximagesink->x_lock);
 
   if (handle_events) {
     if (ximagesink->xwindow->internal) {
@@ -1668,9 +1678,9 @@ gst_ximagesink_set_event_handling (GstVideoOverlay * overlay,
     XSelectInput (ximagesink->xcontext->disp, ximagesink->xwindow->win, 0);
   }
 
-  g_mutex_unlock (ximagesink->x_lock);
+  g_mutex_unlock (&ximagesink->x_lock);
 
-  g_mutex_unlock (ximagesink->flow_lock);
+  g_mutex_unlock (&ximagesink->flow_lock);
 }
 
 static void
@@ -1706,9 +1716,9 @@ gst_ximagesink_set_property (GObject * object, guint prop_id,
       if (ximagesink->xcontext) {
         GST_DEBUG_OBJECT (ximagesink, "XSynchronize called with %s",
             ximagesink->synchronous ? "TRUE" : "FALSE");
-        g_mutex_lock (ximagesink->x_lock);
+        g_mutex_lock (&ximagesink->x_lock);
         XSynchronize (ximagesink->xcontext->disp, ximagesink->synchronous);
-        g_mutex_unlock (ximagesink->x_lock);
+        g_mutex_unlock (&ximagesink->x_lock);
       }
       break;
     case PROP_FORCE_ASPECT_RATIO:
@@ -1818,7 +1828,7 @@ gst_ximagesink_reset (GstXImageSink * ximagesink)
     ximagesink->cur_image = NULL;
   }
 
-  g_mutex_lock (ximagesink->flow_lock);
+  g_mutex_lock (&ximagesink->flow_lock);
 
   if (ximagesink->pool) {
     gst_object_unref (ximagesink->pool);
@@ -1830,7 +1840,7 @@ gst_ximagesink_reset (GstXImageSink * ximagesink)
     gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
     ximagesink->xwindow = NULL;
   }
-  g_mutex_unlock (ximagesink->flow_lock);
+  g_mutex_unlock (&ximagesink->flow_lock);
 
   gst_ximagesink_xcontext_clear (ximagesink);
 }
@@ -1852,14 +1862,8 @@ gst_ximagesink_finalize (GObject * object)
     g_free (ximagesink->par);
     ximagesink->par = NULL;
   }
-  if (ximagesink->x_lock) {
-    g_mutex_free (ximagesink->x_lock);
-    ximagesink->x_lock = NULL;
-  }
-  if (ximagesink->flow_lock) {
-    g_mutex_free (ximagesink->flow_lock);
-    ximagesink->flow_lock = NULL;
-  }
+  g_mutex_clear (&ximagesink->x_lock);
+  g_mutex_clear (&ximagesink->flow_lock);
 
   g_free (ximagesink->media_title);
 
@@ -1880,15 +1884,15 @@ gst_ximagesink_init (GstXImageSink * ximagesink)
   ximagesink->fps_n = 0;
   ximagesink->fps_d = 1;
 
-  ximagesink->x_lock = g_mutex_new ();
-  ximagesink->flow_lock = g_mutex_new ();
+  g_mutex_init (&ximagesink->x_lock);
+  g_mutex_init (&ximagesink->flow_lock);
 
   ximagesink->par = NULL;
 
   ximagesink->pool = NULL;
 
   ximagesink->synchronous = FALSE;
-  ximagesink->keep_aspect = FALSE;
+  ximagesink->keep_aspect = TRUE;
   ximagesink->handle_events = TRUE;
   ximagesink->handle_expose = TRUE;
 }
@@ -1921,7 +1925,7 @@ gst_ximagesink_class_init (GstXImageSinkClass * klass)
   g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
       g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
           "When enabled, reverse caps negotiation (scaling) will respect "
-          "original aspect ratio", FALSE,
+          "original aspect ratio", TRUE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
       g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio",