examples/gstplay/player.c: Adding some new lines in g_print calls.
authorJulien Moutte <julien@moutte.net>
Wed, 7 Jan 2004 15:33:42 +0000 (15:33 +0000)
committerJulien Moutte <julien@moutte.net>
Wed, 7 Jan 2004 15:33:42 +0000 (15:33 +0000)
Original commit message from CVS:
* examples/gstplay/player.c: (got_time_tick), (got_stream_length),
(got_video_size): Adding some new lines in g_print calls.
* sys/ximage/ximagesink.c: (gst_ximagesink_xwindow_new),
(gst_ximagesink_xwindow_destroy), (gst_ximagesink_xwindow_resize),
(gst_ximagesink_handle_xevents), (gst_ximagesink_fixate),
(gst_ximagesink_sinkconnect), (gst_ximagesink_change_state),
(gst_ximagesink_chain), (gst_ximagesink_buffer_new),
(gst_ximagesink_set_xwindow_id), (gst_ximagesink_get_desired_size):
Complete code review, reverting some stuff i disagree with, adding
some fixes : time synchronization on invalid timestamps, renegotiation
of private window.
* sys/ximage/ximagesink.h:
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_xwindow_destroy),
(gst_xvimagesink_xwindow_resize), (gst_xvimagesink_handle_xevents),
(gst_xvimagesink_get_xv_support), (gst_xvimagesink_xcontext_get),
(gst_xvimagesink_fixate), (gst_xvimagesink_sinkconnect),
(gst_xvimagesink_change_state), (gst_xvimagesink_chain),
(gst_xvimagesink_buffer_new),
(gst_xvimagesink_navigation_send_event),
(gst_xvimagesink_set_xwindow_id),
(gst_xvimagesink_get_desired_size),
(gst_xvimagesink_xoverlay_init): Complete code review, reverting some
stuff i disagree with, adding some fixes : Renegotiation of private
window, implementing get_desired_size.

ChangeLog
examples/gstplay/player.c
sys/ximage/ximagesink.c
sys/ximage/ximagesink.h
sys/xvimage/xvimagesink.c
tests/old/examples/gstplay/player.c

index 3cc5046..1d586cf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2004-01-07  Julien MOUTTE,,,  <julien@moutte.net>
+
+       * examples/gstplay/player.c: (got_time_tick), (got_stream_length),
+       (got_video_size): Adding some new lines in g_print calls.
+       * sys/ximage/ximagesink.c: (gst_ximagesink_xwindow_new),
+       (gst_ximagesink_xwindow_destroy), (gst_ximagesink_xwindow_resize),
+       (gst_ximagesink_handle_xevents), (gst_ximagesink_fixate),
+       (gst_ximagesink_sinkconnect), (gst_ximagesink_change_state),
+       (gst_ximagesink_chain), (gst_ximagesink_buffer_new),
+       (gst_ximagesink_set_xwindow_id), (gst_ximagesink_get_desired_size):
+       Complete code review, reverting some stuff i disagree with, adding
+       some fixes : time synchronization on invalid timestamps, renegotiation
+       of private window.
+       * sys/ximage/ximagesink.h:
+       * sys/xvimage/xvimagesink.c: (gst_xvimagesink_xwindow_destroy),
+       (gst_xvimagesink_xwindow_resize), (gst_xvimagesink_handle_xevents),
+       (gst_xvimagesink_get_xv_support), (gst_xvimagesink_xcontext_get),
+       (gst_xvimagesink_fixate), (gst_xvimagesink_sinkconnect),
+       (gst_xvimagesink_change_state), (gst_xvimagesink_chain),
+       (gst_xvimagesink_buffer_new),
+       (gst_xvimagesink_navigation_send_event),
+       (gst_xvimagesink_set_xwindow_id),
+       (gst_xvimagesink_get_desired_size),
+       (gst_xvimagesink_xoverlay_init): Complete code review, reverting some
+       stuff i disagree with, adding some fixes : Renegotiation of private
+       window, implementing get_desired_size.
+
 2004-01-07  Ronald Bultje  <rbultje@ronald.bitfreak.net>
 
        * ext/audiofile/gstafsink.c: (gst_afsink_init), (gst_afsink_chain),
index 76a735f..5d4f246 100644 (file)
@@ -58,20 +58,20 @@ got_found_tag (GstPlay *play,GstElement *source, GstTagList *tag_list)
 static void
 got_time_tick (GstPlay *play, gint64 time_nanos)
 {
-  g_print ("time tick %llu", time_nanos);
+  g_print ("time tick %llu\n", time_nanos);
 }
 
 static void
 got_stream_length (GstPlay *play, gint64 length_nanos)
 {
-  g_print ("got length %llu", length_nanos);
+  g_print ("got length %llu\n", length_nanos);
   length = length_nanos;
 }
 
 static void
 got_video_size (GstPlay *play, gint width, gint height)
 {
-  g_print ("got video size %d, %d", width, height);
+  g_print ("got video size %d, %d\n", width, height);
 }
 
 static void
