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);
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;
* 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);
"Unknown bit depth %d for Xv Colorkey - not adjusting", bits);
}
todo--;
+ xvimagesink->have_colorkey = TRUE;
}
XFree (attr);
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;
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);
switch (prop_id) {
case ARG_DEVICE:
+ case ARG_AUTOPAINT_COLORKEY:
+ case ARG_DOUBLE_BUFFER:
+ case ARG_COLORKEY:
if (xvimagesink->xcontext != NULL) {
ret = FALSE;
} else {
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;
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;
xvimagesink->handle_expose = TRUE;
xvimagesink->autopaint_colorkey = TRUE;
- xvimagesink->colorkey = -1;
+ xvimagesink->colorkey = (1 << 16) | (2 << 8) | 3;;
xvimagesink->draw_borders = TRUE;
}
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
#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;
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);
}
}
}
+}
+
+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;
}
GtkWidget *window;
GstElement *pipeline, *src;
GstBus *bus;
+ GstStateChangeReturn sret;
+ GstPropertyProbe *probe;
+ GValueArray *arr;
if (!g_thread_supported ())
g_thread_init (NULL);
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,
/* 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);