Index: ext/alsa/gstalsaclock.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/ext/alsa/Attic/gstalsaclock.c,v
retrieving revision 1.8
diff -u -r1.8 gstalsaclock.c
--- ext/alsa/gstalsaclock.c	17 Jan 2005 12:45:27 -0000	1.8
+++ ext/alsa/gstalsaclock.c	24 Jan 2006 04:49:02 -0000
@@ -89,6 +89,7 @@
   gst_object_set_name (GST_OBJECT (clock), "GstAlsaClock");
 
   clock->start_time = GST_CLOCK_TIME_NONE;
+  clock->fallback_time = GST_CLOCK_TIME_NONE;
 }
 
 GstAlsaClock *
@@ -135,6 +136,7 @@
       GST_TIMEVAL_TO_TIME (timeval) -
       gst_clock_get_event_time (GST_CLOCK (clock));
   clock->start_time = GST_CLOCK_TIME_NONE;
+  clock->fallback_time = GST_CLOCK_TIME_NONE;
 }
 
 static GstClockTime
@@ -172,8 +174,11 @@
   GTimeVal t;
 
   entry_time = gst_alsa_clock_get_internal_time (clock);
-  diff = GST_CLOCK_ENTRY_TIME (entry) - gst_clock_get_time (clock);
-
+  if (GST_CLOCK_TIME_IS_VALID (this->fallback_time)) {
+    diff = GST_CLOCK_ENTRY_TIME (entry) - this->fallback_time;
+  } else {
+    diff = GST_CLOCK_ENTRY_TIME (entry) - gst_clock_get_time (clock);
+  }
   if (diff < 0)
     return GST_CLOCK_ENTRY_EARLY;
 
@@ -202,6 +207,11 @@
     g_get_current_time (&t);
     glib_cur = GST_TIMEVAL_TO_TIME (t);
   }
+  if (glib_start + diff * 1.5 <= glib_cur) {
+    this->fallback_time = GST_CLOCK_ENTRY_TIME (entry);
+  } else {
+    this->fallback_time = GST_CLOCK_TIME_NONE;
+  }
 
   return entry->status;
 }
Index: ext/alsa/gstalsaclock.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/ext/alsa/Attic/gstalsaclock.h,v
retrieving revision 1.4
diff -u -r1.4 gstalsaclock.h
--- ext/alsa/gstalsaclock.h	15 Mar 2004 16:32:29 -0000	1.4
+++ ext/alsa/gstalsaclock.h	24 Jan 2006 04:49:02 -0000
@@ -43,6 +43,8 @@
   GstClockTimeDiff		adjust; 	/* adjustment to real clock (recalculated when stopping) */
   GstClockTime			start_time;	/* time when the stream started (NONE when stopped) */
   GstClockTime			last_unlock;    /* time of last unlock request */
+
+  GstClockTime			fallback_time;
 };
 
 struct _GstAlsaClockClass {
Index: gst/playback/gstplaybasebin.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/playback/Attic/gstplaybasebin.c,v
retrieving revision 1.62.2.23
diff -u -r1.62.2.23 gstplaybasebin.c
--- gst/playback/gstplaybasebin.c	7 Aug 2005 17:48:02 -0000	1.62.2.23
+++ gst/playback/gstplaybasebin.c	24 Jan 2006 04:49:12 -0000
@@ -869,8 +869,8 @@
         source = GST_OBJECT (play_base_bin);
       }
       /* emit the signal now */
-      g_signal_emit_by_name (G_OBJECT (play_base_bin),
-          "found-tag", source, taglist);
+      //g_signal_emit_by_name (G_OBJECT (play_base_bin),
+          //"found-tag", source, taglist);
       /* and unref */
       gst_object_unref (GST_OBJECT (play_base_bin));
       gst_event_unref (event);
@@ -2045,7 +2060,7 @@
       GST_ELEMENT_NAME (source), GST_OBJECT_NAME (play_base_bin));
 
   /* this would signal completely out-of-band */
-  //g_signal_emit_by_name (G_OBJECT (play_base_bin), "found-tag", source, taglist);
+  g_signal_emit_by_name (G_OBJECT (play_base_bin), "found-tag", source, taglist);
 
   GST_DEBUG ("forwarded taglist %p from %s to %s", taglist,
       GST_ELEMENT_NAME (source), GST_OBJECT_NAME (play_base_bin));
