Mercurial > libdvdread4.hg
comparison ifo_read.c @ 59:bfefcc426154 src
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.
author | erik |
---|---|
date | Sat, 31 Jul 2010 00:21:01 +0000 |
parents | 562a4f76fb53 |
children | eac01aeb7be5 |
comparison
equal
deleted
inserted
replaced
58:562a4f76fb53 | 59:bfefcc426154 |
---|---|
287 free(ptl_mait); | 287 free(ptl_mait); |
288 } | 288 } |
289 | 289 |
290 ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) { | 290 ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) { |
291 ifo_handle_t *ifofile; | 291 ifo_handle_t *ifofile; |
292 int bup_file_opened = 0; | |
293 char ifo_filename[13]; | |
292 | 294 |
293 ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t)); | 295 ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t)); |
294 if(!ifofile) | 296 if(!ifofile) |
295 return NULL; | 297 return NULL; |
296 | 298 |
297 memset(ifofile, 0, sizeof(ifo_handle_t)); | 299 memset(ifofile, 0, sizeof(ifo_handle_t)); |
298 | 300 |
299 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE); | 301 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE); |
300 if(!ifofile->file) /* Should really catch any error and try to fallback */ | 302 if(!ifofile->file) { /* Failed to open IFO, try to open BUP */ |
301 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE); | 303 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE); |
304 bup_file_opened = 1; | |
305 } | |
306 | |
307 if (title) | |
308 snprintf(ifo_filename, 12, "VTS_%02d_0.%s", title, bup_file_opened ? "BUP" : "IFO"); | |
309 else | |
310 snprintf(ifo_filename, 12, "VIDEO_TS.%s", bup_file_opened ? "BUP" : "IFO"); | |
311 | |
312 ifo_filename[12] = '\0'; | |
313 | |
302 if(!ifofile->file) { | 314 if(!ifofile->file) { |
303 if(title) { | 315 fprintf(stderr, "libdvdread: Can't open file %s.\n", ifo_filename); |
304 fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title); | |
305 } else { | |
306 fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n"); | |
307 } | |
308 free(ifofile); | 316 free(ifofile); |
309 return NULL; | 317 return NULL; |
310 } | 318 } |
311 | 319 |
312 /* First check if this is a VMGI file. */ | 320 /* First check if this is a VMGI file. */ |
313 if(ifoRead_VMG(ifofile)) { | 321 if(ifoRead_VMG(ifofile)) { |
314 | 322 |
315 /* These are both mandatory. */ | 323 /* These are both mandatory. */ |
316 if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) { | 324 if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) |
317 fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO), ifoRead_FP_PGC() failed.\n"); | 325 goto ifoOpen_try_bup; |
318 ifoClose(ifofile); | |
319 return NULL; | |
320 } | |
321 | 326 |
322 ifoRead_PGCI_UT(ifofile); | 327 ifoRead_PGCI_UT(ifofile); |
323 ifoRead_PTL_MAIT(ifofile); | 328 ifoRead_PTL_MAIT(ifofile); |
324 | 329 |
325 /* This is also mandatory. */ | 330 /* This is also mandatory. */ |
326 if(!ifoRead_VTS_ATRT(ifofile)) { | 331 if(!ifoRead_VTS_ATRT(ifofile)) |
327 fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO), ifoRead_VTS_ATRT() failed.\n"); | 332 goto ifoOpen_try_bup; |
328 ifoClose(ifofile); | |
329 return NULL; | |
330 } | |
331 | 333 |
332 ifoRead_TXTDT_MGI(ifofile); | 334 ifoRead_TXTDT_MGI(ifofile); |
333 ifoRead_C_ADT(ifofile); | 335 ifoRead_C_ADT(ifofile); |
334 ifoRead_VOBU_ADMAP(ifofile); | 336 ifoRead_VOBU_ADMAP(ifofile); |
335 | 337 |
336 return ifofile; | 338 return ifofile; |
337 } | 339 } |
338 | 340 |
339 if(ifoRead_VTS(ifofile)) { | 341 if(ifoRead_VTS(ifofile)) { |
340 | 342 |
341 if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile)) { | 343 if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile)) |
342 fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n", | 344 goto ifoOpen_try_bup; |
343 title); | |
344 ifoClose(ifofile); | |
345 return NULL; | |
346 } | |
347 | 345 |
348 ifoRead_PGCI_UT(ifofile); | 346 ifoRead_PGCI_UT(ifofile); |
349 ifoRead_VTS_TMAPT(ifofile); | 347 ifoRead_VTS_TMAPT(ifofile); |
350 ifoRead_C_ADT(ifofile); | 348 ifoRead_C_ADT(ifofile); |
351 ifoRead_VOBU_ADMAP(ifofile); | 349 ifoRead_VOBU_ADMAP(ifofile); |
352 | 350 |
353 if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile)) { | 351 if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile)) |
354 fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n", | 352 goto ifoOpen_try_bup; |
355 title); | |
356 ifoClose(ifofile); | |
357 return NULL; | |
358 } | |
359 | 353 |
360 return ifofile; | 354 return ifofile; |
361 } | 355 } |
362 | 356 |
363 if(title) { | 357 ifoOpen_try_bup: |
364 fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.IFO).\n", | 358 if (bup_file_opened) |
365 title, title); | 359 goto ifoOpen_fail; |
366 } else { | 360 |
367 fprintf(stderr, "libdvdread: Invalid IFO for VMGM (VIDEO_TS.IFO).\n"); | 361 /* Try BUP instead */ |
368 } | 362 ifoClose(ifofile); |
363 | |
364 ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t)); | |
365 if(!ifofile) | |
366 return NULL; | |
367 | |
368 memset(ifofile, 0, sizeof(ifo_handle_t)); | |
369 ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE); | |
370 | |
371 if (title) | |
372 snprintf(ifo_filename, 12, "VTS_%02d_0.BUP", title); | |
373 else | |
374 strncpy(ifo_filename, "VIDEO_TS.BUP", 12); | |
375 | |
376 if (!ifofile->file) { | |
377 fprintf(stderr, "libdvdread: Can't open file %s.\n", ifo_filename); | |
378 free(ifofile); | |
379 return NULL; | |
380 } | |
381 bup_file_opened = 1; | |
382 | |
383 /* First check if this is a VMGI file. */ | |
384 if(ifoRead_VMG(ifofile)) { | |
385 | |
386 /* These are both mandatory. */ | |
387 if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) | |
388 goto ifoOpen_fail; | |
389 | |
390 ifoRead_PGCI_UT(ifofile); | |
391 ifoRead_PTL_MAIT(ifofile); | |
392 | |
393 /* This is also mandatory. */ | |
394 if(!ifoRead_VTS_ATRT(ifofile)) | |
395 goto ifoOpen_fail; | |
396 | |
397 ifoRead_TXTDT_MGI(ifofile); | |
398 ifoRead_C_ADT(ifofile); | |
399 ifoRead_VOBU_ADMAP(ifofile); | |
400 | |
401 return ifofile; | |
402 } | |
403 | |
404 if(ifoRead_VTS(ifofile)) { | |
405 | |
406 if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile)) | |
407 goto ifoOpen_fail; | |
408 | |
409 ifoRead_PGCI_UT(ifofile); | |
410 ifoRead_VTS_TMAPT(ifofile); | |
411 ifoRead_C_ADT(ifofile); | |
412 ifoRead_VOBU_ADMAP(ifofile); | |
413 | |
414 if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile)) | |
415 goto ifoOpen_fail; | |
416 | |
417 return ifofile; | |
418 } | |
419 | |
420 ifoOpen_fail: | |
421 fprintf(stderr, "libdvdread: Invalid IFO for title %d (%s).\n", title, ifo_filename); | |
369 ifoClose(ifofile); | 422 ifoClose(ifofile); |
370 return NULL; | 423 return NULL; |
371 } | 424 } |
372 | 425 |
373 | 426 |