index e0dc80c..25a7b96 100644 (file)
@@ -216,27 +216,24 @@ gst_ximagesink_xwindow_new (GstXImageSink *ximagesink, gint width, gint height)
   
   xwindow->width = width;
   xwindow->height = height;
+  xwindow->internal = TRUE;
   
   g_mutex_lock (ximagesink->x_lock);
   
-  if (ximagesink->embed_into == 0) {
-    xwindow->win = XCreateSimpleWindow (ximagesink->xcontext->disp,
-                                        ximagesink->xcontext->root, 
-                                       0, 0, xwindow->width, xwindow->height, 
-                                       0, 0, ximagesink->xcontext->black);
+  xwindow->win = XCreateSimpleWindow (ximagesink->xcontext->disp,
+                                      ximagesink->xcontext->root, 
+                                      0, 0, xwindow->width, xwindow->height, 
+                                      0, 0, ximagesink->xcontext->black);
     
-    XMapRaised (ximagesink->xcontext->disp, xwindow->win);
-  } else {
-    xwindow->win = ximagesink->embed_into;
-  }
+  XMapRaised (ximagesink->xcontext->disp, xwindow->win);
+  
   XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
                 StructureNotifyMask | PointerMotionMask | KeyPressMask |
                 KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
   
   xwindow->gc = XCreateGC (ximagesink->xcontext->disp,
                            xwindow->win, 0, NULL);
-  
-  
+
   g_mutex_unlock (ximagesink->x_lock);
   
   return xwindow;
@@ -253,11 +250,10 @@ gst_ximagesink_xwindow_destroy (GstXImageSink *ximagesink, GstXWindow *xwindow)
   g_mutex_lock (ximagesink->x_lock);
   
   /* If we did not create that window we just free the GC and let it live */
-  if (ximagesink->embed_into == 0) {
+  if (xwindow->internal)
     XDestroyWindow (ximagesink->xcontext->disp, xwindow->win);
-  } else {
+  else
     XSelectInput (ximagesink->xcontext->disp, xwindow->win, 0);
-  }
     
   XFreeGC (ximagesink->xcontext->disp, xwindow->gc);
   
@@ -266,6 +262,26 @@ gst_ximagesink_xwindow_destroy (GstXImageSink *ximagesink, GstXWindow *xwindow)
   g_free (xwindow);
 }
 
+/* This function resizes a GstXWindow */
+static void
+gst_ximagesink_xwindow_resize (GstXImageSink *ximagesink, GstXWindow *xwindow,
+                               guint width, guint height)
+{
+  g_return_if_fail (xwindow != NULL);
+  g_return_if_fail (ximagesink != NULL);
+  g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
+  
+  g_mutex_lock (ximagesink->x_lock);
+  
+  xwindow->width = width;
+  xwindow->height = height;
+  
+  XResizeWindow (ximagesink->xcontext->disp, xwindow->win,
+                 xwindow->width, xwindow->height);
+
+  g_mutex_unlock (ximagesink->x_lock);
+}
+
 /* This function handles XEvents that might be in the queue. It generates
    GstEvent that will be sent upstream in the pipeline to handle interactivity
    and navigation. It will also listen for configure events on the window to
@@ -309,17 +325,17 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
                 ximagesink->xwindow->height = e.xconfigure.height;
                 
                 r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink),
-                   gst_caps_new_simple ("video/x-raw-rgb",
-                     "bpp",        G_TYPE_INT, ximagesink->xcontext->bpp,
-                     "depth",      G_TYPE_INT, ximagesink->xcontext->depth,
-                     "endianness", G_TYPE_INT, ximagesink->xcontext->endianness,
-                     "red_mask",   G_TYPE_INT, ximagesink->xcontext->visual->red_mask,
-                     "green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask,
-                     "blue_mask",  G_TYPE_INT, ximagesink->xcontext->visual->blue_mask,
-                     "width",      G_TYPE_INT, e.xconfigure.width & ~3,
-                     "height",     G_TYPE_INT, e.xconfigure.height & ~3,
-                     "framerate",  G_TYPE_DOUBLE, ximagesink->framerate,
-                     NULL));
+                    gst_caps_new_simple ("video/x-raw-rgb",
+                      "bpp",        G_TYPE_INT, ximagesink->xcontext->bpp,
+                      "depth",      G_TYPE_INT, ximagesink->xcontext->depth,
+                      "endianness", G_TYPE_INT, ximagesink->xcontext->endianness,
+                      "red_mask",   G_TYPE_INT, ximagesink->xcontext->visual->red_mask,
+                      "green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask,
+                      "blue_mask",  G_TYPE_INT, ximagesink->xcontext->visual->blue_mask,
+                      "width",      G_TYPE_INT, e.xconfigure.width & ~3,
+                      "height",     G_TYPE_INT, e.xconfigure.height & ~3,
+                      "framerate",  G_TYPE_DOUBLE, ximagesink->framerate,
+                      NULL));
                 
                 if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) )
                   {
@@ -352,26 +368,25 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
             GST_DEBUG ("ximagesink pointer moved over window at %d,%d",
                        e.xmotion.x, e.xmotion.y);
             gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink),
-                                             "mouse-move",
-                                            0,
+                                             "mouse-move", 0,
                                              e.xmotion.x, e.xmotion.y);
             break;
           case ButtonPress:
+            /* Mouse button pressed/released over our window. We send upstream
+               events for interactivity/navigation */
             GST_DEBUG ("ximagesink button %d pressed over window at %d,%d",
                        e.xbutton.button, e.xbutton.x, e.xbutton.x);
             gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink),
                                              "mouse-button-press",
