Web lists-archives.com

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




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
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:
_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng@xxxxxxxxxxxx
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng