Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 28 Feb 2011 10:58:05 +0000 (11:58 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 28 Feb 2011 10:58:05 +0000 (11:58 +0100)
Conflicts:
configure.ac

1  2 
configure.ac
gst/alpha/gstalpha.c
gst/rtsp/gstrtspsrc.c
sys/v4l2/gstv4l2object.c
sys/v4l2/gstv4l2xoverlay.c

diff --cc configure.ac
@@@ -1233,10 -1244,10 +1244,10 @@@ sed 
      -e "s/.* PACKAGE_STRING$/#define PACKAGE_STRING \"$PACKAGE_STRING\"/" \
      -e 's/.* PACKAGE_TARNAME$/#define PACKAGE_TARNAME "'$PACKAGE_TARNAME'"/' \
      -e 's/.* PACKAGE_VERSION$/#define PACKAGE_VERSION "'$PACKAGE_VERSION'"/' \
 -    -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n#  define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.10"\n#else\n#  define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.10"\n#endif/' \
 +    -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n#  define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.11"\n#else\n#  define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.11"\n#endif/' \
      -e 's/.* USE_BINARY_REGISTRY$/#define USE_BINARY_REGISTRY/' \
      -e 's/.* VERSION$/#define VERSION "'$VERSION'"/' \
-     -e "s/.* DEFAULT_AUDIOSINK$/#define DEFAULT_AUDIOSINK \"directaudiosink\"/" \
+     -e "s/.* DEFAULT_AUDIOSINK$/#define DEFAULT_AUDIOSINK \"directsoundsink\"/" \
      -e "s/.* DEFAULT_AUDIOSRC$/#define DEFAULT_AUDIOSRC \"audiotestsrc\"/" \
      -e "s/.* DEFAULT_VIDEOSRC$/#define DEFAULT_VIDEOSRC \"videotestsrc\"/" \
      -e "s/.* DEFAULT_VISUALIZER$/#define DEFAULT_VISUALIZER \"goom\"/" \
Simple merge
Simple merge
Simple merge
@@@ -40,8 -44,8 +44,8 @@@
  struct _GstV4l2Xv
  {
    Display *dpy;
-   gint port, idle_id;
-   GMutex *mutex;
+   gint port, idle_id, event_id;
 -  GMutex *mutex;                       /* to serialize calls to X11 */
++  GMutex *mutex;                /* to serialize calls to X11 */
  };
  
  GST_DEBUG_CATEGORY_STATIC (v4l2xv_debug);
@@@ -165,6 -177,55 +177,55 @@@ gst_v4l2_xoverlay_stop (GstV4l2Object 
    gst_v4l2_xoverlay_close (v4l2object);
  }
  
 -get_render_rect (GstV4l2Object * v4l2object, GstVideoRectangle *rect)
+ /* should be called with mutex held */
+ static gboolean
 -gst_v4l2_xoverlay_get_render_rect (GstV4l2Object *v4l2object,
 -    GstVideoRectangle *rect)
++get_render_rect (GstV4l2Object * v4l2object, GstVideoRectangle * rect)
+ {
+   GstV4l2Xv *v4l2xv = v4l2object->xv;
+   if (v4l2xv && v4l2xv->dpy && v4l2object->xwindow_id) {
+     XWindowAttributes attr;
+     XGetWindowAttributes (v4l2xv->dpy, v4l2object->xwindow_id, &attr);
+     /* this is where we'd add support to maintain aspect ratio */
+     rect->x = 0;
+     rect->y = 0;
+     rect->w = attr.width;
+     rect->h = attr.height;
+     return TRUE;
+   } else {
+     return FALSE;
+   }
+ }
+ gboolean
++gst_v4l2_xoverlay_get_render_rect (GstV4l2Object * v4l2object,
++    GstVideoRectangle * rect)
+ {
+   GstV4l2Xv *v4l2xv = v4l2object->xv;
+   gboolean ret = FALSE;
+   if (v4l2xv) {
+     g_mutex_lock (v4l2xv->mutex);
+     ret = get_render_rect (v4l2object, rect);
+     g_mutex_unlock (v4l2xv->mutex);
+   }
+   return ret;
+ }
+ static void
+ update_geometry (GstV4l2Object * v4l2object)
+ {
+   GstV4l2Xv *v4l2xv = v4l2object->xv;
+   GstVideoRectangle rect;
+   if (!get_render_rect (v4l2object, &rect))
+     return;
+   /* note: we don't pass in valid video x/y/w/h.. currently the xserver
+    * doesn't need to know these, as they come from v4l2 by setting the
+    * crop..
+    */
+   XvPutVideo (v4l2xv->dpy, v4l2xv->port, v4l2object->xwindow_id,
+       DefaultGC (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy)),
+       0, 0, rect.w, rect.h, rect.x, rect.y, rect.w, rect.h);
+ }
  static gboolean
  idle_refresh (gpointer data)
  {
    return FALSE;
  }
  
 -          PointerMotionMask, &e)) {
+ static gboolean
+ event_refresh (gpointer data)
+ {
+   GstV4l2Object *v4l2object = GST_V4L2_OBJECT (data);
+   GstV4l2Xv *v4l2xv = v4l2object->xv;
+   GST_LOG_OBJECT (v4l2object->element, "event refresh");
+   if (v4l2xv) {
+     XEvent e;
+     g_mutex_lock (v4l2xv->mutex);
+     /* If the element supports navigation, collect the relavent input
+      * events and push them upstream as navigation events
+      */
+     if (GST_IS_NAVIGATION (v4l2object->element)) {
+       guint pointer_x = 0, pointer_y = 0;
+       gboolean pointer_moved = FALSE;
+       /* We get all pointer motion events, only the last position is
+        * interesting.
+        */
+       while (XCheckWindowEvent (v4l2xv->dpy, v4l2object->xwindow_id,
 -            gst_navigation_send_mouse_event (
 -                GST_NAVIGATION (v4l2object->element),
 -                "mouse-button-press", e.xbutton.button,
++              PointerMotionMask, &e)) {
+         switch (e.type) {
+           case MotionNotify:
+             pointer_x = e.xmotion.x;
+             pointer_y = e.xmotion.y;
+             pointer_moved = TRUE;
+             break;
+           default:
+             break;
+         }
+       }
+       if (pointer_moved) {
+         GST_DEBUG_OBJECT (v4l2object->element,
+             "pointer moved over window at %d,%d", pointer_x, pointer_y);
+         g_mutex_unlock (v4l2xv->mutex);
+         gst_navigation_send_mouse_event (GST_NAVIGATION (v4l2object->element),
+             "mouse-move", 0, e.xbutton.x, e.xbutton.y);
+         g_mutex_lock (v4l2xv->mutex);
+       }
+       /* We get all events on our window to throw them upstream
+        */
+       while (XCheckWindowEvent (v4l2xv->dpy, v4l2object->xwindow_id,
+               KeyPressMask | KeyReleaseMask |
+               ButtonPressMask | ButtonReleaseMask, &e)) {
+         KeySym keysym;
+         const char *key_str = NULL;
+         g_mutex_unlock (v4l2xv->mutex);
+         switch (e.type) {
+           case ButtonPress:
+             GST_DEBUG_OBJECT (v4l2object->element,
+                 "button %d pressed over window at %d,%d",
+                 e.xbutton.button, e.xbutton.x, e.xbutton.y);
 -            gst_navigation_send_mouse_event (
 -                GST_NAVIGATION (v4l2object->element),
 -                "mouse-button-release", e.xbutton.button,
++            gst_navigation_send_mouse_event (GST_NAVIGATION
++                (v4l2object->element), "mouse-button-press", e.xbutton.button,
+                 e.xbutton.x, e.xbutton.y);
+             break;
+           case ButtonRelease:
+             GST_DEBUG_OBJECT (v4l2object->element,
+                 "button %d released over window at %d,%d",
+                 e.xbutton.button, e.xbutton.x, e.xbutton.y);
 -            gst_navigation_send_key_event (
 -                GST_NAVIGATION (v4l2object->element),
++            gst_navigation_send_mouse_event (GST_NAVIGATION
++                (v4l2object->element), "mouse-button-release", e.xbutton.button,
+                 e.xbutton.x, e.xbutton.y);
+             break;
+           case KeyPress:
+           case KeyRelease:
+             g_mutex_lock (v4l2xv->mutex);
+             keysym = XKeycodeToKeysym (v4l2xv->dpy, e.xkey.keycode, 0);
+             if (keysym != NoSymbol) {
+               key_str = XKeysymToString (keysym);
+             } else {
+               key_str = "unknown";
+             }
+             g_mutex_unlock (v4l2xv->mutex);
+             GST_DEBUG_OBJECT (v4l2object->element,
+                 "key %d pressed over window at %d,%d (%s)",
+                 e.xkey.keycode, e.xkey.x, e.xkey.y, key_str);
++            gst_navigation_send_key_event (GST_NAVIGATION (v4l2object->element),
+                 e.type == KeyPress ? "key-press" : "key-release", key_str);
+             break;
+           default:
+             GST_DEBUG_OBJECT (v4l2object->element,
+                 "unhandled X event (%d)", e.type);
+         }
+         g_mutex_lock (v4l2xv->mutex);
+       }
+     }
+     /* Handle ConfigureNotify */
+     while (XCheckWindowEvent (v4l2xv->dpy, v4l2object->xwindow_id,
+             StructureNotifyMask, &e)) {
+       switch (e.type) {
+         case ConfigureNotify:
+           update_geometry (v4l2object);
+           break;
+         default:
+           break;
+       }
+     }
+     g_mutex_unlock (v4l2xv->mutex);
+   }
+   /* repeat */
+   return TRUE;
+ }
  void
  gst_v4l2_xoverlay_set_window_handle (GstV4l2Object * v4l2object, guintptr id)
  {
    v4l2xv->idle_id = g_idle_add (idle_refresh, v4l2object);
    g_mutex_unlock (v4l2xv->mutex);
  }
 -          KeyPressMask | KeyReleaseMask |
 -          ButtonPressMask | ButtonReleaseMask;
+ /**
+  * gst_v4l2_xoverlay_prepare_xwindow_id:
+  * @param v4l2object
+  * @param required TRUE if display is required (ie. TRUE for v4l2sink, but
+  *   FALSE for any other element with optional overlay capabilities)
+  */
+ void
+ gst_v4l2_xoverlay_prepare_xwindow_id (GstV4l2Object * v4l2object,
+     gboolean required)
+ {
+   if (!GST_V4L2_IS_OVERLAY (v4l2object))
+     return;
+   gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (v4l2object->element));
+   if (required && !v4l2object->xwindow_id) {
+     GstV4l2Xv *v4l2xv;
+     Window win;
+     int width, height;
+     long event_mask;
+     if (!v4l2object->xv && GST_V4L2_IS_OPEN (v4l2object))
+       gst_v4l2_xoverlay_open (v4l2object);
+     v4l2xv = v4l2object->xv;
+     /* if xoverlay is not supported, just bail */
+     if (!v4l2xv)
+       return;
+     /* xoverlay is supported, but we don't have a window.. so create one */
+     GST_DEBUG_OBJECT (v4l2object->element, "creating window");
+     g_mutex_lock (v4l2xv->mutex);
+     width = XDisplayWidth (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy));
+     height = XDisplayHeight (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy));
+     GST_DEBUG_OBJECT (v4l2object->element, "dpy=%p", v4l2xv->dpy);
+     win = XCreateSimpleWindow (v4l2xv->dpy,
+         DefaultRootWindow (v4l2xv->dpy),
+         0, 0, width, height, 0, 0,
+         XBlackPixel (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy)));
+     GST_DEBUG_OBJECT (v4l2object->element, "win=%lu", win);
+     event_mask = ExposureMask | StructureNotifyMask;
+     if (GST_IS_NAVIGATION (v4l2object->element)) {
+       event_mask |= PointerMotionMask |
++          KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;
+     }
+     XSelectInput (v4l2xv->dpy, win, event_mask);
+     v4l2xv->event_id = g_timeout_add (45, event_refresh, v4l2object);
+     XMapRaised (v4l2xv->dpy, win);
+     XSync (v4l2xv->dpy, FALSE);
+     g_mutex_unlock (v4l2xv->mutex);
+     GST_DEBUG_OBJECT (v4l2object->element, "got window");
+     gst_v4l2_xoverlay_set_window_handle (v4l2object, win);
+   }
+ }