-                                            e.xbutton.button,
+                                             e.xbutton.button,
                                              e.xbutton.x, e.xbutton.y);
-           break;
+            break;
           case ButtonRelease:
-            /* Mouse button pressed/released over our window. We send upstream
-               events for interactivity/navigation */
             GST_DEBUG ("ximagesink button %d release over window at %d,%d",
                        e.xbutton.button, e.xbutton.x, e.xbutton.x);
             gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink),
-                                            "mouse-button-release",
-                                            e.xbutton.button,
+                                             "mouse-button-release",
+                                             e.xbutton.button,
                                              e.xbutton.x, e.xbutton.y);
             break;
           case KeyPress:
@@ -382,19 +397,18 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
                        e.xkey.keycode, e.xkey.x, e.xkey.x);
             keysym = XKeycodeToKeysym (ximagesink->xcontext->disp,
                                        e.xkey.keycode, 0);
-           if (keysym != NoSymbol) {
-               gst_navigation_send_key_event (GST_NAVIGATION (ximagesink),
-                                              e.type == KeyPress ? 
-                                                 "key-press" : "key-release",
-                                               XKeysymToString (keysym));
-           }
-           else {
-               /* FIXME : What's that ? */
-               gst_navigation_send_key_event (GST_NAVIGATION (ximagesink),
-                                              e.type == KeyPress ? 
-                                                 "key-press" : "key-release",
-                                               "unknown");
-           }
+            if (keysym != NoSymbol) {
+              gst_navigation_send_key_event (GST_NAVIGATION (ximagesink),
+                                             e.type == KeyPress ? 
+                                               "key-press" : "key-release",
+                                             XKeysymToString (keysym));
+            }
+            else {
+              gst_navigation_send_key_event (GST_NAVIGATION (ximagesink),
+                                             e.type == KeyPress ? 
+                                               "key-press" : "key-release",
+                                             "unknown");
+            }
             break;
           default:
             GST_DEBUG ("ximagesink unhandled X event (%d)", e.type);
@@ -546,7 +560,7 @@ gst_ximagesink_fixate (GstPad *pad, const GstCaps *caps)
     return newcaps;
   }
   if (gst_caps_structure_fixate_field_nearest_double (structure, "framerate",
-        30.0)) {
+                                                      30.0)) {
     return newcaps;
   }
 
@@ -593,20 +607,20 @@ gst_ximagesink_sinkconnect (GstPad *pad, const GstCaps *caps)
 
   structure = gst_caps_get_structure (caps, 0);
   ret = gst_structure_get_int (structure, "width",
-      &(GST_VIDEOSINK_WIDTH (ximagesink)));
+                               &(GST_VIDEOSINK_WIDTH (ximagesink)));
   ret &= gst_structure_get_int (structure, "height",
-      &(GST_VIDEOSINK_HEIGHT (ximagesink)));
+                                &(GST_VIDEOSINK_HEIGHT (ximagesink)));
   ret &= gst_structure_get_double (structure,
-      "framerate", &ximagesink->framerate);
+                                   "framerate", &ximagesink->framerate);
   if (!ret) return GST_PAD_LINK_REFUSED;
   
   ximagesink->pixel_width = 1;
   gst_structure_get_int  (structure, "pixel_width",
-      &ximagesink->pixel_width);
+                          &ximagesink->pixel_width);
 
   ximagesink->pixel_height = 1;
   gst_structure_get_int  (structure, "pixel_height",
-      &ximagesink->pixel_height);
+                          &ximagesink->pixel_height);
   
   /* Creating our window and our image */
   if (!ximagesink->xwindow)
@@ -614,10 +628,12 @@ gst_ximagesink_sinkconnect (GstPad *pad, const GstCaps *caps)
                                              GST_VIDEOSINK_WIDTH (ximagesink),
                                              GST_VIDEOSINK_HEIGHT (ximagesink));
   else
