Index: ext/alsa/gstalsasink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/ext/alsa/Attic/gstalsasink.c,v
retrieving revision 1.39.2.2
diff -u -r1.39.2.2 gstalsasink.c
--- ext/alsa/gstalsasink.c	5 May 2005 19:23:06 -0000	1.39.2.2
+++ ext/alsa/gstalsasink.c	11 Jun 2005 12:29:20 -0000
@@ -255,7 +255,7 @@
       case GST_EVENT_FILLER:{
         guint64 dur = gst_event_filler_get_duration (event);
 
-        if (GST_CLOCK_TIME_IS_VALID (dur)) {
+        if (this->format && GST_CLOCK_TIME_IS_VALID (dur)) {
           gint samples;
           GstBuffer *buf;
 
Index: gst/mpegstream/gstdvddemux.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/mpegstream/gstdvddemux.c,v
retrieving revision 1.18.2.6
diff -u -r1.18.2.6 gstdvddemux.c
--- gst/mpegstream/gstdvddemux.c	22 Apr 2005 14:24:09 -0000	1.18.2.6
+++ gst/mpegstream/gstdvddemux.c	11 Jun 2005 12:29:31 -0000
@@ -309,6 +309,7 @@
   }
 
   dvd_demux->langcodes = NULL;
+  dvd_demux->ignore_next_newmedia_discont = FALSE;
 }
 
 
@@ -445,9 +446,75 @@
 
     gst_event_unref (event);
   } else if (!strcmp (event_type, "dvd-lang-codes")) {
+    gint num_substreams = 0, num_audstreams = 0, n;
+    GstStructure *s;
+    gchar *t;
+
+    /* reset */
     if (dvd_demux->langcodes)
       gst_event_unref (dvd_demux->langcodes);
+    PARSE_CLASS (dvd_demux)->handle_discont (mpeg_parse,
+        gst_event_new_discontinuous (TRUE, GST_FORMAT_UNDEFINED));
+
+    /* see what kind of streams we have */
     dvd_demux->langcodes = event;
+    s = event->event_data.structure.structure;
+
+    /* now create pads for each; first video */
+    n = 2;
+    DEMUX_CLASS (dvd_demux)->get_video_stream (mpeg_demux,
+        0, GST_MPEG_DEMUX_VIDEO_MPEG, &n);
+
+    /* audio */
+    for (n = 0; ; n++) {
+      gint fmt, ifo = 0;
+
+      t = g_strdup_printf ("audio-%d-format", num_audstreams);
+      if (!gst_structure_get_int (s, t, &fmt)) {
+        g_free (t);
+        break;
+      }
+      g_free (t);
+      switch (fmt) {
+        case 0x0: /* AC-3 */
+          fmt = GST_DVD_DEMUX_AUDIO_AC3;
+          break;
+        case 0x2: case 0x3: /* MPEG */
+          fmt = GST_MPEG_DEMUX_AUDIO_MPEG;
+          break;
+        case 0x4:
+          fmt = GST_DVD_DEMUX_AUDIO_LPCM;
+          break;
+        case 0x6:
+          fmt = GST_DVD_DEMUX_AUDIO_DTS;
+          break;
+        default:
+          fmt = GST_MPEG_DEMUX_AUDIO_UNKNOWN;
+          break;
+      }
+      DEMUX_CLASS (dvd_demux)->get_audio_stream (mpeg_demux,
+          num_audstreams++, fmt, &ifo);
+    }
+
+    /* subtitle */
+    for (;;) {
+      t = g_strdup_printf ("subtitle-%d-language", num_substreams);
+      if (!gst_structure_get_value (s, t)) {
+        g_free (t);
+        break;
+      }
+      g_free (t);
+      CLASS (dvd_demux)->get_subpicture_stream (mpeg_demux,
+           num_substreams++, GST_DVD_DEMUX_SUBP_DVD, NULL);
+    }
+    GST_DEBUG_OBJECT (dvd_demux,
+        "Created 1 video stream, %d audio streams and %d subpicture streams "
+        "based on DVD lang codes event; now signalling no-more-pads",
+        num_audstreams, num_substreams);
+
+    /* we know this will be all */
+    gst_element_no_more_pads (GST_ELEMENT (dvd_demux));
+    dvd_demux->ignore_next_newmedia_discont = TRUE;
   } else {
     GST_DEBUG_OBJECT (dvd_demux, "dvddemux Forwarding DVD event %s to all pads",
         event_type);
@@ -502,7 +569,11 @@
   GstDVDDemux *dvd_demux = GST_DVD_DEMUX (mpeg_parse);
 
   if (GST_EVENT_DISCONT_NEW_MEDIA (event)) {
-    gst_dvd_demux_reset (dvd_demux);
+    /* HACK */
+    if (dvd_demux->ignore_next_newmedia_discont)
+      GST_EVENT_DISCONT_NEW_MEDIA (event) = FALSE;
+    else
+      gst_dvd_demux_reset (dvd_demux);
   }
 
   /* let parent handle and forward discont */
@@ -983,6 +1054,8 @@
     dvd_demux->discont_time = GST_CLOCK_TIME_NONE;
   }
 
