/* GStreamer * Copyright (C) <2005> Julien Moutte * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * 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., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include static GMainLoop *loop; static Display *disp; static Window root, win = 0; static GC gc; static gint width = 320, height = 240, x = 0, y = 0; static gint disp_width, disp_height; static inline long myclock (void) { struct timeval tv; gettimeofday (&tv, NULL); return (tv.tv_sec * 1000 + tv.tv_usec / 1000); } static void open_display (void) { gint screen_num; disp = XOpenDisplay (NULL); root = DefaultRootWindow (disp); screen_num = DefaultScreen (disp); disp_width = DisplayWidth (disp, screen_num); disp_height = DisplayHeight (disp, screen_num); } static void close_display (void) { XCloseDisplay (disp); } static gboolean resize_window (GstPipeline * pipeline) { width = (sin (myclock () / 300.0) * 200) + 640; height = (sin (myclock () / 300.0) * 200) + 480; XResizeWindow (disp, win, width, height); XSync (disp, FALSE); return TRUE; } static gboolean move_window (GstPipeline * pipeline) { x += 5; y = disp_height - height + (sin (myclock () / 300.0) * height); if (x > disp_width) x = 0; XMoveWindow (disp, win, x, y); XSync (disp, FALSE); return TRUE; } static gboolean toggle_events (GstVideoOverlay * ov) { static gboolean events_toggled; gst_video_overlay_handle_events (ov, events_toggled); if (events_toggled) { g_print ("Events are handled\n"); events_toggled = FALSE; } else { g_print ("Events are NOT handled\n"); events_toggled = TRUE; } return TRUE; } static gboolean cycle_window (GstVideoOverlay * ov) { XGCValues values; Window old_win = win; GC old_gc = gc; win = XCreateSimpleWindow (disp, root, 0, 0, width, height, 0, 0, 0); XSetWindowBackgroundPixmap (disp, win, None); gc = XCreateGC (disp, win, 0, &values); XMapRaised (disp, win); XSync (disp, FALSE); gst_video_overlay_set_window_handle (ov, win); if (old_win) { XDestroyWindow (disp, old_win); XFreeGC (disp, old_gc); XSync (disp, FALSE); } return TRUE; } static GstBusSyncReply create_window (GstBus * bus, GstMessage * message, GstPipeline * pipeline) { GstVideoOverlay *ov = NULL; if (!gst_is_video_overlay_prepare_window_handle_message (message)) return GST_BUS_PASS; ov = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)); g_print ("Creating our own window\n"); cycle_window (ov); g_timeout_add (50, (GSourceFunc) resize_window, pipeline); g_timeout_add (50, (GSourceFunc) move_window, pipeline); g_timeout_add (100, (GSourceFunc) cycle_window, ov); g_timeout_add_seconds (2, (GSourceFunc) toggle_events, ov); gst_message_unref (message); return GST_BUS_DROP; } #if 0 static gboolean terminate_playback (GstElement * pipeline) { g_print ("Terminating playback\n"); g_main_loop_quit (loop); return FALSE; } #endif static gboolean pause_playback (GstElement * pipeline) { g_print ("Pausing playback\n"); gst_element_set_state (pipeline, GST_STATE_PAUSED); return FALSE; } static gboolean start_playback (GstElement * pipeline) { g_print ("Starting playback\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); return FALSE; } int main (int argc, char **argv) { GstElement *pipeline; GstBus *bus; #ifndef GST_DISABLE_PARSE GError *error = NULL; #endif gst_init (&argc, &argv); if (argc != 2) { g_print ("Usage: %s \"pipeline description with launch format\"\n", argv[0]); g_print ("The pipeline should contain an element implementing GstVideoOverlay.\n"); g_print ("Example: %s \"videotestsrc ! ximagesink\"\n", argv[0]); return -1; } #ifdef GST_DISABLE_PARSE g_print ("GStreamer was built without pipeline parsing capabilities.\n"); g_print ("Please rebuild GStreamer with pipeline parsing capabilities activated to use this example.\n"); return 1; #else pipeline = gst_parse_launch (argv[1], &error); if (error) { g_print ("Error while parsing pipeline description: %s\n", error->message); return -1; } #endif loop = g_main_loop_new (NULL, FALSE); open_display (); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, pipeline, NULL); gst_element_set_state (pipeline, GST_STATE_PLAYING); /* We want to get out after */ //g_timeout_add (500000, (GSourceFunc) terminate_playback, pipeline); g_timeout_add_seconds (10, (GSourceFunc) pause_playback, pipeline); g_timeout_add_seconds (20, (GSourceFunc) start_playback, pipeline); g_main_loop_run (loop); close_display (); g_main_loop_unref (loop); gst_object_unref (bus); return 0; }