Index: gst/qtdemux/qtdemux.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/qtdemux/Attic/qtdemux.c,v
retrieving revision 1.80.2.16
diff -u -r1.80.2.16 qtdemux.c
--- gst/qtdemux/qtdemux.c	14 Aug 2005 17:09:04 -0000	1.80.2.16
+++ gst/qtdemux/qtdemux.c	24 Jan 2006 04:49:14 -0000
@@ -1928,7 +1979,7 @@
   return NULL;
 }
 
-static void qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak);
+static QtDemuxStream * qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak);
 
 static void
 qtdemux_parse_tree (GstQTDemux * qtdemux)
@@ -1936,6 +1987,7 @@
   GNode *mvhd;
   GNode *trak;
   GNode *udta;
+  GstBuffer *image = NULL;
 
   mvhd = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_mvhd);
   if (mvhd == NULL) {
@@ -1965,39 +2017,71 @@
   GST_INFO ("timescale: %d", qtdemux->timescale);
   GST_INFO ("duration: %d", qtdemux->duration);
 
+  /* parse all streams */
   trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak);
-  qtdemux_parse_trak (qtdemux, trak);
+  do {
+    QtDemuxStream *s;
 
-/*  trak = qtdemux_tree_get_sibling_by_type(trak, FOURCC_trak);
-  if(trak)qtdemux_parse_trak(qtdemux, trak);*/
+    if ((s = qtdemux_parse_trak (qtdemux, trak)) != NULL) {
+      if (image == NULL) {
+        guint64 pos, off = s->samples[0].offset;
+        gint size = s->samples[0].size, res;
+        GstBuffer *buf;
 
-  /* kid pads */
-  while ((trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak)) != NULL)
-    qtdemux_parse_trak (qtdemux, trak);
+        if (gst_bytestream_seek (qtdemux->bs, off, GST_SEEK_METHOD_SET) ||
+            ((pos = gst_bytestream_tell (qtdemux->bs)) <= off &&
+              (off - pos == 0 ||
+               gst_bytestream_flush (qtdemux->bs, off - pos)))) {
+          while ((res = gst_bytestream_peek (qtdemux->bs, &buf, size)) < size) {
+            if (!gst_qtdemux_handle_sink_event (qtdemux))
+              break;
+          }
+          if (res == size || (size < 0 && res > 0))
+            image = buf;
+        }
+      }
+      g_free (s);
+    }
+  } while ((trak = qtdemux_tree_get_sibling_by_type (trak,
+						     FOURCC_trak)) != NULL);
   gst_element_no_more_pads (GST_ELEMENT (qtdemux));
 
   /* tags */
   udta = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_udta);
-  if (udta) {
+  if (udta)
     qtdemux_parse_udta (qtdemux, udta);
 
-    if (qtdemux->tag_list) {
-      GstEvent *event;
-      gchar *t;
+  if (image) {
+    if (!qtdemux->tag_list)
+      qtdemux->tag_list = gst_tag_list_new ();
 
-      event = gst_event_new_tag (gst_tag_list_copy (qtdemux->tag_list));
-      gst_pad_event_default (qtdemux->sinkpad, event);
-      t = gst_structure_to_string (qtdemux->tag_list);
-      GST_DEBUG ("calling gst_element_found_tags with %s", t);
-      g_free (t);
-      gst_element_found_tags (GST_ELEMENT (qtdemux), qtdemux->tag_list);
-    }
-  } else {
-    GST_LOG ("No udta node found.");
+    gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
+		      GST_TAG_IMAGE, image, NULL);
+    gst_buffer_unref (image);
+  }
+
+  if (qtdemux->tag_list) {
+    GstEvent *event;
+    gchar *t;
+
+    event = gst_event_new_tag (gst_tag_list_copy (qtdemux->tag_list));
+    gst_pad_event_default (qtdemux->sinkpad, event);
+    t = gst_structure_to_string (qtdemux->tag_list);
+    GST_DEBUG ("calling gst_element_found_tags with %s", t);
+    g_free (t);
+    gst_element_found_tags (GST_ELEMENT (qtdemux), qtdemux->tag_list);
   }
 }
 