-    XResizeWindow (ximagesink->xcontext->disp,
-                  ximagesink->xwindow->win,
-                  GST_VIDEOSINK_WIDTH (ximagesink),
-                  GST_VIDEOSINK_HEIGHT (ximagesink));
+    {
+      if (ximagesink->xwindow->internal)
+        gst_ximagesink_xwindow_resize (ximagesink, ximagesink->xwindow,
+                                       GST_VIDEOSINK_WIDTH (ximagesink),
+                                       GST_VIDEOSINK_HEIGHT (ximagesink));
+    }
   
   if ( (ximagesink->ximage) &&
        ( (GST_VIDEOSINK_WIDTH (ximagesink) != ximagesink->ximage->width) ||
@@ -635,8 +651,8 @@ gst_ximagesink_sinkconnect (GstPad *pad, const GstCaps *caps)
                                              GST_VIDEOSINK_HEIGHT (ximagesink));
   
   gst_x_overlay_got_desired_size (GST_X_OVERLAY (ximagesink),
-                                 GST_VIDEOSINK_WIDTH (ximagesink),
-                                 GST_VIDEOSINK_HEIGHT (ximagesink));
+                                  GST_VIDEOSINK_WIDTH (ximagesink),
+                                  GST_VIDEOSINK_HEIGHT (ximagesink));
   gst_video_sink_got_video_size (GST_VIDEOSINK (ximagesink),
                                  GST_VIDEOSINK_WIDTH (ximagesink),
                                  GST_VIDEOSINK_HEIGHT (ximagesink));
@@ -660,12 +676,14 @@ gst_ximagesink_change_state (GstElement *element)
         return GST_STATE_FAILURE;
       break;
     case GST_STATE_READY_TO_PAUSED:
+      ximagesink->time = 0;
       break;
     case GST_STATE_PAUSED_TO_PLAYING:
       break;
     case GST_STATE_PLAYING_TO_PAUSED:
       break;
     case GST_STATE_PAUSED_TO_READY:
+      ximagesink->framerate = 0;
       GST_VIDEOSINK_WIDTH (ximagesink) = 0;
       GST_VIDEOSINK_HEIGHT (ximagesink) = 0;
       break;
@@ -680,10 +698,9 @@ gst_ximagesink_change_state (GstElement *element)
 }
 
 static void
-gst_ximagesink_chain (GstPad *pad, GstData *_data)
+gst_ximagesink_chain (GstPad *pad, GstData *data)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
-  GstClockTime time = GST_BUFFER_TIMESTAMP (buf);
+  GstBuffer *buf = GST_BUFFER (data);
   GstXImageSink *ximagesink;
   
   g_return_if_fail (pad != NULL);
@@ -692,30 +709,36 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data)
 
   ximagesink = GST_XIMAGESINK (gst_pad_get_parent (pad));
     
-  if (GST_IS_EVENT (buf))
+  if (GST_IS_EVENT (data))
     {
-      GstEvent *event = GST_EVENT (buf);
+      GstEvent *event = GST_EVENT (data);
       gint64 offset;
 
       switch (GST_EVENT_TYPE (event))
         {
           case GST_EVENT_DISCONTINUOUS:
-           offset = GST_EVENT_DISCONT_OFFSET (event, 0).value;
-           GST_DEBUG ("ximage discont %" G_GINT64_FORMAT "\n", offset);
-           break;
+            offset = GST_EVENT_DISCONT_OFFSET (event, 0).value;
+            GST_DEBUG ("ximage discont %" G_GINT64_FORMAT "\n", offset);
+            break;
           default:
-           gst_pad_event_default (pad, event);
-           return;
+            gst_pad_event_default (pad, event);
+            return;
         }
       gst_event_unref (event);
       return;
     }
   
-  GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT, time);
+  buf = GST_BUFFER (data);
+  /* update time */
+  if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
+    ximagesink->time = GST_BUFFER_TIMESTAMP (buf);
+  }
+  GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT, ximagesink->time);
   
   if (GST_VIDEOSINK_CLOCK (ximagesink)) {
     GstClockID id;
-    id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (ximagesink), time);
+    id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (ximagesink),
+                                       ximagesink->time);
     gst_element_clock_wait (GST_ELEMENT (ximagesink), id, NULL);
     gst_clock_id_free (id);
   }
@@ -744,6 +767,10 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data)
 #if 0
     }
 #endif
+  /* set correct time for next buffer */
+  if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && ximagesink->framerate > 0) {
+    ximagesink->time += GST_SECOND / ximagesink->framerate;
+  }
   
   gst_buffer_unref (buf);
     
@@ -753,7 +780,7 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data)
 #if 0
 static GstBuffer*
 gst_ximagesink_buffer_new (GstBufferPool *pool,  
-                          gint64 location, guint size, gpointer user_data)
+                           gint64 location, guint size, gpointer user_data)
 {
   GstXImageSink *ximagesink;
   GstBuffer *buffer;
@@ -910,17 +937,14 @@ static void
 gst_ximagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
 {
   GstXImageSink *ximagesink = GST_XIMAGESINK (overlay);
+  GstXWindow *xwindow = NULL;
+  XWindowAttributes attr;
   
   g_return_if_fail (ximagesink != NULL);
   g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
   
-  if (ximagesink->embed_into == xwindow_id)
-    return;
-  
   if (!ximagesink->xcontext)
-    {
-      ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink);
-    }
+    ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink);
   
   if ( (ximagesink->xwindow) && (ximagesink->ximage) )
     { /* If we are replacing a window we destroy pictures and window as they
@@ -930,16 +954,30 @@ gst_ximagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
       gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
     }
     
-  ximagesink->embed_into = xwindow_id;
+  xwindow = g_new0 (GstXWindow, 1);
+  
+  xwindow->win = xwindow_id;
+  
+  /* We get window geometry, set the event we want to receive, and create a GC */
+  g_mutex_lock (ximagesink->x_lock);
+  XGetWindowAttributes (ximagesink->xcontext->disp, xwindow->win, &attr);
+  xwindow->width = attr.width;
+  xwindow->height = attr.height;
+  xwindow->internal = FALSE;
+  XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
+                StructureNotifyMask | PointerMotionMask | KeyPressMask |
+                KeyReleaseMask);
   
