stress-xoverlay.c 5.41 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
/* 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

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

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

#include <math.h>
#include <sys/time.h>

static GMainLoop *loop;

static Display *disp;
36
static Window root, win = 0;
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
static GC gc;
static gint width = 320, height = 240, x = 0, y = 0;
static gint disp_width, disp_height;

static inline long
myclock ()
{
  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;
}

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
static gboolean
toggle_events (GstXOverlay * ov)
{
  static gboolean events_toggled;

  gst_x_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;
}

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
static gboolean
cycle_window (GstXOverlay * 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_x_overlay_set_xwindow_id (ov, win);

  if (old_win) {
    XDestroyWindow (disp, old_win);
    XFreeGC (disp, old_gc);
    XSync (disp, FALSE);
  }

  return TRUE;
}

142 143 144 145
static GstBusSyncReply
create_window (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
{
  const GstStructure *s;
146
  GstXOverlay *ov = NULL;
147 148 149 150 151 152

  s = gst_message_get_structure (message);
  if (!gst_structure_has_name (s, "prepare-xwindow-id")) {
    return GST_BUS_PASS;
  }

153 154
  ov = GST_X_OVERLAY (GST_MESSAGE_SRC (message));

155 156
  g_print ("Creating our own window\n");

157
  cycle_window (ov);
158 159 160

  g_timeout_add (50, (GSourceFunc) resize_window, pipeline);
  g_timeout_add (50, (GSourceFunc) move_window, pipeline);
161
  g_timeout_add (100, (GSourceFunc) cycle_window, ov);
162
  g_timeout_add (2000, (GSourceFunc) toggle_events, ov);
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197

  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;
198 199

#ifndef GST_DISABLE_PARSE
200
  GError *error = NULL;
201
#endif
202 203 204 205 206 207 208 209 210 211

  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 XOverlay.\n");
    g_print ("Example: %s \"videotestsrc ! ximagesink\"\n", argv[0]);
    return -1;
  }
212 213 214 215 216 217
#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
218 219 220 221 222
  pipeline = gst_parse_launch (argv[1], &error);
  if (error) {
    g_print ("Error while parsing pipeline description: %s\n", error->message);
    return -1;
  }
223
#endif
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246

  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);

  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 (10000, (GSourceFunc) pause_playback, pipeline);
  g_timeout_add (20000, (GSourceFunc) start_playback, pipeline);

  g_main_loop_run (loop);

  close_display ();

  g_main_loop_unref (loop);

  return 0;
}