mirror of https://github.com/mpv-player/mpv
patch by Joey Parrish <joey@nicewarrior.org>:
- updated from libdvdread 0.9.4 and removed udf caching (fixes mpdvdkit on cygwin) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10724 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
51843b59f7
commit
948c6be0b1
|
@ -4,6 +4,9 @@
|
||||||
*
|
*
|
||||||
* Modifications by:
|
* Modifications by:
|
||||||
* Billy Biggs <vektor@dumbterm.net>.
|
* Billy Biggs <vektor@dumbterm.net>.
|
||||||
|
* Björn Englund <d4bjorn@dtek.chalmers.se>.
|
||||||
|
* Joey Parrish <joey@nicewarrior.org>.
|
||||||
|
* - updated from libdvdread 0.9.4 and removed udf caching
|
||||||
*
|
*
|
||||||
* dvdudf: parse and read the UDF volume information of a DVD Video
|
* dvdudf: parse and read the UDF volume information of a DVD Video
|
||||||
* Copyright (C) 1999 Christian Wolff for convergence integrated media
|
* Copyright (C) 1999 Christian Wolff for convergence integrated media
|
||||||
|
@ -95,6 +98,32 @@ struct AD {
|
||||||
uint16_t Partition;
|
uint16_t Partition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct extent_ad {
|
||||||
|
uint32_t location;
|
||||||
|
uint32_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct avdp_t {
|
||||||
|
struct extent_ad mvds;
|
||||||
|
struct extent_ad rvds;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pvd_t {
|
||||||
|
uint8_t VolumeIdentifier[32];
|
||||||
|
uint8_t VolumeSetIdentifier[128];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lbudf {
|
||||||
|
uint32_t lb;
|
||||||
|
uint8_t *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct icbmap {
|
||||||
|
uint32_t lbn;
|
||||||
|
struct AD file;
|
||||||
|
uint8_t filetype;
|
||||||
|
};
|
||||||
|
|
||||||
/* For direct data access, LSB first */
|
/* For direct data access, LSB first */
|
||||||
#define GETN1(p) ((uint8_t)data[p])
|
#define GETN1(p) ((uint8_t)data[p])
|
||||||
#define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8))
|
#define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8))
|
||||||
|
@ -336,19 +365,16 @@ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks for partition on the disc. Returns 1 if partition found, 0 on error.
|
static int UDFGetAVDP( dvd_reader_t *device,
|
||||||
* partnum: Number of the partition, starting at 0.
|
struct avdp_t *avdp)
|
||||||
* part: structure to fill with the partition information
|
|
||||||
*/
|
|
||||||
static int UDFFindPartition( dvd_reader_t *device, int partnum,
|
|
||||||
struct Partition *part )
|
|
||||||
{
|
{
|
||||||
uint8_t LogBlock[ DVD_VIDEO_LB_LEN ], Anchor[ DVD_VIDEO_LB_LEN ];
|
uint8_t Anchor[ DVD_VIDEO_LB_LEN ];
|
||||||
uint32_t lbnum, MVDS_location, MVDS_length;
|
uint32_t lbnum, MVDS_location, MVDS_length;
|
||||||
uint16_t TagID;
|
uint16_t TagID;
|
||||||
uint32_t lastsector;
|
uint32_t lastsector;
|
||||||
int i, terminate, volvalid;
|
int terminate;
|
||||||
|
struct avdp_t;
|
||||||
|
|
||||||
/* Find Anchor */
|
/* Find Anchor */
|
||||||
lastsector = 0;
|
lastsector = 0;
|
||||||
|
@ -389,6 +415,39 @@ static int UDFFindPartition( dvd_reader_t *device, int partnum,
|
||||||
}
|
}
|
||||||
/* Main volume descriptor */
|
/* Main volume descriptor */
|
||||||
UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
|
UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
|
||||||
|
avdp->mvds.location = MVDS_location;
|
||||||
|
avdp->mvds.length = MVDS_length;
|
||||||
|
|
||||||
|
/* Backup volume descriptor */
|
||||||
|
UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );
|
||||||
|
avdp->rvds.location = MVDS_location;
|
||||||
|
avdp->rvds.length = MVDS_length;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks for partition on the disc. Returns 1 if partition found, 0 on error.
|
||||||
|
* partnum: Number of the partition, starting at 0.
|
||||||
|
* part: structure to fill with the partition information
|
||||||
|
*/
|
||||||
|
static int UDFFindPartition( dvd_reader_t *device, int partnum,
|
||||||
|
struct Partition *part )
|
||||||
|
{
|
||||||
|
uint8_t LogBlock[ DVD_VIDEO_LB_LEN ];
|
||||||
|
uint32_t lbnum, MVDS_location, MVDS_length;
|
||||||
|
uint16_t TagID;
|
||||||
|
int i, volvalid;
|
||||||
|
struct avdp_t avdp;
|
||||||
|
|
||||||
|
|
||||||
|
if(!UDFGetAVDP(device, &avdp)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main volume descriptor */
|
||||||
|
MVDS_location = avdp.mvds.location;
|
||||||
|
MVDS_length = avdp.mvds.length;
|
||||||
|
|
||||||
part->valid = 0;
|
part->valid = 0;
|
||||||
volvalid = 0;
|
volvalid = 0;
|
||||||
|
@ -425,7 +484,8 @@ static int UDFFindPartition( dvd_reader_t *device, int partnum,
|
||||||
|
|
||||||
if( ( !part->valid) || ( !volvalid ) ) {
|
if( ( !part->valid) || ( !volvalid ) ) {
|
||||||
/* Backup volume descriptor */
|
/* Backup volume descriptor */
|
||||||
UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );
|
MVDS_location = avdp.mvds.location;
|
||||||
|
MVDS_length = avdp.mvds.length;
|
||||||
}
|
}
|
||||||
} while( i-- && ( ( !part->valid ) || ( !volvalid ) ) );
|
} while( i-- && ( ( !part->valid ) || ( !volvalid ) ) );
|
||||||
|
|
||||||
|
@ -449,6 +509,7 @@ uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
|
||||||
tokenline[0] = '\0';
|
tokenline[0] = '\0';
|
||||||
strcat( tokenline, filename );
|
strcat( tokenline, filename );
|
||||||
|
|
||||||
|
|
||||||
/* Find partition, 0 is the standard location for DVD Video.*/
|
/* Find partition, 0 is the standard location for DVD Video.*/
|
||||||
if( !UDFFindPartition( device, 0, &partition ) ) return 0;
|
if( !UDFFindPartition( device, 0, &partition ) ) return 0;
|
||||||
|
|
||||||
|
@ -476,13 +537,21 @@ uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
|
||||||
if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) return 0;
|
if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) return 0;
|
||||||
if( filetype != 4 ) return 0; /* Root dir should be dir */
|
if( filetype != 4 ) return 0; /* Root dir should be dir */
|
||||||
|
|
||||||
|
{
|
||||||
/* Tokenize filepath */
|
/* Tokenize filepath */
|
||||||
token = strtok(tokenline, "/");
|
token = strtok(tokenline, "/");
|
||||||
|
|
||||||
while( token != NULL ) {
|
while( token != NULL ) {
|
||||||
if( !UDFScanDir( device, File, token, &partition, &ICB ) ) return 0;
|
|
||||||
if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) return 0;
|
if( !UDFScanDir( device, File, token, &partition, &ICB)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
token = strtok( NULL, "/" );
|
token = strtok( NULL, "/" );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if( File.Partition != 0 ) return 0;
|
if( File.Partition != 0 ) return 0;
|
||||||
|
@ -494,3 +563,81 @@ uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
|
||||||
else
|
else
|
||||||
return partition.Start + File.Location;
|
return partition.Start + File.Location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a Descriptor .
|
||||||
|
* Returns 1 if descriptor found, 0 on error.
|
||||||
|
* id, tagid of descriptor
|
||||||
|
* bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN).
|
||||||
|
*/
|
||||||
|
static int UDFGetDescriptor( dvd_reader_t *device, int id,
|
||||||
|
uint8_t *descriptor, int bufsize)
|
||||||
|
{
|
||||||
|
uint32_t lbnum, MVDS_location, MVDS_length;
|
||||||
|
struct avdp_t avdp;
|
||||||
|
uint16_t TagID;
|
||||||
|
uint32_t lastsector;
|
||||||
|
int i, terminate;
|
||||||
|
int desc_found = 0;
|
||||||
|
/* Find Anchor */
|
||||||
|
lastsector = 0;
|
||||||
|
lbnum = 256; /* Try #1, prime anchor */
|
||||||
|
terminate = 0;
|
||||||
|
if(bufsize < DVD_VIDEO_LB_LEN) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!UDFGetAVDP(device, &avdp)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main volume descriptor */
|
||||||
|
MVDS_location = avdp.mvds.location;
|
||||||
|
MVDS_length = avdp.mvds.length;
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
do {
|
||||||
|
/* Find Descriptor */
|
||||||
|
lbnum = MVDS_location;
|
||||||
|
do {
|
||||||
|
|
||||||
|
if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) {
|
||||||
|
TagID = 0;
|
||||||
|
} else {
|
||||||
|
UDFDescriptor( descriptor, &TagID );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (TagID == id) && ( !desc_found ) ) {
|
||||||
|
/* Descriptor */
|
||||||
|
desc_found = 1;
|
||||||
|
}
|
||||||
|
} while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )
|
||||||
|
/ DVD_VIDEO_LB_LEN ) && ( TagID != 8 )
|
||||||
|
&& ( !desc_found) );
|
||||||
|
|
||||||
|
if( !desc_found ) {
|
||||||
|
/* Backup volume descriptor */
|
||||||
|
MVDS_location = avdp.rvds.location;
|
||||||
|
MVDS_length = avdp.rvds.length;
|
||||||
|
}
|
||||||
|
} while( i-- && ( !desc_found ) );
|
||||||
|
|
||||||
|
return desc_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd)
|
||||||
|
{
|
||||||
|
uint8_t pvd_buf[DVD_VIDEO_LB_LEN];
|
||||||
|
|
||||||
|
if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);
|
||||||
|
memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue