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

Micah Richert micah at salk.edu
Sun Jan 28 04:10:23 EET 2018


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
-------------- next part --------------
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:


More information about the MPlayer-dev-eng mailing list