-  ximagesink->xwindow = gst_ximagesink_xwindow_new (ximagesink, GST_VIDEOSINK_WIDTH (ximagesink), GST_VIDEOSINK_HEIGHT (ximagesink));
-  ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink, 
-      GST_VIDEOSINK_WIDTH (ximagesink), GST_VIDEOSINK_HEIGHT (ximagesink));
-  gst_x_overlay_got_xwindow_id (overlay, xwindow_id);
+  xwindow->gc = XCreateGC (ximagesink->xcontext->disp,
+                           xwindow->win, 0, NULL);
+  g_mutex_unlock (ximagesink->x_lock);
+    
+  ximagesink->xwindow = xwindow;
 }
 
 static void
-gst_ximagesink_get_desired_size (GstXOverlay *overlay, guint *width, guint *height)
+gst_ximagesink_get_desired_size (GstXOverlay *overlay,
+                                 guint *width, guint *height)
 {
   GstXImageSink *ximagesink = GST_XIMAGESINK (overlay);
 
index ad292a9..74fe93e 100644 (file)
@@ -83,6 +83,7 @@ struct _GstXContext {
 struct _GstXWindow {
   Window win;
   gint width, height;
+  gboolean internal;
   GC gc;
 };
 
@@ -102,8 +103,6 @@ struct _GstXImageSink {
   /* Our element stuff */
   GstVideoSink videosink;
 
-  XID embed_into;
-  
   GstXContext *xcontext;
   GstXWindow *xwindow;
   GstXImage *ximage;
@@ -114,6 +113,8 @@ struct _GstXImageSink {
   /* Unused */
   gint pixel_width, pixel_height;
  
+  GstClockTime time;
+  
   GMutex *pool_lock;
   GSList *image_pool;
 };
index 7c3da91..6f1ab4b 100644 (file)
@@ -263,6 +263,8 @@ gst_xvimagesink_xwindow_destroy (GstXvImageSink *xvimagesink, GstXWindow *xwindo
   /* If we did not create that window we just free the GC and let it live */
   if (xwindow->internal)
     XDestroyWindow (xvimagesink->xcontext->disp, xwindow->win);
+  else
+    XSelectInput (xvimagesink->xcontext->disp, xwindow->win, 0);
   
   XFreeGC (xvimagesink->xcontext->disp, xwindow->gc);
   
@@ -271,6 +273,26 @@ gst_xvimagesink_xwindow_destroy (GstXvImageSink *xvimagesink, GstXWindow *xwindo
   g_free (xwindow);
 }
 
+/* This function resizes a GstXWindow */
+static void
+gst_xvimagesink_xwindow_resize (GstXvImageSink *xvimagesink,
+                                GstXWindow *xwindow, guint width, guint height)
+{
+  g_return_if_fail (xwindow != NULL);
+  g_return_if_fail (xvimagesink != NULL);
+  g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
+  
+  g_mutex_lock (xvimagesink->x_lock);
+  
+  xwindow->width = width;
+  xwindow->height = height;
+  
+  XResizeWindow (xvimagesink->xcontext->disp, xwindow->win,
+                 xwindow->width, xwindow->height);
+
+  g_mutex_unlock (xvimagesink->x_lock);
+}
+
 /* This function handles XEvents that might be in the queue. It generates
    GstEvent that will be sent upstream in the pipeline to handle interactivity
    and navigation. It will also listen for configure events on the window to
@@ -301,7 +323,7 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
         {
           case ConfigureNotify:
             /* Window got resized or moved. We update our data. */
-            GST_DEBUG ("ximagesink window is at %d, %d with geometry : %d,%d",
+            GST_DEBUG ("xvimagesink window is at %d, %d with geometry : %d,%d",
                        e.xconfigure.x, e.xconfigure.y,
                        e.xconfigure.width, e.xconfigure.height);
             xvimagesink->xwindow->width = e.xconfigure.width;
@@ -313,7 +335,7 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
             GST_DEBUG ("xvimagesink pointer moved over window at %d,%d",
                        e.xmotion.x, e.xmotion.y);
             gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink),
-                                            "mouse-move", 0, 
+                                             "mouse-move", 0, 
                                              e.xmotion.x, e.xmotion.y);
             break;
           case ButtonPress:
@@ -322,8 +344,8 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
             GST_DEBUG ("xvimagesink button %d pressed over window at %d,%d",
                        e.xbutton.button, e.xbutton.x, e.xbutton.y);
             gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink),
-                                            "mouse-button-press",
-                                            e.xbutton.button,
+                                             "mouse-button-press",
+                                             e.xbutton.button,
                                              e.xbutton.x, e.xbutton.y);
             break;
           case ButtonRelease:
@@ -332,8 +354,8 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
             GST_DEBUG ("xvimagesink button %d released over window at %d,%d",
                        e.xbutton.button, e.xbutton.x, e.xbutton.y);
             gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink),