-static void
+/*
+ * NOTE!
+ *
+ * A stream is returned *only* and *only* if it was *not* added as a regular
+ * stream. This happens only if it is a single-image stream and should be
+ * exported as a screenshot.
+ */
+
+static QtDemuxStream *
 qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
 {
   int offset;
@@ -2050,20 +2134,6 @@
   GST_LOG ("track timescale: %d", stream->timescale);
   GST_LOG ("track duration: %d", QTDEMUX_GUINT32_GET (mdhd->data + 24));
 
-  /* HACK:
-   * some of those trailers, nowadays, have prologue images that are
-   * themselves vide tracks as well. I haven't really found a way to
-   * identify those yet, except for just looking at their duration. */
-  if (stream->timescale * qtdemux->duration != 0 &&
-      (guint64) QTDEMUX_GUINT32_GET (mdhd->data + 24) *
-      qtdemux->timescale * 10 / (stream->timescale * qtdemux->duration) < 2) {
-    GST_WARNING ("Track shorter than 20%% (%d/%d vs. %d/%d) of the stream "
-        "found, assuming preview image or something; skipping track",
-        QTDEMUX_GUINT32_GET (mdhd->data + 24), stream->timescale,
-        qtdemux->duration, qtdemux->timescale);
-    return;
-  }
-
   hdlr = qtdemux_tree_get_child_by_type (mdia, FOURCC_hdlr);
   g_assert (hdlr);
 
@@ -2295,7 +2377,8 @@
   } else {
     GST_INFO ("unknown subtype " GST_FOURCC_FORMAT,
         GST_FOURCC_ARGS (stream->subtype));
-    return;
+    g_free (stream);
+    return NULL;
   }
 
   /* sample to chunk */
@@ -2482,7 +2565,29 @@
       break;
   }
 #endif
+  if (stream->n_samples == 1 &&
+      stream->subtype == FOURCC_vide) {
+    if (list)
+      gst_tag_list_free (list);
+    return stream;
+  /* HACK:
+   * some of those trailers, nowadays, have prologue images that are
+   * themselves vide tracks as well. I haven't really found a way to
+   * identify those yet, except for just looking at their duration. */
+  } else if (stream->timescale * qtdemux->duration != 0 &&
+      (guint64) QTDEMUX_GUINT32_GET (mdhd->data + 24) *
+      qtdemux->timescale * 10 / (stream->timescale * qtdemux->duration) < 2 &&
+      stream->subtype == FOURCC_vide) {
+    GST_WARNING ("Track shorter than 20%% (%d/%d vs. %d/%d) of the stream "
+        "found, assuming preview image or something; skipping track",
+        QTDEMUX_GUINT32_GET (mdhd->data + 24), stream->timescale,
+        qtdemux->duration, qtdemux->timescale);
+    return stream;
+  }
+
   gst_qtdemux_add_stream (qtdemux, stream, list);
+
+  return NULL;
 }
 
 static void
Index: sys/xvimage/xvimagesink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/sys/xvimage/Attic/xvimagesink.c,v
retrieving revision 1.100.2.10
diff -u -r1.100.2.10 xvimagesink.c
--- sys/xvimage/xvimagesink.c	29 Sep 2005 11:09:19 -0000	1.100.2.10
+++ sys/xvimage/xvimagesink.c	24 Jan 2006 04:49:23 -0000
@@ -403,7 +403,7 @@
 /* This function handles a GstXWindow creation
  * The width and height are the actual pixel size on the display */
 static GstXWindow *
-gst_xvimagesink_xwindow_new (GstXvImageSink * xvimagesink,
+gst_xvimagesink_own_xwindow_new (GstXvImageSink * xvimagesink,
     gint width, gint height)
 {
   GstXWindow *xwindow = NULL;
@@ -445,6 +445,45 @@
   return xwindow;
 }
 
+static GstXWindow *
+gst_xvimagesink_ext_xwindow_new (GstXvImageSink *xvimagesink)
+{
+  GstXWindow *xwindow;
+  XWindowAttributes attr;
+
+  xwindow = g_new0 (GstXWindow, 1);
+  xwindow->win = xvimagesink->saved_xwindow_id;
+  /* We get window geometry, set the event we want to receive,
+     and create a GC */
+  g_mutex_lock (xvimagesink->x_lock);
+  XGetWindowAttributes (xvimagesink->xcontext->disp, xwindow->win, &attr);
+  xwindow->width = attr.width;
+  xwindow->height = attr.height;
+  xwindow->internal = FALSE;
+  GST_LOG_OBJECT (xvimagesink, "xwindow with xid %ld is %dx%d", xwindow->win,
+      xwindow->width, xwindow->height);
+  XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
+      StructureNotifyMask | PointerMotionMask | KeyPressMask |
+      KeyReleaseMask);
+
+  xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
+      xwindow->win, 0, NULL);
+  g_mutex_unlock (xvimagesink->x_lock);
+
+  return xwindow;
+}
+
+static GstXWindow *
+gst_xvimagesink_xwindow_new (GstXvImageSink *xvimagesink, gint width,
+    gint height)
+{
+  if (xvimagesink->saved_xwindow_id == 0) {
+    return gst_xvimagesink_own_xwindow_new (xvimagesink, width, height);
+  } else {
+    return gst_xvimagesink_ext_xwindow_new (xvimagesink);
+  }
+}
+
 /* This function destroys a GstXWindow */
 static void
 gst_xvimagesink_xwindow_destroy (GstXvImageSink * xvimagesink,
@@ -1102,7 +1141,7 @@
       xvimagesink->xcontext->xv_port_id, 0);
 
   XCloseDisplay (xvimagesink->xcontext->disp);
