Allow setting colorkey if possible. Implement property probe interface for optional...
authorStefan Kost <ensonic@users.sourceforge.net>
Wed, 22 Oct 2008 12:25:02 +0000 (12:25 +0000)
committerStefan Kost <ensonic@users.sourceforge.net>
Wed, 22 Oct 2008 12:25:02 +0000 (12:25 +0000)
Original commit message from CVS:
* sys/xvimage/xvimagesink.c:
* sys/xvimage/xvimagesink.h:
* tests/icles/Makefile.am:
* tests/icles/test-colorkey.c:
Allow setting colorkey if possible. Implement property probe interface
for optional X features (autopaint-colorkey, double-buffer and
colorkey). Fixes #554533

ChangeLog
sys/xvimage/xvimagesink.c
sys/xvimage/xvimagesink.h
tests/icles/Makefile.am
tests/icles/test-colorkey.c

index 8ca65c7..709a309 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-10-22  Stefan Kost  <ensonic@users.sf.net>
+
+       * sys/xvimage/xvimagesink.c:
+       * sys/xvimage/xvimagesink.h:
+       * tests/icles/Makefile.am:
+       * tests/icles/test-colorkey.c:
+         Allow setting colorkey if possible. Implement property probe interface
+         for optional X features (autopaint-colorkey, double-buffer and
+         colorkey). Fixes #554533
+
 2008-10-22  Sebastian Dröge  <slomo@circular-chaos.org>
 
        * gst-libs/gst/tag/tags.c: (gst_tag_image_data_to_image_buffer):