-                                            "mouse-button-release",    
-                                            e.xbutton.button,
+                                             "mouse-button-release",
+                                             e.xbutton.button,
                                              e.xbutton.x, e.xbutton.y);
             break;
           case KeyPress:
@@ -344,18 +366,18 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
                        e.xkey.keycode, e.xkey.x, e.xkey.y);
             keysym = XKeycodeToKeysym (xvimagesink->xcontext->disp,
                                        e.xkey.keycode, 0);
-           if (keysym != NoSymbol) {
-               gst_navigation_send_key_event (GST_NAVIGATION (xvimagesink),
-                                               e.type == KeyPress ?
-                                               "key-press" : "key-release",
-                                               XKeysymToString (keysym));
-           }
-           else {
-               gst_navigation_send_key_event (GST_NAVIGATION (xvimagesink),
-                                               e.type == KeyPress ?
-                                               "key-press" : "key-release",
-                                               "unknown");
-           }
+            if (keysym != NoSymbol) {
+              gst_navigation_send_key_event (GST_NAVIGATION (xvimagesink),
+                                             e.type == KeyPress ?
+                                               "key-press" : "key-release",
+                                             XKeysymToString (keysym));
+            }
+            else {
+              gst_navigation_send_key_event (GST_NAVIGATION (xvimagesink),
+                                             e.type == KeyPress ?
+                                               "key-press" : "key-release",
+                                             "unknown");
+            }
             break;
           default:
             GST_DEBUG ("xvimagesink unhandled X event (%d)", e.type);
@@ -366,6 +388,9 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad)
   g_mutex_unlock (xvimagesink->x_lock);
 }
 
+/* This function generates a caps with all supported format by the first
+   Xv grabable port we find. We store each one of the supported formats in a
+   format list and append the format to a newly created caps that we return */
 static GstCaps *
 gst_xvimagesink_get_xv_support (GstXContext *xcontext)
 {
@@ -437,21 +462,21 @@ gst_xvimagesink_get_xv_support (GstXContext *xcontext)
               case XvRGB:
                 {
                   format_caps = gst_caps_new_simple ("video/x-raw-rgb",
-                     "endianness", G_TYPE_INT, xcontext->endianness,
-                     "depth", G_TYPE_INT, xcontext->depth,
-                     "bpp", G_TYPE_INT, xcontext->bpp,
-                     "blue_mask", G_TYPE_INT, formats[i].red_mask,
-                     "green_mask", G_TYPE_INT, formats[i].green_mask,
-                     "red_mask", G_TYPE_INT, formats[i].blue_mask,
-                     "width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
-                     "height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
-                     "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
-                     NULL);
+                      "endianness", G_TYPE_INT, xcontext->endianness,
+                      "depth", G_TYPE_INT, xcontext->depth,
+                      "bpp", G_TYPE_INT, xcontext->bpp,
+                      "blue_mask", G_TYPE_INT, formats[i].red_mask,
+                      "green_mask", G_TYPE_INT, formats[i].green_mask,
+                      "red_mask", G_TYPE_INT, formats[i].blue_mask,
+                      "width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
+                      "height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
+                      "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
+                      NULL);
                   
                   /* For RGB caps we store them and the image 
-                 format so that we can get back the format
-                 when sinkconnect will give us a caps without
-                 format property */
+                     format so that we can get back the format
+                     when sinkconnect will give us a caps without
+                     format property */
                   if (format_caps)
                     {
                       GstXvImageFormat *format = NULL;
@@ -467,16 +492,16 @@ gst_xvimagesink_get_xv_support (GstXContext *xcontext)
                   break;
                 }
               case XvYUV:
-               format_caps = gst_caps_new_simple ("video/x-raw-yuv",
-                   "format", GST_TYPE_FOURCC,formats[i].id,
-                   "width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
-                   "height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
-                   "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
-                   NULL);
+                format_caps = gst_caps_new_simple ("video/x-raw-yuv",
+                    "format", GST_TYPE_FOURCC,formats[i].id,
+                    "width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
+                    "height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
+                    "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
+                    NULL);
+                break;
+              default:
+                g_assert_not_reached();
                 break;
-             default:
-               g_assert_not_reached();
-               break;
             }
           
           gst_caps_append (caps, format_caps);
@@ -564,13 +589,19 @@ gst_xvimagesink_xcontext_get (GstXvImageSink *xvimagesink)
     }
 #endif /* HAVE_XSHM */
   
