[DVDnav-discuss] r1215 - trunk/libdvdread/src/ifo_read.c

erik subversion at mplayerhq.hu
Sat Jul 31 02:21:02 CEST 2010


Author: erik
Date: Sat Jul 31 02:21:01 2010
New Revision: 1215

Log:
Provide BUP file support for more issues.

The BUP file is only opened when the IFO file open fails. We have a
few times where file corruption could happen and we could use the
BUP instead. This patch attempts to address this by trying to
open the BUP if there is any reported error w/ the IFO. Inspiration
for this patch came from Rich E, thanks for the detailed bug
report and attempts at using earlier patches.

Modified:
   trunk/libdvdread/src/ifo_read.c

Modified: trunk/libdvdread/src/ifo_read.c
==============================================================================
--- trunk/libdvdread/src/ifo_read.c	Sat Jul 31 02:10:33 2010	(r1214)
+++ trunk/libdvdread/src/ifo_read.c	Sat Jul 31 02:21:01 2010	(r1215)
@@ -289,6 +289,8 @@ static void free_ptl_mait(ptl_mait_t* pt
 
 ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
   ifo_handle_t *ifofile;
+  int bup_file_opened = 0;
+  char ifo_filename[13];
 
   ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
   if(!ifofile)
@@ -297,14 +299,20 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd,
   memset(ifofile, 0, sizeof(ifo_handle_t));
 
   ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
-  if(!ifofile->file) /* Should really catch any error and try to fallback */
+  if(!ifofile->file) { /* Failed to open IFO, try to open BUP */
     ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
+    bup_file_opened = 1;
+  }
+
+  if (title)
+    snprintf(ifo_filename, 12, "VTS_%02d_0.%s", title, bup_file_opened ? "BUP" : "IFO");
+  else
+    snprintf(ifo_filename, 12, "VIDEO_TS.%s", bup_file_opened ? "BUP" : "IFO");
+
+  ifo_filename[12] = '\0';
+
   if(!ifofile->file) {
-    if(title) {
-      fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title);
-    } else {
-      fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n");
-    }
+    fprintf(stderr, "libdvdread: Can't open file %s.\n", ifo_filename);
     free(ifofile);
     return NULL;
   }
@@ -313,21 +321,15 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd,
   if(ifoRead_VMG(ifofile)) {
 
     /* These are both mandatory. */
-    if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) {
-      fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO), ifoRead_FP_PGC() failed.\n");
-      ifoClose(ifofile);
-      return NULL;
-    }
+    if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile))
+      goto ifoOpen_try_bup;
 
     ifoRead_PGCI_UT(ifofile);
     ifoRead_PTL_MAIT(ifofile);
 
     /* This is also mandatory. */
-    if(!ifoRead_VTS_ATRT(ifofile)) {
-      fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO), ifoRead_VTS_ATRT() failed.\n");
-      ifoClose(ifofile);
-      return NULL;
-    }
+    if(!ifoRead_VTS_ATRT(ifofile))
+      goto ifoOpen_try_bup;
 
     ifoRead_TXTDT_MGI(ifofile);
     ifoRead_C_ADT(ifofile);
@@ -338,34 +340,85 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd,
 
   if(ifoRead_VTS(ifofile)) {
 
-    if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile)) {
-      fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n",
-              title);
-      ifoClose(ifofile);
-      return NULL;
-    }
+    if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile))
+      goto ifoOpen_try_bup;
 
     ifoRead_PGCI_UT(ifofile);
     ifoRead_VTS_TMAPT(ifofile);
     ifoRead_C_ADT(ifofile);
     ifoRead_VOBU_ADMAP(ifofile);
 
-    if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile)) {
-      fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n",
-              title);
-      ifoClose(ifofile);
-      return NULL;
-    }
+    if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile))
+      goto ifoOpen_try_bup;
 
     return ifofile;
   }
 
-  if(title) {
-    fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.IFO).\n",
-            title, title);
-  } else {
-    fprintf(stderr, "libdvdread: Invalid IFO for VMGM (VIDEO_TS.IFO).\n");
+ifoOpen_try_bup:
+  if (bup_file_opened)
+    goto ifoOpen_fail;
+
+  /* Try BUP instead */
+  ifoClose(ifofile);
+
+  ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
+  if(!ifofile)
+    return NULL;
+
+  memset(ifofile, 0, sizeof(ifo_handle_t));
+  ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
+
+  if (title)
+    snprintf(ifo_filename, 12, "VTS_%02d_0.BUP", title);
+  else
+    strncpy(ifo_filename, "VIDEO_TS.BUP", 12);
+
+  if (!ifofile->file) {
+    fprintf(stderr, "libdvdread: Can't open file %s.\n", ifo_filename);
+    free(ifofile);
+    return NULL;
   }
+  bup_file_opened = 1;
+
+  /* First check if this is a VMGI file. */
+  if(ifoRead_VMG(ifofile)) {
+
+    /* These are both mandatory. */
+    if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile))
+      goto ifoOpen_fail;
+
+    ifoRead_PGCI_UT(ifofile);
+    ifoRead_PTL_MAIT(ifofile);
+
+    /* This is also mandatory. */
+    if(!ifoRead_VTS_ATRT(ifofile))
+      goto ifoOpen_fail;
+
+    ifoRead_TXTDT_MGI(ifofile);
+    ifoRead_C_ADT(ifofile);
+    ifoRead_VOBU_ADMAP(ifofile);
+
+    return ifofile;
+  }
+
+  if(ifoRead_VTS(ifofile)) {
+
+    if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile))
+      goto ifoOpen_fail;
+
+    ifoRead_PGCI_UT(ifofile);
+    ifoRead_VTS_TMAPT(ifofile);
+    ifoRead_C_ADT(ifofile);
+    ifoRead_VOBU_ADMAP(ifofile);
+
+    if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile))
+      goto ifoOpen_fail;
+
+    return ifofile;
+  }
+
+ifoOpen_fail:
+  fprintf(stderr, "libdvdread: Invalid IFO for title %d (%s).\n", title, ifo_filename);
   ifoClose(ifofile);
   return NULL;
 }


More information about the DVDnav-discuss mailing list