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