[gst-devel] GstXOverlay/gtk+ issues

Florian Schmidt mista.tapas at gmx.net
Thu Feb 2 09:53:04 CET 2006


Hi,

i have a small problem which the following code serves as a test case
for. You can also download it here: 

http://affenbande.org/~tapas/test_overlay.cc

Using the overlay seems to be straight forward, but i have the issue
that sometimes after switching from fullscreen back to windowed (press f
to toggle fullscreen), the screen simply stays black (which is the bg
color of the GtkDrawingArea i overlay the video output into).

Anybody got any hints/clues about what i'm doing wrongly?

Thanks in advance,
Flo

#include <iostream>
#include <sstream>

#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <X11/Xlib.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xvlib.h>

#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>

GstElement  *playbin;
GstXOverlay *x_overlay;

GtkWindow *window;
GtkWidget *videoarea;

Drawable xwindow_id;	

bool full_screen = false;

gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer data) 
{
	switch (GST_MESSAGE_TYPE (message)) {
		case GST_MESSAGE_ERROR:
			GError *err;
			gchar *debug;

			gst_message_parse_error (message, &err, &debug);

			std::cout << "Error: " << err->message << std::endl;
			g_error_free(err);
			g_free(debug);
			gtk_main_quit();

			break;

		case GST_MESSAGE_EOS:
			std::cout << "End of stream." << std::endl;

			// x_overlay = 0;

			// gst_element_set_state (playbin, GST_STATE_READY);
	
			// gtk_widget_queue_draw(videoarea);

			gtk_main_quit();
			break;

		default:
			break;
	}

	return true;
}

GstBusSyncReply sync_callback(GstBus *bus, GstMessage *message, gpointer data)
{
	const GstStructure *s;

	s = gst_message_get_structure (message);
	
	if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) 
	{ 
		return GST_BUS_PASS; 
	}

	if (gst_structure_has_name (s, "prepare-xwindow-id")) 
	{
		std::cout << "embed" << std::endl;

		x_overlay = GST_X_OVERLAY(GST_MESSAGE_SRC(message));

		gst_x_overlay_set_xwindow_id(x_overlay, xwindow_id);
 
		return GST_BUS_PASS;
	}

	return GST_BUS_DROP;
}

static void on_mainwindow_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
	if (event->keyval == GDK_q) {
		gtk_main_quit();
	}
	if (event->keyval == GDK_f) {
		// switch to full screen
		if (!full_screen) 
		{
			gtk_window_fullscreen(window);
			full_screen = true;
		} 
		else 
		{
			gtk_window_unfullscreen(window);
			full_screen = false;
		}
	}
}

static gboolean delete_event(GtkWidget *widget, GdkEvent  *event, gpointer data )
{
	g_print ("delete event occurred\n");
	return TRUE;
}

static void destroy(GtkWidget *widget, gpointer data)
{
	gtk_main_quit ();
}

int main(int argc, char *argv[])
{
	if (argc < 2) 
	{
		std::cout << "too few params. specify video file" << std::endl;
		exit (EXIT_FAILURE);
	}    

	gtk_init (&argc, &argv);
	g_thread_init(NULL);
	gdk_threads_init();
	gst_init (&argc, &argv);

	// create our one in all wonder gst package thingy!!!! tha playbin
	playbin = gst_element_factory_make ("playbin", "play");
	if (!playbin) {
		std::cout << "Couldn't create playbin element." << std::endl;
		exit (EXIT_FAILURE);
	}

	gst_bus_add_watch(gst_pipeline_get_bus (GST_PIPELINE (playbin)), bus_callback, 0);
	gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (playbin)), (GstBusSyncHandler)sync_callback, 0);
    
	window = (GtkWindow*)gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
	g_signal_connect (G_OBJECT (window), "delete_event",
	G_CALLBACK (delete_event), NULL);
    
	g_signal_connect (G_OBJECT (window), "key_press_event",
	G_CALLBACK (on_mainwindow_keypress_event), NULL);

	g_signal_connect (G_OBJECT (window), "destroy",
	G_CALLBACK (destroy), NULL);
    
	// gtk_container_set_border_width (GTK_CONTAINER (window), 2);
    
	videoarea = gtk_drawing_area_new ();

	gtk_widget_set_size_request(videoarea, 320, 200);

	GdkColor color;

	gdk_color_parse ("black", &color);
	gtk_widget_modify_bg (videoarea, GTK_STATE_NORMAL, &color);
    
	gtk_container_add (GTK_CONTAINER (window), videoarea);
	    
	gtk_widget_show (videoarea);
    
	gtk_widget_show ((GtkWidget*)window);

	Display *display;

	display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
	xwindow_id = GDK_DRAWABLE_XID((videoarea->window));

	std::stringstream sstream;

	sstream << "file:///" << argv[1];

	std::string uri = sstream.str();

	g_object_set(G_OBJECT(playbin), "uri", uri.c_str(), NULL);
	
	gst_element_set_state(playbin, GST_STATE_READY);
	// gst_element_set_state (_playbin, GST_STATE_PAUSED);
	gst_element_set_state(playbin, GST_STATE_PLAYING);

	gtk_main ();
    
	return 0;
}


-- 
Palimm Palimm!
http://tapas.affenbande.org




More information about the gstreamer-devel mailing list