[PATCH] Read scratched DVDs, warn for corrupt titles and report number of cells in title

Micah Richert <[email protected]>
Newsgroups gmane.comp.video.mplayer.devel
Message-ID <[email protected]>
This patch does 3 things:
Continues to next cell when DVD sector read fails instead of the current 
behavior of failing/signaling EOF.  This is useful for playing scratched 
DVDs.
Reports the total number of cells in a DVD title.  This is useful for 
finding the longest title when title duration information is inaccurate.
Warns when packs are out of order in the current title.  This is useful 
for finding titles that are corrupt/invalid.

If desired, I can separate this patch into two, one for the sector read 
failure handling and the second to report cell count and pack order.

Thank you,
Micah Richert

_______________________________________________
MPlayer-dev-eng mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
count_cells.patch (text/plain, 2.5 KB)
Index: stream/stream_dvd.c
===================================================================
--- stream/stream_dvd.c	(revision 38017)
+++ stream/stream_dvd.c	(working copy)
@@ -382,9 +382,29 @@
   int64_t pos;
   if (len < 2048)
     return -1;
-  pos = dvd_read_sector(s->priv, buf);
-  if (pos < 0)
+
+  // if the current position exists the end of file
+  // then return eof
+  if (s->pos > s->end_pos)
     return -1;
+
+  while ((pos = dvd_read_sector(s->priv, buf)) <= 0)
+  {
+    // if reading dvd sector fails then jump to next cell
+    // in order to be able to handle bad sectors
+    dvd_priv_t *d = s->priv;
+    int next=dvd_next_cell(d);
+    if(next>=0) {
+      d->cur_cell=next;
+      d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector;
+      d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector;
+      mp_msg(MSGT_DVD,MSGL_WARN,"Unable to read cell: %d  pack: 0x%X-0x%X, jumping to next cell.\n",d->cur_cell,d->cur_pack,d->cell_last_pack);
+    } else {
+      // if no more cells then signal error/eof
+      return -1;
+    }
+  }
+
   s->pos = 2048*(pos - 1);
   return 2048; // full sector
 }
@@ -543,6 +563,35 @@
     mp_msg(MSGT_IDENTIFY, MSGL_INFO, "\n");
 }
 
+static void count_cells(dvd_priv_t *d)
+{
+  // Counts number of cells in current title
+  // Also validates pack order
+
+  int next;
+  int start_cur_cell = d->cur_cell;
+  int total_cells = d->cell_last_pack - d->cur_cell + 1;
+
+  while((next=dvd_next_cell(d))>=0)
+  {
+    int next_pack;
+    d->cur_cell=next;
+    next_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector;
+    if (d->cur_pack > next_pack)
+    {
+      mp_msg(MSGT_DVD,MSGL_WARN,"Packs out of order! Current pack: 0x%X next pack: 0x%X. Likely corrupt title.\n",d->cur_pack, next_pack);
+    }
+    d->cur_pack = next_pack;
+    d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector;
+total_cells += d->cell_last_pack - d->cur_cell + 1;
+  }
+  mp_msg(MSGT_IDENTIFY, MSGL_INFO, "Total cells: %d\n", total_cells);
+
+  d->cur_cell = start_cur_cell;
+  d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector;
+  d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector;
+}
+
 static double dvd_get_current_time(stream_t *stream, int cell)
 {
     int i, tm;
@@ -1031,6 +1080,9 @@
     *file_format = DEMUXER_TYPE_MPEG_PS;
     mp_msg(MSGT_DVD,MSGL_V,"DVD start=%d end=%d  \n",d->cur_pack,d->cur_pgc->cell_playback[d->last_cell-1].last_sector);
     stream->priv = (void*)d;
+
+    count_cells(d);
+
     return STREAM_OK;
 
 fail:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.