Index: ext/dvdread/dvdreadsrc.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-ugly/ext/dvdread/dvdreadsrc.c,v
retrieving revision 1.48
diff -u -r1.48 dvdreadsrc.c
--- ext/dvdread/dvdreadsrc.c	19 Oct 2006 10:17:14 -0000	1.48
+++ ext/dvdread/dvdreadsrc.c	13 Nov 2006 03:01:51 -0000
@@ -278,7 +278,7 @@
   src->chapter = 0;
   src->title = 0;
   src->need_newsegment = TRUE;
-  src->vts_tmapt = NULL;
+  src->tmap = NULL;
   if (src->title_lang_event_pending) {
     gst_event_unref (src->title_lang_event_pending);
     src->title_lang_event_pending = NULL;
@@ -339,7 +339,6 @@
 static gboolean
 gst_dvd_read_src_goto_chapter (GstDvdReadSrc * src, gint chapter)
 {
-  gint i;
 
   /* make sure the chapter number is valid for this title */
   if (chapter < 0 || chapter >= src->num_chapters) {
@@ -359,19 +358,9 @@
       src->start_cell, src->last_cell);
 
   /* retrieve position */
-  src->cur_pack = 0;
-  for (i = 0; i < chapter; i++) {
-    gint c1, c2;
-
-    cur_title_get_chapter_bounds (src, i, &c1, &c2);
-
-    while (c1 < c2) {
-      src->cur_pack +=
-          src->cur_pgc->cell_playback[c1].last_sector -
-          src->cur_pgc->cell_playback[c1].first_sector;
-      ++c1;
-    }
-  }
+  gint c1, c2;
+  cur_title_get_chapter_bounds (src, chapter, &c1, &c2);
+  src->cur_pack = src->cur_pgc->cell_playback[c1].first_sector;
 
   /* prepare reading for new cell */
   src->new_cell = TRUE;
@@ -549,31 +538,20 @@
   src->title_lang_event_pending =
       gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
 
-  /* dump seek tables */
-  src->vts_tmapt = src->vts_file->vts_tmapt;
-  if (src->vts_tmapt) {
-    gint i, j;
-
-    GST_LOG_OBJECT (src, "nr_of_tmaps = %d", src->vts_tmapt->nr_of_tmaps);
-    for (i = 0; i < src->vts_tmapt->nr_of_tmaps; ++i) {
-      GST_LOG_OBJECT (src, "======= Table %d ===================", i);
-      GST_LOG_OBJECT (src, "Offset relative to VTS_TMAPTI: %d",
-          src->vts_tmapt->tmap_offset[i]);
-      GST_LOG_OBJECT (src, "Time unit (seconds)          : %d",
-          src->vts_tmapt->tmap[i].tmu);
-      GST_LOG_OBJECT (src, "Number of entries            : %d",
-          src->vts_tmapt->tmap[i].nr_of_entries);
-      for (j = 0; j < src->vts_tmapt->tmap[i].nr_of_entries; j++) {
-        guint64 time;
-
-        time = src->vts_tmapt->tmap[i].tmu * (j + 1) * GST_SECOND;
-        GST_LOG_OBJECT (src, "Time: %" GST_TIME_FORMAT " VOBU "
-            "Sector: 0x%08x %s", GST_TIME_ARGS (time),
-            src->vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff,
-            (src->vts_tmapt->tmap[i].map_ent[j] >> 31) ? "discontinuity" : "");
-      }
+  
+  /* If the current title_set has a vts_tmapt, it will have one tmap per
+  title, but we are only interested in the tmap for this title. */
+  if (src->vts_file->vts_tmapt != NULL)
+  {
+    gint i;
+    i = src->ttn - 1;       
+    if (i >= 0 && i < src->vts_file->vts_tmapt->nr_of_tmaps)
+    {
+      src->tmap = & src->vts_file->vts_tmapt->tmap[i];
     }
-  } else {
+  }
+  else 
+  {
     GST_WARNING_OBJECT (src, "no vts_tmapt - seeking will suck");
   }
 
@@ -657,55 +635,55 @@
 /* find time for sector from index, returns NONE if there is no exact match */
 static GstClockTime
 gst_dvd_read_src_get_time_for_sector (GstDvdReadSrc * src, guint sector)
-{
-  gint i, j;
+{  
+  gint i;
 
-  if (src->vts_tmapt == NULL || src->vts_tmapt->nr_of_tmaps == 0)
+  if (src->tmap == NULL) 
     return GST_CLOCK_TIME_NONE;
-
-  for (i = 0; i < src->vts_tmapt->nr_of_tmaps; ++i) {
-    for (j = 0; j < src->vts_tmapt->tmap[i].nr_of_entries; ++j) {
-      if ((src->vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff) == sector)
-        return src->vts_tmapt->tmap[i].tmu * (j + 1) * GST_SECOND;
+    
+  for (i = 0; i < src->tmap->nr_of_entries; i++)
+  {
+    if ((src->tmap->map_ent[i] & 0x7fffffff) == sector)
+    {
+      return src->tmap->tmu * (i + 1) * GST_SECOND;
     }
   }
-
-  if (sector == 0)
-    return (GstClockTime) 0;
-
   return GST_CLOCK_TIME_NONE;
 }
 
-/* returns the sector in the index at (or before) the given time, or -1 */
+
+/* Returns sector for time <= ts, or -1 if src->tmap == NULL */
 static gint
 gst_dvd_read_src_get_sector_from_time (GstDvdReadSrc * src, GstClockTime ts)
 {
-  gint sector, i, j;
+  gint i;
 
-  if (src->vts_tmapt == NULL || src->vts_tmapt->nr_of_tmaps == 0)
+  if (src->tmap == NULL) 
+  {
+    GST_WARNING_OBJECT (src, 
+      "Trying to get sector from time, but src->tmap == NULL");
     return -1;
-
-  sector = 0;
-  for (i = 0; i < src->vts_tmapt->nr_of_tmaps; ++i) {
-    for (j = 0; j < src->vts_tmapt->tmap[i].nr_of_entries; ++j) {
-      GstClockTime entry_time;
-
-      entry_time = src->vts_tmapt->tmap[i].tmu * (j + 1) * GST_SECOND;
-      if (entry_time <= ts) {
-        sector = src->vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff;
-      }
-      if (entry_time >= ts) {
-        return sector;
-      }
-    }
+  }
+    
+  i = ts / GST_SECOND / src->tmap->tmu - 1;
+  
+  if (i < 0)
+  {
+    /* FIXME: we should actually return the start sector for the title,
+    which is not in src->tmap->map_ent[] */
+    i = 0;
+  }
+  else if (i >= src->tmap->nr_of_entries)
+  {
+    GST_WARNING_OBJECT (src, 
+      "Probably trying to seek beyond end of title");
+    i = src->tmap->nr_of_entries - 1;
   }
 
-  if (ts == 0)
-    return 0;
-
-  return -1;
+  return src->tmap->map_ent[i] & 0x7fffffff; // Some high bits aren't used.
 }
 
+
 typedef enum
 {
   GST_DVD_READ_OK = 0,
@@ -1007,6 +985,9 @@
   GST_OBJECT_UNLOCK (src);
 }
 
+
+/* Because there can be more than one title in the title_set, this doesn't
+   always return something meaningful. */
 static gboolean
 gst_dvd_read_src_get_size (GstDvdReadSrc * src, gint64 * size)
 {
@@ -1501,59 +1482,63 @@
   return res;
 }
 
+/* sector is absolute (i.e., relative to title_set, not title) */
 static gboolean
 gst_dvd_read_src_goto_sector (GstDvdReadSrc * src, int angle)
-{
+{ 
   gint seek_to = src->cur_pack;
-  gint chapter, sectors, next, cur, i;
+  gint chap, cell;
 
-  /* retrieve position */
-  src->cur_pack = 0;
-  for (i = 0; i < src->num_chapters; i++) {
+  /* find chapter and cell containing sector src->cur_pack */
+  for (chap = 0; chap < src->num_chapters; chap++)
+  {
     gint c1, c2;
+    cur_title_get_chapter_bounds (src, chap, &c1, &c2);
 
-    cur_title_get_chapter_bounds (src, i, &c1, &c2);
-
-    for (next = cur = c1; cur < c2;) {
-      if (next != cur) {
-        sectors =
-            src->cur_pgc->cell_playback[cur].last_sector -
-            src->cur_pgc->cell_playback[cur].first_sector;
-        if (src->cur_pack + sectors > seek_to) {
-          chapter = i;
+    for (cell = c1; cell < c2;) {
+      if (seek_to < src->cur_pgc->cell_playback[cell].first_sector)
+      {
+        /* HACK: Some initial seek to FORMAT_BYTES 0 is being called, maybe
+        from GstBaseSrc, which is breaking things for a title_set with more
+        than one title.  As an aside, querying and seeking by sector (or
+        bytes, which are converted to sectors) is totally broken because of
+        further title starts at sector 0 assumptions throughout the code */
+        seek_to = src->cur_pgc->cell_playback[cell].first_sector;
+        goto done;
+      }
+      if (src->cur_pgc->cell_playback[cell].first_sector <= src->cur_pack &&
+          src->cur_pgc->cell_playback[cell].last_sector >= src->cur_pack)
+      {
+          /* seek_to is in the sector interval for this chap and cell */
           goto done;
-        }
-        src->cur_pack += sectors;
       }
-      cur = next;
-      if (src->cur_pgc->cell_playback[cur].block_type == BLOCK_TYPE_ANGLE_BLOCK)
-        cur += angle;
-      next = gst_dvd_read_src_get_next_cell (src, src->cur_pgc, cur);
+      
+      if (src->cur_pgc->cell_playback[cell].block_type == BLOCK_TYPE_ANGLE_BLOCK)
+        cell += angle;
+        
+      cell = gst_dvd_read_src_get_next_cell (src, src->cur_pgc, cell);
     }
   }
 
-  GST_DEBUG_OBJECT (src, "Seek to sector %u failed", seek_to);
+  GST_WARNING_OBJECT (src, "Seek to sector %u failed", seek_to);
 
   return FALSE;
 
 done:
   {
-    /* so chapter $chapter and cell $cur contain our sector
-     * of interest. Let's go there! */
     GST_INFO_OBJECT (src, "Seek succeeded, going to chapter %u, cell %u",
-        chapter + 1, cur);
-
-    gst_dvd_read_src_goto_chapter (src, chapter);
-    src->cur_cell = cur;
-    src->next_cell = next;
+        chap + 1, cell);
+    gst_dvd_read_src_goto_chapter (src, chap);
+    src->cur_cell = cell;
+    src->next_cell = gst_dvd_read_src_get_next_cell (src, src->cur_pgc, cell);
     src->new_cell = FALSE;
     src->cur_pack = seek_to;
-
     return TRUE;
   }
 }
 
 
+
 /*** URI interface ***/
 
 static GstURIType
Index: ext/dvdread/dvdreadsrc.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-ugly/ext/dvdread/dvdreadsrc.h,v
retrieving revision 1.11
diff -u -r1.11 dvdreadsrc.h
--- ext/dvdread/dvdreadsrc.h	6 Aug 2006 19:47:40 -0000	1.11
+++ ext/dvdread/dvdreadsrc.h	13 Nov 2006 03:01:51 -0000
@@ -73,7 +73,7 @@
   tt_srpt_t       *tt_srpt;
   ifo_handle_t    *vts_file;
   vts_ptt_srpt_t  *vts_ptt_srpt;
-  vts_tmapt_t     *vts_tmapt;
+  vts_tmap_t      *tmap;
   dvd_file_t      *dvd_title;
   gint             num_chapters;
   gint             num_angles;