+  dvd_demux->ignore_next_newmedia_discont = FALSE;
+
   /* You never know what happens to a buffer when you send it.  Just
      in case, we keep a reference to the buffer during the execution
      of this function. */
@@ -1198,6 +1271,7 @@
         gst_event_unref (dvd_demux->langcodes);
         dvd_demux->langcodes = NULL;
       }
+      dvd_demux->ignore_next_newmedia_discont = FALSE;
       break;
     default:
       break;
Index: gst/mpegstream/gstdvddemux.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/mpegstream/gstdvddemux.h,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 gstdvddemux.h
--- gst/mpegstream/gstdvddemux.h	17 Apr 2005 20:46:45 -0000	1.7.2.2
+++ gst/mpegstream/gstdvddemux.h	11 Jun 2005 12:29:32 -0000
@@ -113,6 +113,8 @@
 				/* Subpicture output streams. */
 
   GstEvent *langcodes;
+
+  gboolean ignore_next_newmedia_discont;
 };
 
 
Index: gst/playback/gstplaybasebin.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v
retrieving revision 1.62.2.16
diff -u -r1.62.2.16 gstplaybasebin.c
--- gst/playback/gstplaybasebin.c	10 Jun 2005 13:29:53 -0000	1.62.2.16
+++ gst/playback/gstplaybasebin.c	11 Jun 2005 12:29:36 -0000
@@ -585,6 +585,8 @@
     prename = "text";
   else if (type == GST_STREAM_TYPE_AUDIO)
     prename = "audio";
+  else if (type == GST_STREAM_TYPE_SUBPICTURE)
+    prename = "subpicture";
   else
     g_return_if_reached ();
 
@@ -643,6 +645,10 @@
   gst_element_link (selector, preroll);
   group->type[type - 1].selector = selector;
   group->type[type - 1].preroll = preroll;
+  if (type == GST_STREAM_TYPE_SUBPICTURE) {
+    g_object_set (G_OBJECT (preroll), "block-timeout",
+        (guint64) GST_MSECOND * 20, NULL);
+  }
   if (type == GST_STREAM_TYPE_TEXT && play_base_bin->subtitle) {
     group->type[type - 1].bin = GST_BIN (play_base_bin->subtitle);
     gst_bin_add (GST_BIN (play_base_bin->subtitle), selector);
@@ -921,6 +927,33 @@
   return FALSE;
 }
 
+/*
+ */
+
+static gboolean
+has_subtitle_ancestor (GstPad * src)
+{
+  GList *list;
+  GstPad *sink = NULL;
+  gint len;
+
+  for (;;) {
+    if (strstr (GST_OBJECT_NAME (src), "subtitle") ||
+        strstr (GST_OBJECT_NAME (src), "subpicture"))
+      return TRUE;
+    list = gst_pad_get_internal_links (src);
+    if ((len = g_list_length (list)) == 1)
+      if ((sink = list->data))
+        src = GST_PAD_PEER (sink);
+    g_list_free (list);
+
+    if (len != 1 || !sink || !src)
+      break;
+  }
+
+  return FALSE;
+}
+
 /* signal fired when decodebin has found a new raw pad. We create
  * a preroll element if needed and the appropriate streaminfo.
  */