-
+GST_DEBUG ("xcontext cleared");
   g_mutex_unlock (xvimagesink->x_lock);
 
   g_free (xvimagesink->xcontext);
@@ -1256,10 +1295,8 @@
   }
   /* get display's PAR */
   if (xvimagesink->par) {
-    display_par_n =
-        MAX (gst_value_get_fraction_numerator (xvimagesink->par), 1);
-    display_par_d =
-        MAX (gst_value_get_fraction_denominator (xvimagesink->par), 1);
+    display_par_n = gst_value_get_fraction_numerator (xvimagesink->par);
+    display_par_d = gst_value_get_fraction_denominator (xvimagesink->par);
   } else {
     display_par_n = 1;
     display_par_d = 1;
@@ -1348,6 +1385,7 @@
       if (!xvimagesink->xcontext &&
           !(xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink)))
         return GST_STATE_FAILURE;
+
       /* update object's par with calculated one if not set yet */
       if (!xvimagesink->par) {
         xvimagesink->par = g_new0 (GValue, 1);
@@ -1361,6 +1399,18 @@
       XSynchronize (xvimagesink->xcontext->disp, xvimagesink->synchronous);
       g_mutex_unlock (xvimagesink->x_lock);
       gst_xvimagesink_update_colorbalance (xvimagesink);
+
+      if (xvimagesink->saved_xwindow_id != 0) {
+        GstXWindow *win;
+
+        if ((win = gst_xvimagesink_xwindow_new (xvimagesink, 0, 0)))
+          xvimagesink->xwindow = win;
+        else {
+          gst_xvimagesink_xcontext_clear (xvimagesink);
+          xvimagesink->xcontext = NULL;
+          return GST_STATE_FAILURE;
+        }
+      }
       break;
     case GST_STATE_READY_TO_PAUSED:
       xvimagesink->time = 0;
@@ -1576,8 +1626,7 @@
       /* We check for geometry or image format changes */
       if ((xvimage->width != xvimagesink->video_width) ||
           (xvimage->height != xvimagesink->video_height) ||
-          (xvimage->im_format != xvimagesink->xcontext->im_format) ||
-          (xvimage->size < size)) {
+          (xvimage->im_format != xvimagesink->xcontext->im_format)) {
         /* This image is unusable. Destroying... */
         gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage);
         xvimage = NULL;
@@ -1597,13 +1646,6 @@
         xvimagesink->video_height);
   }
 
-  if (xvimage && xvimage->size < size) {
-    g_warning ("gst_xvimagesink_xvimage_new failed to create image "
-        "of suitable size (Wanted %u, got %u)", size, xvimage->size);
-    gst_xvimagesink_xvimage_destroy (xvimagesink, xvimage);
-    xvimage = NULL;
-  }
-
   if (xvimage) {
     buffer = gst_buffer_new ();
     /* Storing some pointers in the buffer */
@@ -1712,17 +1754,15 @@
 {
   GstXvImageSink *xvimagesink = GST_XVIMAGESINK (overlay);
   GstXWindow *xwindow = NULL;
-  XWindowAttributes attr;
 
   g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
   /* If we already use that window return */
-  if (xvimagesink->xwindow && (xwindow_id == xvimagesink->xwindow->win))
+  if (xvimagesink->xwindow && (xwindow_id == xvimagesink->saved_xwindow_id))
     return;
-  /* If the element has not initialized the X11 context try to do so */
-  if (!xvimagesink->xcontext &&
-      !(xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink)))
-    /* we have thrown a GST_ELEMENT_ERROR now */
+  xvimagesink->saved_xwindow_id = xwindow_id;
+  if (xvimagesink->xcontext == NULL)
     return;
+
   gst_xvimagesink_update_colorbalance (xvimagesink);
   /* We acquire the stream lock while setting this window in the element.
      We are basically cleaning tons of stuff replacing the old window, putting
@@ -1742,39 +1782,14 @@
     xvimagesink->xwindow = NULL;
   }
 
-  /* If the xid is 0 we go back to an internal window */
-  if (xwindow_id == 0) {
-    /* If no width/height caps nego did not happen window will be created
-       during caps nego then */
-    if (GST_VIDEOSINK_WIDTH (xvimagesink)
-        && GST_VIDEOSINK_HEIGHT (xvimagesink)) {
-      xwindow =
-          gst_xvimagesink_xwindow_new (xvimagesink,
-          GST_VIDEOSINK_WIDTH (xvimagesink),
-          GST_VIDEOSINK_HEIGHT (xvimagesink));
-    }
-  } else {
-    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 (xvimagesink->x_lock);
-    XGetWindowAttributes (xvimagesink->xcontext->disp, xwindow->win, &attr);
-    xwindow->width = attr.width;
-    xwindow->height = attr.height;
-    xwindow->internal = FALSE;
-    GST_LOG_OBJECT (xvimagesink, "xwindow with xid %ld is %dx%d", xwindow_id,
-        xwindow->width, xwindow->height);
-    XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
-        StructureNotifyMask | PointerMotionMask | KeyPressMask |
-        KeyReleaseMask);
-
-    xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
-        xwindow->win, 0, NULL);
-    g_mutex_unlock (xvimagesink->x_lock);
-  }
+  if (xwindow_id == 0 &&
+      (GST_VIDEOSINK_WIDTH (xvimagesink) == 0 ||
+       GST_VIDEOSINK_HEIGHT (xvimagesink) == 0))
+    return;
 
