ximagesink: Ask pad peer to accept new caps once only
authorPhilippe Normand <pnormand@igalia.com>
Mon, 14 Jun 2010 10:27:02 +0000 (12:27 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 18 Jun 2010 04:11:36 +0000 (06:11 +0200)
In buffer_alloc, if the buffer caps are new, call
gst_pad_peer_accept_caps once only, it's useless to call it in the
cases where we know it will always fail.

Fixes bug #621190

sys/ximage/ximagesink.c
sys/ximage/ximagesink.h

index f8bcf57..0e768b0 100644 (file)
@@ -1396,6 +1396,9 @@ gst_ximagesink_xcontext_clear (GstXImageSink * ximagesink)
   g_free (ximagesink->par);
   ximagesink->par = NULL;
 
+  if (xcontext->last_caps)
+    gst_caps_replace (&xcontext->last_caps, NULL);
+
   g_mutex_lock (ximagesink->x_lock);
 
   XCloseDisplay (xcontext->disp);
@@ -1770,6 +1773,7 @@ gst_ximagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
   gboolean alloc_unref = FALSE;
   gint width, height;
   GstVideoRectangle dst, src, result;
+  gboolean caps_accepted = FALSE;
 
   ximagesink = GST_XIMAGESINK (bsink);
 
@@ -1856,10 +1860,22 @@ gst_ximagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
           GST_TYPE_FRACTION, nom, den, NULL);
     }
 
+
     /* see if peer accepts our new suggestion, if there is no peer, this 
      * function returns true. */
-    if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (ximagesink),
-            desired_caps)) {
+    if (!ximagesink->xcontext->last_caps ||
+        !gst_caps_is_equal (desired_caps, ximagesink->xcontext->last_caps)) {
+      caps_accepted =
+          gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (ximagesink),
+          desired_caps);
+
+      /* Suggestion failed, prevent future attempts for the same caps
+       * to fail as well. */
+      if (!caps_accepted)
+        gst_caps_replace (&ximagesink->xcontext->last_caps, desired_caps);
+    }
+
+    if (caps_accepted) {
       /* we will not alloc a buffer of the new suggested caps. Make sure
        * we also unref this new caps after we set it on the buffer. */
       alloc_caps = desired_caps;
@@ -2414,24 +2430,16 @@ gst_ximagesink_get_type (void)
       (GClassInitFunc) gst_ximagesink_class_init,
       NULL,
       NULL,
-      sizeof (GstXImageSink),
-      0,
-      (GInstanceInitFunc) gst_ximagesink_init,
+      sizeof (GstXImageSink), 0, (GInstanceInitFunc) gst_ximagesink_init,
     };
     static const GInterfaceInfo iface_info = {
-      (GInterfaceInitFunc) gst_ximagesink_interface_init,
-      NULL,
-      NULL,
+      (GInterfaceInitFunc) gst_ximagesink_interface_init, NULL, NULL,
     };
     static const GInterfaceInfo navigation_info = {
-      (GInterfaceInitFunc) gst_ximagesink_navigation_init,
-      NULL,
-      NULL,
+      (GInterfaceInitFunc) gst_ximagesink_navigation_init, NULL, NULL,
     };
     static const GInterfaceInfo overlay_info = {
-      (GInterfaceInitFunc) gst_ximagesink_xoverlay_init,
-      NULL,
-      NULL,
+      (GInterfaceInitFunc) gst_ximagesink_xoverlay_init, NULL, NULL,
     };
 
     ximagesink_type = g_type_register_static (GST_TYPE_VIDEO_SINK,
index 75e5f52..83e973f 100644 (file)
@@ -39,7 +39,6 @@
 #include <math.h>
 
 G_BEGIN_DECLS
-
 #define GST_TYPE_XIMAGESINK \
   (gst_ximagesink_get_type())
 #define GST_XIMAGESINK(obj) \
@@ -50,7 +49,6 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_XIMAGESINK))
 #define GST_IS_XIMAGESINK_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_XIMAGESINK))
-
 typedef struct _GstXContext GstXContext;
 typedef struct _GstXWindow GstXWindow;
 
@@ -85,7 +83,8 @@ typedef struct _GstXImageSinkClass GstXImageSinkClass;
  * Structure used to store various informations collected/calculated for a
  * Display.
  */
-struct _GstXContext {
+struct _GstXContext
+{
   Display *disp;
 
   Screen *screen;
@@ -108,6 +107,7 @@ struct _GstXContext {
   gboolean use_xshm;
 
   GstCaps *caps;
+  GstCaps *last_caps;
 };
 
 /*
@@ -121,7 +121,8 @@ struct _GstXContext {
  *
  * Structure used to store informations about a Window.
  */
-struct _GstXWindow {
+struct _GstXWindow
+{
   Window win;
   gint width, height;
   gboolean internal;
@@ -138,7 +139,8 @@ struct _GstXWindow {
  *
  * Subclass of #GstBuffer containing additional information about an XImage.
  */
-struct _GstXImageBuffer {
+struct _GstXImageBuffer
+{
   GstBuffer buffer;
 
   /* Reference to the ximagesink we belong to */
@@ -148,7 +150,7 @@ struct _GstXImageBuffer {
 
 #ifdef HAVE_XSHM
   XShmSegmentInfo SHMInfo;
-#endif /* HAVE_XSHM */
+#endif                          /* HAVE_XSHM */
 
   gint width, height;
   size_t size;
@@ -183,7 +185,8 @@ struct _GstXImageBuffer {
  *
  * The #GstXImageSink data structure.
  */
-struct _GstXImageSink {
+struct _GstXImageSink
+{
   /* Our element stuff */
   GstVideoSink videosink;
 
@@ -193,7 +196,7 @@ struct _GstXImageSink {
   GstXWindow *xwindow;
   GstXImageBuffer *ximage;
   GstXImageBuffer *cur_image;
-  
+
   GThread *event_thread;
   gboolean running;
 
@@ -203,7 +206,7 @@ struct _GstXImageSink {
 
   GMutex *x_lock;
   GMutex *flow_lock;
-  
+
   /* object-set pixel aspect ratio */
   GValue *par;
 
@@ -215,17 +218,17 @@ struct _GstXImageSink {
   gboolean handle_events;
   gboolean handle_expose;
   gboolean draw_border;
-  
+
   /* stream metadata */
   gchar *media_title;
 };
 
-struct _GstXImageSinkClass {
+struct _GstXImageSinkClass
+{
   GstVideoSinkClass parent_class;
 };
 
-GType gst_ximagesink_get_type(void);
+GType gst_ximagesink_get_type (void);
 
 G_END_DECLS
-
 #endif /* __GST_XIMAGESINK_H__ */