| /* GStreamer |
| * Copyright (C) <2005> Julien Moutte <julien@moutte.net> |
| * |
| * 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 <gst/gst.h> |
| #include <gst/video/videooverlay.h> |
| |
| #include <X11/Xlib.h> |
| #include <X11/Xutil.h> |
| |
| #include <math.h> |
| #include <sys/time.h> |
| |
| 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; |
| } |