@@ -965,7 +998,10 @@
   } else if (g_str_has_prefix (mimetype, "video/") &&
       gst_object_get_parent (GST_OBJECT (element)) !=
       GST_OBJECT (play_base_bin->subtitle)) {
-    type = GST_STREAM_TYPE_VIDEO;
+    if (has_subtitle_ancestor (pad))
+      type = GST_STREAM_TYPE_SUBPICTURE;
+    else
+      type = GST_STREAM_TYPE_VIDEO;
   } else if (g_str_has_prefix (mimetype, "text/")) {
     type = GST_STREAM_TYPE_TEXT;
   } else {
@@ -981,14 +1017,18 @@
     }
   }
 
-  /* add to stream selector */
-  sinkpad = gst_element_get_pad (group->type[type - 1].selector, "sink%d");
-  /* make sure we catch unlink signals */
-  sig = g_signal_connect (G_OBJECT (sinkpad), "unlinked",
-      G_CALLBACK (preroll_unlinked), play_base_bin);
-  /* keep a ref to the signal id so that we can disconnect the signal callback */
-  g_object_set_data (G_OBJECT (sinkpad), "unlinked_id", GINT_TO_POINTER (sig));
-  gst_pad_link (pad, sinkpad);
+  if (type != GST_STREAM_TYPE_UNKNOWN) {
+    /* add to stream selector */
+    sinkpad = gst_element_get_pad (group->type[type - 1].selector, "sink%d");
+    /* make sure we catch unlink signals */
+    sig = g_signal_connect (G_OBJECT (sinkpad), "unlinked",
+        G_CALLBACK (preroll_unlinked), play_base_bin);
+    /* keep a ref to the signal id so that we can disconnect the
+     * signal callback */
+    g_object_set_data (G_OBJECT (sinkpad), "unlinked_id",
+        GINT_TO_POINTER (sig));
+    gst_pad_link (pad, sinkpad);
+  }
 
   /* add the stream to the list */
   gst_caps_free (caps);
Index: gst/playback/gstplaybasebin.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h,v
retrieving revision 1.12.2.3
diff -u -r1.12.2.3 gstplaybasebin.h
--- gst/playback/gstplaybasebin.h	1 Apr 2005 11:15:22 -0000	1.12.2.3
+++ gst/playback/gstplaybasebin.h	11 Jun 2005 12:29:36 -0000
@@ -58,7 +58,7 @@
     GstElement	*preroll;
     GstElement	*selector;
     gboolean	 done;
-#define NUM_TYPES 3
+#define NUM_TYPES 4
   } type[NUM_TYPES]; /* AUDIO, VIDEO, TEXT */
 } GstPlayBaseGroup;
 
Index: gst/playback/gstplaybin.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybin.c,v
retrieving revision 1.36.2.3
diff -u -r1.36.2.3 gstplaybin.c
--- gst/playback/gstplaybin.c	9 May 2005 09:11:16 -0000	1.36.2.3
+++ gst/playback/gstplaybin.c	11 Jun 2005 12:29:37 -0000
@@ -469,21 +469,21 @@
  */
 
 static GstElement *
-gen_text_element (GstPlayBin * play_bin)
+gen_subtitle_element (GstPlayBin * play_bin, gboolean need_text_render)
 {
   GstElement *element, *csp, *overlay, *vbin;
 
-  overlay = gst_element_factory_make ("textoverlay", "overlay");
-  g_object_set (G_OBJECT (overlay),
-      "halign", "center", "valign", "bottom", NULL);
-  play_bin->textoverlay_element = overlay;
-  if (play_bin->font_desc) {
-    g_object_set (G_OBJECT (play_bin->textoverlay_element),
-        "font-desc", play_bin->font_desc, NULL);
-  }
+  overlay = gst_element_factory_make ("imagemixer", "blender");
+//  g_object_set (G_OBJECT (overlay),
+//      "halign", "center", "valign", "bottom", NULL);
+//  play_bin->textoverlay_element = overlay;
+//  if (play_bin->font_desc) {
+//    g_object_set (G_OBJECT (play_bin->textoverlay_element),
+//        "font-desc", play_bin->font_desc, NULL);
+//  }
   vbin = gen_video_element (play_bin);
   if (!overlay) {
-    g_warning ("No overlay (pango) element, subtitles disabled");
+    g_warning ("No overlay rendering element, subtitles disabled");
     return vbin;
   }
   csp = gst_element_factory_make ("ffmpegcolorspace", "subtitlecsp");
@@ -492,7 +492,7 @@
   gst_bin_add_many (GST_BIN (element), csp, overlay, vbin, NULL);
 
   gst_element_add_ghost_pad (element,
-      gst_element_get_pad (overlay, "text_sink"), "text_sink");
+      gst_element_get_pad (overlay, "subpicture_sink_0"), "subtitle_sink");
   gst_element_add_ghost_pad (element,
       gst_element_get_pad (csp, "sink"), "sink");
 