-  if (xcontext->endianness == G_LITTLE_ENDIAN && xcontext->depth == 24)
-    {
-      xcontext->endianness = G_BIG_ENDIAN;
-      xcontext->visual->red_mask = GUINT32_SWAP_LE_BE (xcontext->visual->red_mask);
-      xcontext->visual->green_mask = GUINT32_SWAP_LE_BE (xcontext->visual->green_mask);
-      xcontext->visual->blue_mask = GUINT32_SWAP_LE_BE (xcontext->visual->blue_mask);
+  /* our caps system handles 24/32bpp RGB as big-endian. */
+  if ((xcontext->bpp == 24 || xcontext->bpp == 32) &&
+      xcontext->endianness == G_LITTLE_ENDIAN) {
+    xcontext->endianness = G_BIG_ENDIAN;
+    xcontext->visual->red_mask = GUINT32_TO_BE (xcontext->visual->red_mask);
+    xcontext->visual->green_mask = GUINT32_TO_BE (xcontext->visual->green_mask);
+    xcontext->visual->blue_mask = GUINT32_TO_BE (xcontext->visual->blue_mask);
+    if (xcontext->bpp == 24) {
+      xcontext->visual->red_mask >>= 8;
+      xcontext->visual->green_mask >>= 8;
+      xcontext->visual->blue_mask >>= 8;
     }
+  }
   
   xcontext->caps = gst_xvimagesink_get_xv_support (xcontext);
   
@@ -644,7 +675,7 @@ gst_xvimagesink_fixate (GstPad *pad, const GstCaps *caps)
     return newcaps;
   }
   if (gst_caps_structure_fixate_field_nearest_double (structure, "framerate",
-        30.0)) {
+                                                      30.0)) {
     return newcaps;
   }
 
@@ -652,6 +683,8 @@ gst_xvimagesink_fixate (GstPad *pad, const GstCaps *caps)
   return NULL;
 }
 
+/* This function tries to get a format matching with a given caps in the
+   supported list of formats we generated in gst_xvimagesink_get_xv_support */
 static gint
 gst_xvimagesink_get_fourcc_from_caps (GstXvImageSink *xvimagesink,
                                       GstCaps *caps)
@@ -713,23 +746,26 @@ gst_xvimagesink_sinkconnect (GstPad *pad, const GstCaps *caps)
 
   caps_str1 = gst_caps_to_string (xvimagesink->xcontext->caps);
   caps_str2 = gst_caps_to_string (caps);
-                                                                                
+
   GST_DEBUG ("sinkconnect %s with %s", caps_str1, caps_str2);
-                                                                                
+
   g_free (caps_str1);
   g_free (caps_str2);
   
   structure = gst_caps_get_structure (caps, 0);
