Index: ext/ogg/gstoggdemux.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.c,v
retrieving revision 1.199
diff -u -r1.199 gstoggdemux.c
--- ext/ogg/gstoggdemux.c	10 Dec 2008 14:55:10 -0000	1.199
+++ ext/ogg/gstoggdemux.c	16 Jan 2009 04:28:29 -0000
@@ -961,6 +961,13 @@
     gst_ogg_pad_parse_skeleton_fisbone (pad, packet);
   }
 
+  if (pad->codec == GST_OGG_PAD_CODEC_UNKNOWN) {
+    if (packet->bytes >= 7 && packet->packet[0] == 0x80 &&
+        !memcmp (packet->packet + 1, "theora", 6)) {
+      pad->codec = GST_OGG_PAD_CODEC_THEORA;
+    }
+  }
+
   granule = packet->granulepos;
   if (granule != -1) {
     GST_DEBUG_OBJECT (ogg, "%p has granulepos %" G_GINT64_FORMAT, pad, granule);
@@ -2561,6 +2568,15 @@
     }
   }
 
+  /* we are about to set segment_stop (the time of the end of the video) based
+   * on the starting time of last_granule.  for theora, this is incorrect.
+   * what we really want is the time up through the last granule.  to do this,
+   * we will calculate the time based on last_granule+1.  the starting time of
+   * this technically non-existent granule is the length of the video
+   */
+  if (last_granule != -1 && last_pad->codec == GST_OGG_PAD_CODEC_THEORA)
+    ++last_granule;
+
   target = GST_FORMAT_TIME;
   if (last_granule == -1 || !gst_ogg_pad_query_convert (last_pad,
           GST_FORMAT_DEFAULT, last_granule, &target,
Index: ext/ogg/gstoggdemux.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/ext/ogg/gstoggdemux.h,v
retrieving revision 1.6
diff -u -r1.6 gstoggdemux.h
--- ext/ogg/gstoggdemux.h	4 Nov 2008 17:24:35 -0000	1.6
+++ ext/ogg/gstoggdemux.h	16 Jan 2009 04:28:29 -0000
@@ -79,6 +79,13 @@
   GST_OGG_PAD_MODE_STREAMING,   /* we are streaming buffers to the outside */
 } GstOggPadMode;
 
+/* different codecs for the pad */
+typedef enum
+{
+  GST_OGG_PAD_CODEC_UNKNOWN,
+  GST_OGG_PAD_CODEC_THEORA
+} GstOggPadCodec;
+
 /* all information needed for one ogg stream */
 struct _GstOggPad
 {
@@ -96,7 +103,8 @@
 
   GList *headers;
 
-  gboolean is_skeleton;
+  GstOggPadCodec codec;
+  gboolean is_skeleton; /* TODO: merge into GstOggPadCodec? */
   gboolean have_fisbone;
   gint64 granulerate_n;
   gint64 granulerate_d;