@@ -751,7 +751,7 @@
   GstPlayBaseGroup *group;
   GList *streaminfo = NULL, *s;
   gboolean need_vis = FALSE;
-  gboolean need_text = FALSE;
+  gboolean need_text = FALSE, need_subpicture = FALSE;
   GstPad *textsrcpad = NULL, *textsinkpad = NULL;
   GstElement *sink;
 
@@ -763,9 +763,12 @@
 
   /* find out what to do */
   group = play_base_bin->queued_groups->data;
-  if (group->type[GST_STREAM_TYPE_VIDEO - 1].npads > 0 &&
-      group->type[GST_STREAM_TYPE_TEXT - 1].npads > 0) {
-    need_text = TRUE;
+  if (group->type[GST_STREAM_TYPE_VIDEO - 1].npads > 0) {
+    if (group->type[GST_STREAM_TYPE_SUBPICTURE - 1].npads > 0) {
+      need_subpicture = TRUE;
+    } else if (group->type[GST_STREAM_TYPE_TEXT - 1].npads > 0) {
+      need_text = TRUE;
+    }
   } else if (group->type[GST_STREAM_TYPE_VIDEO - 1].npads == 0 &&
       group->type[GST_STREAM_TYPE_AUDIO - 1].npads > 0 &&
       play_bin->visualisation != NULL) {
@@ -802,13 +805,19 @@
 
   /* link video */
   if (group->type[GST_STREAM_TYPE_VIDEO - 1].npads > 0) {
-    if (need_text) {
-      sink = gen_text_element (play_bin);
+    if (need_text || need_subpicture) {
+      sink = gen_subtitle_element (play_bin, !need_subpicture);
 
-      textsinkpad = gst_element_get_pad (sink, "text_sink");
-      textsrcpad =
-          gst_element_get_pad (group->type[GST_STREAM_TYPE_TEXT - 1].preroll,
-          "src");
+      textsinkpad = gst_element_get_pad (sink, "subtitle_sink");
+      if (need_subpicture) {
+        textsrcpad =
+            gst_element_get_pad (group->type[GST_STREAM_TYPE_SUBPICTURE - 1].preroll,
+            "src");
+      } else {
+        textsrcpad =
+            gst_element_get_pad (group->type[GST_STREAM_TYPE_TEXT - 1].preroll,
+            "src");
+      }
       if (textsinkpad && textsrcpad) {
         gst_pad_link (textsrcpad, textsinkpad);
       }
Index: gst/playback/gststreaminfo.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gststreaminfo.h,v
retrieving revision 1.7.4.1
diff -u -r1.7.4.1 gststreaminfo.h
--- gst/playback/gststreaminfo.h	17 Apr 2005 20:46:45 -0000	1.7.4.1
+++ gst/playback/gststreaminfo.h	11 Jun 2005 12:29:37 -0000
@@ -35,11 +35,12 @@
 typedef struct _GstStreamInfoClass GstStreamInfoClass;
 
 typedef enum {
-  GST_STREAM_TYPE_UNKNOWN = 0,
-  GST_STREAM_TYPE_AUDIO   = 1,	/* an audio stream */
-  GST_STREAM_TYPE_VIDEO   = 2,	/* a video stream */
-  GST_STREAM_TYPE_TEXT    = 3,	/* a subtitle/text stream */
-  GST_STREAM_TYPE_ELEMENT = 4,	/* stream handled by an element */
+  GST_STREAM_TYPE_UNKNOWN    = 0,
+  GST_STREAM_TYPE_AUDIO      = 1,	/* an audio stream */
+  GST_STREAM_TYPE_VIDEO      = 2,	/* a video stream */
+  GST_STREAM_TYPE_TEXT       = 3,	/* a subtitle/text stream */
+  GST_STREAM_TYPE_SUBPICTURE = 4,	/* a subtitle in picture-form */
+  GST_STREAM_TYPE_ELEMENT    = 5,	/* stream handled by an element */
 } GstStreamType;
 
 struct _GstStreamInfo {