-  ret = gst_structure_get_int (structure, "width", &(GST_VIDEOSINK_WIDTH (xvimagesink)));
-  ret &= gst_structure_get_int (structure, "height", &(GST_VIDEOSINK_HEIGHT (xvimagesink)));
-  ret &= gst_structure_get_double (structure, "framerate", &xvimagesink->framerate);
+  ret = gst_structure_get_int (structure, "width",
+                               &(GST_VIDEOSINK_WIDTH (xvimagesink)));
+  ret &= gst_structure_get_int (structure, "height",
+                                &(GST_VIDEOSINK_HEIGHT (xvimagesink)));
+  ret &= gst_structure_get_double (structure, "framerate",
+                                   &xvimagesink->framerate);
   if (!ret) return GST_PAD_LINK_REFUSED;
   
   xvimagesink->xcontext->im_format = 0;
   if (!gst_structure_get_fourcc (structure, "format",
-       &xvimagesink->xcontext->im_format)) {
+                                 &xvimagesink->xcontext->im_format)) {
     xvimagesink->xcontext->im_format = gst_xvimagesink_get_fourcc_from_caps (
-       xvimagesink, gst_caps_copy(caps));
+                                         xvimagesink, gst_caps_copy(caps));
   }
   if (xvimagesink->xcontext->im_format == 0) {
     return GST_PAD_LINK_REFUSED;
@@ -739,13 +775,21 @@ gst_xvimagesink_sinkconnect (GstPad *pad, const GstCaps *caps)
   gst_structure_get_int (structure, "pixel_width", &xvimagesink->pixel_width);
 
   xvimagesink->pixel_height = 1;
-  gst_structure_get_int  (structure, "pixel_height", &xvimagesink->pixel_height);
+  gst_structure_get_int  (structure, "pixel_height",
+                          &xvimagesink->pixel_height);
   
   /* Creating our window and our image */
   if (!xvimagesink->xwindow)
     xvimagesink->xwindow = gst_xvimagesink_xwindow_new (xvimagesink,
                                             GST_VIDEOSINK_WIDTH (xvimagesink),
                                             GST_VIDEOSINK_HEIGHT (xvimagesink));
+  else
+    {
+      if (xvimagesink->xwindow->internal)
+        gst_xvimagesink_xwindow_resize (xvimagesink, xvimagesink->xwindow,
+                                        GST_VIDEOSINK_WIDTH (xvimagesink),
+                                        GST_VIDEOSINK_HEIGHT (xvimagesink));
+    }
   
   if ( (xvimagesink->xvimage) &&
        ( (GST_VIDEOSINK_WIDTH (xvimagesink) != xvimagesink->xvimage->width) ||
@@ -762,6 +806,9 @@ gst_xvimagesink_sinkconnect (GstPad *pad, const GstCaps *caps)
                                             GST_VIDEOSINK_WIDTH (xvimagesink),
                                             GST_VIDEOSINK_HEIGHT (xvimagesink));
   
+  gst_x_overlay_got_desired_size (GST_X_OVERLAY (xvimagesink),
+                                  GST_VIDEOSINK_WIDTH (xvimagesink),
+                                  GST_VIDEOSINK_HEIGHT (xvimagesink));
   gst_video_sink_got_video_size (GST_VIDEOSINK (xvimagesink),
                                  GST_VIDEOSINK_WIDTH (xvimagesink),
                                  GST_VIDEOSINK_HEIGHT (xvimagesink));
@@ -793,6 +840,8 @@ gst_xvimagesink_change_state (GstElement *element)
       break;
     case GST_STATE_PAUSED_TO_READY:
       xvimagesink->framerate = 0;
+      GST_VIDEOSINK_WIDTH (xvimagesink) = 0;
+      GST_VIDEOSINK_HEIGHT (xvimagesink) = 0;
       break;
     case GST_STATE_READY_TO_NULL:
       break;
@@ -824,12 +873,12 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
       switch (GST_EVENT_TYPE (event))
         {
           case GST_EVENT_DISCONTINUOUS:
-           offset = GST_EVENT_DISCONT_OFFSET (event, 0).value;
-           GST_DEBUG ("xvimage discont %" G_GINT64_FORMAT "\n", offset);
-           break;
+            offset = GST_EVENT_DISCONT_OFFSET (event, 0).value;
+            GST_DEBUG ("xvimage discont %" G_GINT64_FORMAT "\n", offset);
+            break;
           default:
-           gst_pad_event_default (pad, event);
-           return;
+            gst_pad_event_default (pad, event);
+            return;
         }
       gst_event_unref (event);
       return;
@@ -844,7 +893,8 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
   
   if (GST_VIDEOSINK_CLOCK (xvimagesink)) {
     GstClockID id;
-    id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (xvimagesink), xvimagesink->time);
+    id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (xvimagesink),
+                                       xvimagesink->time);
     gst_element_clock_wait (GST_ELEMENT (xvimagesink), id, NULL);
     gst_clock_id_free (id);
   }
@@ -886,7 +936,7 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
 #if 0
 static GstBuffer*
 gst_xvimagesink_buffer_new (GstBufferPool *pool,  
-                          gint64 location, guint size, gpointer user_data)
+                            gint64 location, guint size, gpointer user_data)
 {
   GstXvImageSink *xvimagesink;
   GstBuffer *buffer;
@@ -1024,7 +1074,8 @@ gst_xvimagesink_navigation_send_event (GstNavigation *navigation,
       gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
     }
 
-  gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (xvimagesink)), event);
+  gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (xvimagesink)),
+                      event);
 }
 
 static void
@@ -1044,9 +1095,7 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
   g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
   
   if (!xvimagesink->xcontext)
-    {
-      xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink);
-    }
+    xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink);
   
   if ( (xvimagesink->xwindow) && (xvimagesink->xvimage) )
     { /* If we are replacing a window we destroy pictures and window as they
@@ -1078,9 +1127,20 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
 }
 
 static void
+gst_xvimagesink_get_desired_size (GstXOverlay *overlay,
+                                  guint *width, guint *height)
+{
+  GstXvImageSink *xvimagesink = GST_XVIMAGESINK (overlay);
+
+  *width = GST_VIDEOSINK_WIDTH (xvimagesink);
+  *height = GST_VIDEOSINK_HEIGHT (xvimagesink);
+}
+
+static void
 gst_xvimagesink_xoverlay_init (GstXOverlayClass *iface)
 {
   iface->set_xwindow_id = gst_xvimagesink_set_xwindow_id;
+  iface->get_desired_size = gst_xvimagesink_get_desired_size;
 }
 
 /* =========================================== */
index 76a735f..5d4f246 100644 (file)
@@ -58,20 +58,20 @@ got_found_tag (GstPlay *play,GstElement *source, GstTagList *tag_list)
 static void
 got_time_tick (GstPlay *play, gint64 time_nanos)
 {
-  g_print ("time tick %llu", time_nanos);
+  g_print ("time tick %llu\n", time_nanos);
 }
 
 static void
 got_stream_length (GstPlay *play, gint64 length_nanos)
 {
-  g_print ("got length %llu", length_nanos);
+  g_print ("got length %llu\n", length_nanos);
   length = length_nanos;
 }
 
 static void
 got_video_size (GstPlay *play, gint width, gint height)
 {
-  g_print ("got video size %d, %d", width, height);
+  g_print ("got video size %d, %d\n", width, height);
 }
 
 static void