index 0b87a2b..9c0c5e0 100644 (file)
@@ -1363,6 +1363,10 @@ gst_xvimagesink_get_xv_support (GstXvImageSink * xvimagesink,
 
     GST_DEBUG_OBJECT (xvimagesink, "Checking %d Xv port attributes", count);
 
+    xvimagesink->have_autopaint_colorkey = FALSE;
+    xvimagesink->have_double_buffer = FALSE;
+    xvimagesink->have_colorkey = FALSE;
+
     for (i = 0; ((i < count) && todo); i++)
       if (!strcmp (attr[i].name, autopaint)) {
         const Atom atom = XInternAtom (xcontext->disp, autopaint, False);
@@ -1371,20 +1375,25 @@ gst_xvimagesink_get_xv_support (GstXvImageSink * xvimagesink,
         XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom,
             (xvimagesink->autopaint_colorkey ? 1 : 0));
         todo--;
+        xvimagesink->have_autopaint_colorkey = TRUE;
       } else if (!strcmp (attr[i].name, dbl_buffer)) {
         const Atom atom = XInternAtom (xcontext->disp, dbl_buffer, False);
 
         XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom,
             (xvimagesink->double_buffer ? 1 : 0));
         todo--;
+        xvimagesink->have_double_buffer = TRUE;
       } else if (!strcmp (attr[i].name, colorkey)) {
-        /* Set the colorkey to something that is dark but hopefully won't randomly
-         * appear on the screen elsewhere (ie not black or greys) */
+        /* Set the colorkey, default is something that is dark but hopefully
+         * won't randomly appear on the screen elsewhere (ie not black or greys)
+         * can be overridden by setting "colorkey" property
+         */
         const Atom atom = XInternAtom (xcontext->disp, colorkey, False);
         guint32 ckey = 0;
         guint32 keymask;
         gint bits;
         gboolean set_attr = TRUE;
+        guint cr, cg, cb;
 
         /* Count the bits in the colorkey mask 'max' value */
         bits = 0;
@@ -1397,15 +1406,16 @@ gst_xvimagesink_get_xv_support (GstXvImageSink * xvimagesink,
          * depth (xcontext->depth). We only handle these 2 cases, because
          * they're the only types of devices we've encountered. If we don't
          * recognise it, leave it alone  */
+        cr = (xvimagesink->colorkey >> 16);
+        cg = (xvimagesink->colorkey >> 8) & 0xFF;
+        cb = (xvimagesink->colorkey) & 0xFF;
         if (bits == 16)
-          ckey = (1 << 11) | (2 << 5) | 3;
+          ckey = (cr << 11) | (cg << 5) | cb;
         else if (bits == 24 || bits == 32)
-          ckey = (1 << 16) | (2 << 8) | 3;
+          ckey = (cr << 16) | (cg << 8) | cb;
         else
           set_attr = FALSE;
 
-        xvimagesink->colorkey = (1 << 16) | (2 << 8) | 3;
-
         if (set_attr) {
           ckey = CLAMP (ckey, (guint32) attr[i].min_value,
               (guint32) attr[i].max_value);
@@ -1420,6 +1430,7 @@ gst_xvimagesink_get_xv_support (GstXvImageSink * xvimagesink,
               "Unknown bit depth %d for Xv Colorkey - not adjusting", bits);
         }
         todo--;
+        xvimagesink->have_colorkey = TRUE;
       }
 
     XFree (attr);
@@ -2734,6 +2745,14 @@ gst_xvimagesink_probe_get_properties (GstPropertyProbe * probe)
 
   if (!list) {
     list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
+    list =
+        g_list_append (list, g_object_class_find_property (klass,
+            "autopaint-colorkey"));
+    list =
+        g_list_append (list, g_object_class_find_property (klass,
+            "double-buffer"));
+    list =
+        g_list_append (list, g_object_class_find_property (klass, "colorkey"));
   }
 
   return list;
@@ -2747,7 +2766,11 @@ gst_xvimagesink_probe_probe_property (GstPropertyProbe * probe,
 
   switch (prop_id) {
     case ARG_DEVICE:
-      GST_DEBUG_OBJECT (xvimagesink, "probing device list");
+    case ARG_AUTOPAINT_COLORKEY:
+    case ARG_DOUBLE_BUFFER:
+    case ARG_COLORKEY:
+      GST_DEBUG_OBJECT (xvimagesink,
+          "probing device list and get capabilities");
       if (!xvimagesink->xcontext) {
         GST_DEBUG_OBJECT (xvimagesink, "generating xcontext");
         xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink);
@@ -2768,6 +2791,9 @@ gst_xvimagesink_probe_needs_probe (GstPropertyProbe * probe,
 
   switch (prop_id) {
     case ARG_DEVICE:
+    case ARG_AUTOPAINT_COLORKEY:
+    case ARG_DOUBLE_BUFFER:
+    case ARG_COLORKEY:
       if (xvimagesink->xcontext != NULL) {
         ret = FALSE;
       } else {
@@ -2814,6 +2840,43 @@ gst_xvimagesink_probe_get_values (GstPropertyProbe * probe,
       g_value_unset (&value);
       break;
     }
+    case ARG_AUTOPAINT_COLORKEY:
+      if (xvimagesink->have_autopaint_colorkey) {
+        GValue value = { 0 };
+
+        array = g_value_array_new (2);
+        g_value_init (&value, G_TYPE_BOOLEAN);
+        g_value_set_boolean (&value, FALSE);
+        g_value_array_append (array, &value);
+        g_value_set_boolean (&value, TRUE);
+        g_value_array_append (array, &value);
+        g_value_unset (&value);
+      }
+      break;
+    case ARG_DOUBLE_BUFFER:
+      if (xvimagesink->have_double_buffer) {
+        GValue value = { 0 };
+
+        array = g_value_array_new (2);
+        g_value_init (&value, G_TYPE_BOOLEAN);
+        g_value_set_boolean (&value, FALSE);
+        g_value_array_append (array, &value);
+        g_value_set_boolean (&value, TRUE);
+        g_value_array_append (array, &value);
+        g_value_unset (&value);
+      }
+      break;
+    case ARG_COLORKEY:
+      if (xvimagesink->have_colorkey) {
+        GValue value = { 0 };
+
+        array = g_value_array_new (1);
+        g_value_init (&value, GST_TYPE_INT_RANGE);
+        gst_value_set_int_range (&value, 0, 0xffffff);
+        g_value_array_append (array, &value);
+        g_value_unset (&value);
+      }
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
       break;
@@ -2912,6 +2975,9 @@ gst_xvimagesink_set_property (GObject * object, guint prop_id,
     case ARG_AUTOPAINT_COLORKEY:
       xvimagesink->autopaint_colorkey = g_value_get_boolean (value);
       break;
+    case ARG_COLORKEY:
+      xvimagesink->colorkey = g_value_get_int (value);
+      break;
     case ARG_DRAW_BORDERS:
       xvimagesink->draw_borders = g_value_get_boolean (value);
       break;
@@ -3106,7 +3172,7 @@ gst_xvimagesink_init (GstXvImageSink * xvimagesink)
   xvimagesink->handle_expose = TRUE;
   xvimagesink->autopaint_colorkey = TRUE;
 
-  xvimagesink->colorkey = -1;
+  xvimagesink->colorkey = (1 << 16) | (2 << 8) | 3;;
   xvimagesink->draw_borders = TRUE;
 }
 
@@ -3224,7 +3290,7 @@ gst_xvimagesink_class_init (GstXvImageSinkClass * klass)
   g_object_class_install_property (gobject_class, ARG_COLORKEY,
       g_param_spec_int ("colorkey", "Colorkey",
           "Color to use for the overlay mask", G_MININT, G_MAXINT, 0,
-          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   /**
    * GstXvImageSink:draw-borders
index eec17c6..84ae006 100644 (file)
@@ -271,6 +271,11 @@ struct _GstXvImageSink {
   gint colorkey;
   
   gboolean draw_borders;
+  
+  /* port features */
+  gboolean have_autopaint_colorkey;
+  gboolean have_colorkey;
+  gboolean have_double_buffer;
 };
 
 struct _GstXvImageSinkClass {
index 47a3cac..b06e967 100644 (file)
@@ -19,7 +19,6 @@ else
 X_TESTS =
 endif
 
-
 if USE_PANGO
 PANGO_TESTS = test-textoverlay
 
index 1b452f6..08a8b23 100644 (file)
 #endif
 
 #include <stdlib.h>
+#include <string.h>
+
 #include <glib.h>
+#include <gdk/gdkx.h>
 #include <gtk/gtk.h>
-#include <gst/gst.h>
-#include <string.h>
 
 #include <X11/Xlib.h>
-#include <gdk/gdkx.h>
+
+#include <gst/gst.h>
 #include <gst/interfaces/xoverlay.h>
+#include <gst/interfaces/propertyprobe.h>
 
 static GtkWidget *video_window = NULL;
 static GstElement *sink = NULL;
@@ -61,8 +64,8 @@ bus_sync_handler (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
   return GST_BUS_PASS;
 }
 
-static gboolean
-handle_resize_cb (GtkWidget * widget, GdkEventConfigure * event, gpointer data)
+static void
+redraw_overlay (GtkWidget * widget)
 {
   gdk_draw_rectangle (widget->window, widget->style->white_gc, TRUE,
       0, 0, widget->allocation.width, widget->allocation.height);
@@ -82,6 +85,19 @@ handle_resize_cb (GtkWidget * widget, GdkEventConfigure * event, gpointer data)
       }
     }
   }
+}
+
+static gboolean
+handle_resize_cb (GtkWidget * widget, GdkEventConfigure * event, gpointer data)
+{
+  redraw_overlay (widget);
+  return FALSE;
+}
+
+static gboolean
+handle_expose_cb (GtkWidget * widget, GdkEventExpose * event, gpointer data)
+{
+  redraw_overlay (widget);
   return FALSE;
 }
 
@@ -138,6 +154,9 @@ main (int argc, char **argv)
   GtkWidget *window;
   GstElement *pipeline, *src;
   GstBus *bus;
+  GstStateChangeReturn sret;
+  GstPropertyProbe *probe;
+  GValueArray *arr;
 
   if (!g_thread_supported ())
     g_thread_init (NULL);
@@ -158,9 +177,35 @@ main (int argc, char **argv)
   gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
   gst_element_link (src, sink);
 
-  g_object_set (G_OBJECT (sink),
-      "autopaint-colorkey", FALSE,
-      "force-aspect-ratio", TRUE, "draw-borders", FALSE, NULL);
+  g_object_set (G_OBJECT (sink), "autopaint-colorkey", FALSE, "force-aspect-ratio", TRUE, "draw-borders", FALSE, "colorkey", 0x7F7F7F,  /* gray */
+      NULL);
+
+  /* check xvimagesink capabilities */
+  sret = gst_element_set_state (pipeline, GST_STATE_READY);
+  if (sret == GST_STATE_CHANGE_FAILURE) {
+    g_printerr ("Can't set pipelien to READY\n");
+    gst_object_unref (pipeline);
+    return -1;
+  }
+
+  probe = GST_PROPERTY_PROBE (sink);
+  if (!probe) {
+    g_printerr ("Can't probe sink\n");
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+    return -1;
+  }
+  arr =
+      gst_property_probe_probe_and_get_values_name (probe,
+      "autopaint-colorkey");
+  if (!arr || !arr->n_values) {
+    g_printerr ("Can't disable autopaint-colorkey property\n");
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+    return -1;
+  }
+  if (arr)
+    g_value_array_free (arr);
 
   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
   gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler,
@@ -173,21 +218,27 @@ main (int argc, char **argv)
   /* prepare the ui */
 
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  video_window = gtk_drawing_area_new ();
-  gtk_widget_set_double_buffered (video_window, FALSE);
-
-  gtk_window_set_default_size (GTK_WINDOW (window), 320, 240);
-  gtk_container_add (GTK_CONTAINER (window), video_window);
   g_signal_connect (G_OBJECT (window), "delete-event",
       G_CALLBACK (window_closed), (gpointer) pipeline);
+  gtk_window_set_default_size (GTK_WINDOW (window), 320, 240);
+
+  video_window = gtk_drawing_area_new ();
   g_signal_connect (G_OBJECT (video_window), "configure-event",
       G_CALLBACK (handle_resize_cb), NULL);
+  g_signal_connect (G_OBJECT (video_window), "expose-event",
+      G_CALLBACK (handle_expose_cb), NULL);
+  gtk_widget_set_double_buffered (video_window, FALSE);
+  gtk_container_add (GTK_CONTAINER (window), video_window);
 
-  /* show the gui. */
-  gtk_widget_show_all (window);
+  /* show the gui and play */
 
-  //connect_bus_signals (pipeline);
-  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+  gtk_widget_show_all (window);
+  sret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+  if (sret == GST_STATE_CHANGE_FAILURE) {
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+    return -1;
+  }
   gtk_main ();
   gst_object_unref (pipeline);