2016-07-31 08:19:31 +02:00
|
|
|
# HG changeset patch
|
|
|
|
# User Tobias Rautenkranz <mail@tobias.rautenkranz.ch>
|
|
|
|
# Date 1202208482 -3600
|
|
|
|
# Node ID 100241ff36f0730a15018a58456fb86eb590bf18
|
|
|
|
# Parent 07c29261ed98fdb710a241c6711dac0215b6074a
|
|
|
|
Fix playback of DVDs with a broken UDF file system (aka DVD-Movie-Protect).
|
|
|
|
|
2017-04-09 17:04:53 +02:00
|
|
|
Index: src/input/libdvdnav/dvd_udf.c
|
|
|
|
===================================================================
|
|
|
|
--- src/input/libdvdnav/dvd_udf.c.orig 2017-02-21 13:13:13.000000000 +0200
|
|
|
|
+++ src/input/libdvdnav/dvd_udf.c 2017-04-09 12:18:04.684166526 +0200
|
|
|
|
@@ -38,10 +38,16 @@
|
2016-07-31 08:19:31 +02:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
+#ifndef __WIN32__
|
|
|
|
+#include <fnmatch.h>
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
#include "dvd_reader.h"
|
|
|
|
#include "dvd_udf.h"
|
2017-04-09 17:04:53 +02:00
|
|
|
|
2016-07-31 08:19:31 +02:00
|
|
|
+#include "ifo_types.h"
|
|
|
|
+#include "ifo_read.h"
|
2017-04-09 17:04:53 +02:00
|
|
|
+
|
2016-07-31 08:19:31 +02:00
|
|
|
/* Private but located in/shared with dvd_reader.c */
|
|
|
|
extern int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
|
2017-04-09 17:04:53 +02:00
|
|
|
size_t block_count, unsigned char *data,
|
|
|
|
@@ -779,7 +785,9 @@ static int UDFFindPartition( dvd_reader_
|
2016-07-31 08:19:31 +02:00
|
|
|
return part->valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
-uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static uint32_t UDFFindFileReal( dvd_reader_t *device, char *filename,
|
|
|
|
uint32_t *filesize )
|
|
|
|
{
|
|
|
|
uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ];
|
2017-04-09 17:04:53 +02:00
|
|
|
@@ -861,6 +869,84 @@ uint32_t UDFFindFile( dvd_reader_t *devi
|
2016-07-31 08:19:31 +02:00
|
|
|
return partition.Start + File.Location;
|
|
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Get the offset from the ifo files to allow playback of DVDs
|
|
|
|
+ * with a deliberately broken UDF file system (aka DVD-Movie-Protect).
|
|
|
|
+ * When the file is not an IFO or VOB, it calls the real UDF routine.
|
|
|
|
+ */
|
|
|
|
+uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
|
|
|
|
+ uint32_t *filesize )
|
|
|
|
+{
|
|
|
|
+#ifndef __WIN32__
|
|
|
|
+ if (!fnmatch("/VIDEO_TS/VTS_[0-9][0-9]_[0-9].???", filename, FNM_PATHNAME)) {
|
|
|
|
+#else
|
|
|
|
+ if (strlen("/VIDEO_TS/VTS_01_1.VOB") == strlen(filename)
|
|
|
|
+ && !strncmp(filename, "/VIDEO_TS/VTS_", strlen("/VIDEO_TS/VTS_")) ) {
|
|
|
|
+#endif
|
|
|
|
+ size_t len = strlen(filename);
|
|
|
|
+ char *extension = &filename[len-3];
|
|
|
|
+ if (!strcmp(extension, "IFO") || !strcmp(extension, "VOB")) {
|
|
|
|
+ int title = atoi(&filename[len-8]);
|
|
|
|
+ int part = atoi(&filename[len-5]);
|
|
|
|
+
|
|
|
|
+ ifo_handle_t *ifo_handle = ifoOpen(device, 0);
|
|
|
|
+ if (0 == ifo_handle)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ uint32_t tmp_filesize;
|
|
|
|
+ uint32_t offset = UDFFindFileReal(device, "/VIDEO_TS/VIDEO_TS.IFO", &tmp_filesize);
|
|
|
|
+
|
|
|
|
+ int i;
|
|
|
|
+ for (i=0; i<ifo_handle->tt_srpt->nr_of_srpts; i++)
|
|
|
|
+ if (title == ifo_handle->tt_srpt->title[i].title_set_nr)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ if (i == ifo_handle->tt_srpt->nr_of_srpts) {
|
|
|
|
+ /* not found */
|
|
|
|
+ ifoClose(ifo_handle);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ offset += ifo_handle->tt_srpt->title[i].title_set_sector;
|
|
|
|
+ ifoClose(ifo_handle);
|
|
|
|
+
|
|
|
|
+ if (!strcmp(extension, "VOB")) {
|
|
|
|
+ ifo_handle = ifoOpen(device, title);
|
|
|
|
+ if (0 == ifo_handle)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ switch(part) {
|
|
|
|
+ case 0:
|
|
|
|
+ if (0 == ifo_handle->vtsi_mat->vtsm_vobs) {
|
|
|
|
+ ifoClose(ifo_handle);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ offset += ifo_handle->vtsi_mat->vtsm_vobs;
|
|
|
|
+ break;
|
|
|
|
+ case 1:
|
|
|
|
+ if (0 == ifo_handle->vtsi_mat->vtstt_vobs) {
|
|
|
|
+ ifoClose(ifo_handle);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ offset += ifo_handle->vtsi_mat->vtstt_vobs;
|
|
|
|
+ break;
|
|
|
|
+ default: /* can't get other parts (also no need to) */
|
|
|
|
+ offset = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ifoClose(ifo_handle);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ *filesize = 1000000; /* File size unknown */
|
|
|
|
+ if (offset != 0)
|
|
|
|
+ return offset;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return UDFFindFileReal( device, filename, filesize);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
/**
|