-  if (xwindow)
+  if ((xwindow = gst_xvimagesink_xwindow_new (xvimagesink,
+           GST_VIDEOSINK_WIDTH (xvimagesink),
+           GST_VIDEOSINK_HEIGHT (xvimagesink))) != NULL)
     xvimagesink->xwindow = xwindow;
   g_mutex_unlock (xvimagesink->stream_lock);
 }
@@ -1968,12 +1983,6 @@
       GST_DEBUG_OBJECT (xvimagesink, "set PAR to %d/%d",
           gst_value_get_fraction_numerator (xvimagesink->par),
           gst_value_get_fraction_denominator (xvimagesink->par));
-      if (gst_value_get_fraction_numerator (xvimagesink->par) <= 0
-          || gst_value_get_fraction_denominator (xvimagesink->par) <= 0) {
-        GST_WARNING_OBJECT (xvimagesink, "Invalid PAR, defaulting to 1/1");
-        g_free (xvimagesink->par);
-        xvimagesink->par = NULL;
-      }
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -2009,9 +2018,8 @@
       g_value_set_boolean (value, xvimagesink->synchronous);
       break;
     case ARG_PIXEL_ASPECT_RATIO:
-      if (!xvimagesink->par || !g_value_transform (xvimagesink->par, value)) {
-        g_value_set_string (value, "1/1");
-      }
+      if (xvimagesink->par)
+        g_value_transform (xvimagesink->par, value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -2126,14 +2134,7 @@
 
   gobject_class = (GObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  gobject_class->finalize = gst_xvimagesink_finalize;
-  gobject_class->set_property = gst_xvimagesink_set_property;
-  gobject_class->get_property = gst_xvimagesink_get_property;
-  gstelement_class->change_state = gst_xvimagesink_change_state;
-
+  parent_class = g_type_class_ref (GST_TYPE_VIDEOSINK);
   g_object_class_install_property (gobject_class, ARG_CONTRAST,
       g_param_spec_int ("contrast", "Contrast",
           "The contrast of the video", -1000, 1000, 0, G_PARAM_READWRITE));
@@ -2157,6 +2158,10 @@
   g_object_class_install_property (gobject_class, ARG_PIXEL_ASPECT_RATIO,
       g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio",
           "The pixel aspect ratio of the device", "1/1", G_PARAM_READWRITE));
+  gobject_class->finalize = gst_xvimagesink_finalize;
+  gobject_class->set_property = gst_xvimagesink_set_property;
+  gobject_class->get_property = gst_xvimagesink_get_property;
+  gstelement_class->change_state = gst_xvimagesink_change_state;
 }
 
 /* ============================================================= */
Index: sys/xvimage/xvimagesink.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/sys/xvimage/Attic/xvimagesink.h,v
retrieving revision 1.28.2.1
diff -u -r1.28.2.1 xvimagesink.h
--- sys/xvimage/xvimagesink.h	9 Mar 2005 11:48:30 -0000	1.28.2.1
+++ sys/xvimage/xvimagesink.h	24 Jan 2006 04:49:23 -0000
@@ -158,6 +158,8 @@
 
   GMutex *nav_lock;
   GSList *pend_nav_events;
+
+  Window saved_xwindow_id;
 };
 
 struct _GstXvImageSinkClass {
