Commit 3e74c740 authored by Erik Hovland's avatar Erik Hovland

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.
parent a9457969
...@@ -289,6 +289,8 @@ static void free_ptl_mait(ptl_mait_t* ptl_mait, int num_entries) { ...@@ -289,6 +289,8 @@ static void free_ptl_mait(ptl_mait_t* ptl_mait, int num_entries) {
ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) { ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
ifo_handle_t *ifofile; ifo_handle_t *ifofile;
int bup_file_opened = 0;
char ifo_filename[13];
ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t)); ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t));
if(!ifofile) if(!ifofile)
...@@ -297,14 +299,20 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) { ...@@ -297,14 +299,20 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
memset(ifofile, 0, sizeof(ifo_handle_t)); memset(ifofile, 0, sizeof(ifo_handle_t));
ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE); 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); 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(!ifofile->file) {
if(title) { fprintf(stderr, "libdvdread: Can't open file %s.\n", ifo_filename);
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");
}
free(ifofile); free(ifofile);
return NULL; return NULL;
} }
...@@ -313,21 +321,15 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) { ...@@ -313,21 +321,15 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
if(ifoRead_VMG(ifofile)) { if(ifoRead_VMG(ifofile)) {
/* These are both mandatory. */ /* These are both mandatory. */
if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) { if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile))
fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO), ifoRead_FP_PGC() failed.\n"); goto ifoOpen_try_bup;
ifoClose(ifofile);
return NULL;
}
ifoRead_PGCI_UT(ifofile); ifoRead_PGCI_UT(ifofile);
ifoRead_PTL_MAIT(ifofile); ifoRead_PTL_MAIT(ifofile);
/* This is also mandatory. */ /* This is also mandatory. */
if(!ifoRead_VTS_ATRT(ifofile)) { if(!ifoRead_VTS_ATRT(ifofile))
fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO), ifoRead_VTS_ATRT() failed.\n"); goto ifoOpen_try_bup;
ifoClose(ifofile);
return NULL;
}
ifoRead_TXTDT_MGI(ifofile); ifoRead_TXTDT_MGI(ifofile);
ifoRead_C_ADT(ifofile); ifoRead_C_ADT(ifofile);
...@@ -338,34 +340,85 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) { ...@@ -338,34 +340,85 @@ ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
if(ifoRead_VTS(ifofile)) { if(ifoRead_VTS(ifofile)) {
if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile)) { if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile))
fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n", goto ifoOpen_try_bup;
title);
ifoClose(ifofile);
return NULL;
}
ifoRead_PGCI_UT(ifofile); ifoRead_PGCI_UT(ifofile);
ifoRead_VTS_TMAPT(ifofile); ifoRead_VTS_TMAPT(ifofile);
ifoRead_C_ADT(ifofile); ifoRead_C_ADT(ifofile);
ifoRead_VOBU_ADMAP(ifofile); ifoRead_VOBU_ADMAP(ifofile);
if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_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", goto ifoOpen_try_bup;
title);
ifoClose(ifofile);
return NULL;
}
return ifofile; return ifofile;
} }
if(title) { ifoOpen_try_bup:
fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.IFO).\n", if (bup_file_opened)
title, title); goto ifoOpen_fail;
} else {
fprintf(stderr, "libdvdread: Invalid IFO for VMGM (VIDEO_TS.IFO).\n"); /* 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); ifoClose(ifofile);
return NULL; return NULL;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment