[MPlayer-cvslog] CVS: main/libmpdvdkit2 Makefile, 1.4, 1.5 README, 1.4, 1.5 bswap.h, 1.4, 1.5 config.h, 1.3, 1.4 dvd_input.c, 1.5, 1.6 dvd_input.h, 1.3, 1.4 dvd_reader.c, 1.14, 1.15 dvd_reader.h, 1.3, 1.4 dvd_udf.c, 1.5, 1.6 dvd_udf.h, 1.1, 1.2 ifo_print.c, 1.3, 1.4 ifo_print.h, 1.3, 1.4 ifo_read.c, 1.3, 1.4 ifo_read.h, 1.3, 1.4 ifo_types.h, 1.3, 1.4 nav_print.c, 1.3, 1.4 nav_print.h, 1.3, 1.4 nav_read.c, 1.5, 1.6 nav_read.h, 1.3, 1.4 nav_types.h, 1.3, 1.4
Aurelien Jacobs CVS
syncmail at mplayerhq.hu
Fri Jul 1 00:48:29 CEST 2005
CVS change done by Aurelien Jacobs CVS
Update of /cvsroot/mplayer/main/libmpdvdkit2
In directory mail:/var2/tmp/cvs-serv18766/libmpdvdkit2
Modified Files:
Makefile README bswap.h config.h dvd_input.c dvd_input.h
dvd_reader.c dvd_reader.h dvd_udf.c dvd_udf.h ifo_print.c
ifo_print.h ifo_read.c ifo_read.h ifo_types.h nav_print.c
nav_print.h nav_read.c nav_read.h nav_types.h
Log Message:
update libdvdread to v0.9.4
Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/Makefile,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Makefile 30 Jun 2005 22:41:40 -0000 1.4
+++ Makefile 30 Jun 2005 22:48:26 -0000 1.5
@@ -15,6 +15,7 @@
libdvdcss.c \
nav_print.c \
nav_read.c \
+ md5.c \
#bsdi_ioctl.c
@@ -34,7 +35,8 @@
# -funroll-loops removed, triggered gcc 3.0.4 (3.x?) bug
CFLAGS= -I. $(OPTFLAGS) $(EXTRA_INC)\
- -DSYS_LINUX -D__USE_UNIX98 -D_REENTRANT -D_GNU_SOURCE
+ -DSYS_LINUX -D__USE_UNIX98 -D_REENTRANT -D_GNU_SOURCE \
+ -DHAVE_DVDCSS_DVDCSS_H -DSTDC_HEADERS
.c.o:
$(CC) $(CFLAGS) -c -o $@ $<
Index: README
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/README,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- README 8 Feb 2003 00:22:38 -0000 1.4
+++ README 30 Jun 2005 22:48:26 -0000 1.5
@@ -1,12 +1,12 @@
-MPlayer DVD-kit v2.2 :)
+MPlayer DVD-kit v2.3 :)
made by Pontscho & A'rpi for the MPlayer project
What the hell is this?
======================
Nothing special, just a collection of sources and patches and fixes:
-- dvdread 0.9.3 + static libdvdcss (removed dlopen code)
-- libdvdcss 1.2.5
+- dvdread 0.9.4 + static libdvdcss
+- libdvdcss 1.2.8
- optimizations enabled, asserts disabled
everything packed together with _static_ linking to maximize performance.
Index: bswap.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/bswap.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- bswap.h 25 May 2005 08:48:32 -0000 1.4
+++ bswap.h 30 Jun 2005 22:48:26 -0000 1.5
@@ -32,6 +32,11 @@
#else
+/* For __FreeBSD_version */
+#if defined(HAVE_SYS_PARAM_H)
+#include <sys/param.h>
+#endif
+
#if defined(__linux__)
#include <byteswap.h>
#define B2N_16(x) x = bswap_16(x)
@@ -50,6 +55,18 @@
#define B2N_32(x) x = swap32(x)
#define B2N_64(x) x = swap64(x)
+#elif defined(__FreeBSD__) && __FreeBSD_version >= 470000
+#include <sys/endian.h>
+#define B2N_16(x) x = be16toh(x)
+#define B2N_32(x) x = be32toh(x)
+#define B2N_64(x) x = be64toh(x)
+
+#elif defined(__DragonFly__)
+#include <sys/endian.h>
+#define B2N_16(x) x = be16toh(x)
+#define B2N_32(x) x = be32toh(x)
+#define B2N_64(x) x = be64toh(x)
+
#elif defined(ARCH_X86)
inline static unsigned short bswap_16(unsigned short x)
{
@@ -88,17 +105,12 @@
}
#define B2N_64(x) x = bswap_64(x)
-#elif defined(__DragonFly__)
-#include <sys/endian.h>
-#define B2N_16(x) x = be16toh(x)
-#define B2N_32(x) x = be32toh(x)
-#define B2N_64(x) x = be64toh(x)
-
/* This is a slow but portable implementation, it has multiple evaluation
* problems so beware.
- * FreeBSD and Solaris don't have <byteswap.h> or any other such
+ * Old FreeBSD's and Solaris don't have <byteswap.h> or any other such
* functionality!
*/
+
#elif defined(__FreeBSD__) || defined(__sun) || defined(__bsdi__) || defined(__CYGWIN__)
#define B2N_16(x) \
x = ((((x) & 0xff00) >> 8) | \
Index: config.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/config.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- config.h 23 Feb 2003 20:31:59 -0000 1.3
+++ config.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -1,6 +1,6 @@
/* Version number of package */
-#define VERSION "1.2.2"
+#define VERSION "1.2.3"
#define HAVE_UNISTD_H 1
/* Define if your processor stores words with the most significant
Index: dvd_input.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/dvd_input.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- dvd_input.c 11 Mar 2005 02:40:28 -0000 1.5
+++ dvd_input.c 30 Jun 2005 22:48:26 -0000 1.6
@@ -21,6 +21,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*/
+#include "config.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
@@ -29,21 +31,34 @@
#include "dvd_reader.h"
#include "dvd_input.h"
-#include "dvdcss.h"
+/* The function pointers that is the exported interface of this file. */
+dvd_input_t (*dvdinput_open) (const char *);
+int (*dvdinput_close) (dvd_input_t);
+int (*dvdinput_seek) (dvd_input_t, int);
+int (*dvdinput_title) (dvd_input_t, int);
+int (*dvdinput_read) (dvd_input_t, void *, int, int);
+char * (*dvdinput_error) (dvd_input_t);
-dvdcss_handle (*DVDcss_open) (const char *);
-int (*DVDcss_close) (dvdcss_handle);
-int (*DVDcss_seek) (dvdcss_handle, int, int);
-int (*DVDcss_title) (dvdcss_handle, int);
-int (*DVDcss_read) (dvdcss_handle, void *, int, int);
-char * (*DVDcss_error) (dvdcss_handle);
-
-dvd_input_t (*DVDinput_open) (const char *);
-int (*DVDinput_close) (dvd_input_t);
-int (*DVDinput_seek) (dvd_input_t, int, int);
-int (*DVDinput_title) (dvd_input_t, int);
-int (*DVDinput_read) (dvd_input_t, void *, int, int);
-char * (*DVDinput_error) (dvd_input_t);
+#ifdef HAVE_DVDCSS_DVDCSS_H
+/* linking to libdvdcss */
+#include "dvdcss.h"
+#define DVDcss_open(a) dvdcss_open((char*)(a))
+#define DVDcss_close dvdcss_close
+#define DVDcss_seek dvdcss_seek
+#define DVDcss_title dvdcss_title
+#define DVDcss_read dvdcss_read
+#define DVDcss_error dvdcss_error
+#else
+/* dlopening libdvdcss */
+#include <dlfcn.h>
+typedef struct dvdcss_s *dvdcss_handle;
+static dvdcss_handle (*DVDcss_open) (const char *);
+static int (*DVDcss_close) (dvdcss_handle);
+static int (*DVDcss_seek) (dvdcss_handle, int, int);
+static int (*DVDcss_title) (dvdcss_handle, int);
+static int (*DVDcss_read) (dvdcss_handle, void *, int, int);
+static char * (*DVDcss_error) (dvdcss_handle);
+#endif
/* The DVDinput handle, add stuff here for new input methods. */
struct dvd_input_s {
@@ -61,7 +76,7 @@
static dvd_input_t css_open(const char *target)
{
dvd_input_t dev;
-
+
/* Allocate the handle structure */
dev = (dvd_input_t) malloc(sizeof(struct dvd_input_s));
if(dev == NULL) {
@@ -72,7 +87,7 @@
/* Really open it with libdvdcss */
dev->dvdcss = DVDcss_open(target);
if(dev->dvdcss == 0) {
- fprintf(stderr, "libdvdread: Could not open device with libdvdcss.\n");
+ fprintf(stderr, "libdvdread: Could not open %s with libdvdcss.\n", target);
free(dev);
return NULL;
}
@@ -91,9 +106,10 @@
/**
* seek into the device.
*/
-static int css_seek(dvd_input_t dev, int blocks, int flags)
+static int css_seek(dvd_input_t dev, int blocks)
{
- return DVDcss_seek(dev->dvdcss, blocks, flags);
+ /* DVDINPUT_NOFLAGS should match the DVDCSS_NOFLAGS value. */
+ return DVDcss_seek(dev->dvdcss, blocks, DVDINPUT_NOFLAGS);
}
/**
@@ -131,34 +147,207 @@
+
+
+
+/**
+ * initialize and open a DVD device or file.
+ */
+static dvd_input_t file_open(const char *target)
+{
+ dvd_input_t dev;
+
+ /* Allocate the library structure */
+ dev = (dvd_input_t) malloc(sizeof(dvd_input_t));
+ if(dev == NULL) {
+ fprintf(stderr, "libdvdread: Could not allocate memory.\n");
+ return NULL;
+ }
+
+ /* Open the device */
+ dev->fd = open(target, O_RDONLY);
+ if(dev->fd < 0) {
+ perror("libdvdread: Could not open input");
+ free(dev);
+ return NULL;
+ }
+
+ return dev;
+}
+
+/**
+ * return the last error message
+ */
+static char *file_error(dvd_input_t dev)
+{
+ /* use strerror(errno)? */
+ return (char *)"unknown error";
+}
+
+/**
+ * seek into the device.
+ */
+static int file_seek(dvd_input_t dev, int blocks)
+{
+ off_t pos;
+
+ pos = lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET);
+ if(pos < 0) {
+ return pos;
+ }
+ /* assert pos % DVD_VIDEO_LB_LEN == 0 */
+ return (int) (pos / DVD_VIDEO_LB_LEN);
+}
+
+/**
+ * set the block for the begining of a new title (key).
+ */
+static int file_title(dvd_input_t dev, int block)
+{
+ return -1;
+}
+
+/**
+ * read data from the device.
+ */
+static int file_read(dvd_input_t dev, void *buffer, int blocks, int flags)
+{
+ size_t len;
+ ssize_t ret;
+
+ len = (size_t)blocks * DVD_VIDEO_LB_LEN;
+
+ while(len > 0) {
+
+ ret = read(dev->fd, buffer, len);
+
+ if(ret < 0) {
+ /* One of the reads failed, too bad. We won't even bother
+ * returning the reads that went ok, and as in the posix spec
+ * the file postition is left unspecified after a failure. */
+ return ret;
+ }
+
+ if(ret == 0) {
+ /* Nothing more to read. Return the whole blocks, if any, that we got.
+ and adjust the file possition back to the previous block boundary. */
+ size_t bytes = (size_t)blocks * DVD_VIDEO_LB_LEN - len;
+ off_t over_read = -(bytes % DVD_VIDEO_LB_LEN);
+ /*off_t pos =*/ lseek(dev->fd, over_read, SEEK_CUR);
+ /* should have pos % 2048 == 0 */
+ return (int) (bytes / DVD_VIDEO_LB_LEN);
+ }
+
+ len -= ret;
+ }
+
+ return blocks;
+}
+
+/**
+ * close the DVD device and clean up.
+ */
+static int file_close(dvd_input_t dev)
+{
+ int ret;
+
+ ret = close(dev->fd);
+
+ if(ret < 0)
+ return ret;
+
+ free(dev);
+
+ return 0;
+}
+
+
/**
* Setup read functions with either libdvdcss or minimal DVD access.
*/
-int DVDInputSetup(void)
+int dvdinput_setup(void)
{
- DVDcss_open = dvdcss_open;
- DVDcss_close = dvdcss_close;
- DVDcss_title = dvdcss_title;
- DVDcss_seek = dvdcss_seek;
- DVDcss_read = dvdcss_read;
- DVDcss_error = dvdcss_error;
+ void *dvdcss_library = NULL;
+ char **dvdcss_version = NULL;
+
+#ifdef HAVE_DVDCSS_DVDCSS_H
+ /* linking to libdvdcss */
+ dvdcss_library = &dvdcss_library; /* Give it some value != NULL */
+ /* the DVDcss_* functions have been #defined at the top */
+ dvdcss_version = &dvdcss_interface_2;
+
+#else
+ /* dlopening libdvdcss */
+ dvdcss_library = dlopen("libdvdcss.so.2", RTLD_LAZY);
+
+ if(dvdcss_library != NULL) {
+#if defined(__OpenBSD__) && !defined(__ELF__)
+#define U_S "_"
+#else
+#define U_S
+#endif
+ DVDcss_open = (dvdcss_handle (*)(const char*))
+ dlsym(dvdcss_library, U_S "dvdcss_open");
+ DVDcss_close = (int (*)(dvdcss_handle))
+ dlsym(dvdcss_library, U_S "dvdcss_close");
+ DVDcss_title = (int (*)(dvdcss_handle, int))
+ dlsym(dvdcss_library, U_S "dvdcss_title");
+ DVDcss_seek = (int (*)(dvdcss_handle, int, int))
+ dlsym(dvdcss_library, U_S "dvdcss_seek");
+ DVDcss_read = (int (*)(dvdcss_handle, void*, int, int))
+ dlsym(dvdcss_library, U_S "dvdcss_read");
+ DVDcss_error = (char* (*)(dvdcss_handle))
+ dlsym(dvdcss_library, U_S "dvdcss_error");
+ dvdcss_version = (char **)dlsym(dvdcss_library, U_S "dvdcss_interface_2");
+
+ if(dlsym(dvdcss_library, U_S "dvdcss_crack")) {
+ fprintf(stderr,
+ "libdvdread: Old (pre-0.0.2) version of libdvdcss found.\n"
+ "libdvdread: You should get the latest version from "
+ "http://www.videolan.org/\n" );
+ dlclose(dvdcss_library);
+ dvdcss_library = NULL;
+ } else if(!DVDcss_open || !DVDcss_close || !DVDcss_title || !DVDcss_seek
+ || !DVDcss_read || !DVDcss_error || !dvdcss_version) {
+ fprintf(stderr, "libdvdread: Missing symbols in libdvdcss.so.2, "
+ "this shouldn't happen !\n");
+ dlclose(dvdcss_library);
+ }
+ }
+#endif /* HAVE_DVDCSS_DVDCSS_H */
+
+ if(dvdcss_library != NULL) {
/*
char *psz_method = getenv( "DVDCSS_METHOD" );
char *psz_verbose = getenv( "DVDCSS_VERBOSE" );
fprintf(stderr, "DVDCSS_METHOD %s\n", psz_method);
fprintf(stderr, "DVDCSS_VERBOSE %s\n", psz_verbose);
*/
-// fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD access\n",
-// *dvdcss_version);
+ /*
+ fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD access\n",
+ *dvdcss_version);
+ */
- /* libdvdcss wraper functions */
- DVDinput_open = css_open;
- DVDinput_close = css_close;
- DVDinput_seek = css_seek;
- DVDinput_title = css_title;
- DVDinput_read = css_read;
- DVDinput_error = css_error;
+ /* libdvdcss wrapper functions */
+ dvdinput_open = css_open;
+ dvdinput_close = css_close;
+ dvdinput_seek = css_seek;
+ dvdinput_title = css_title;
+ dvdinput_read = css_read;
+ dvdinput_error = css_error;
return 1;
+ } else {
+ fprintf(stderr, "libdvdread: Encrypted DVD support unavailable.\n");
+
+ /* libdvdcss replacement functions */
+ dvdinput_open = file_open;
+ dvdinput_close = file_close;
+ dvdinput_seek = file_seek;
+ dvdinput_title = file_title;
+ dvdinput_read = file_read;
+ dvdinput_error = file_error;
+ return 0;
+ }
}
Index: dvd_input.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/dvd_input.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- dvd_input.h 11 Mar 2005 02:40:28 -0000 1.3
+++ dvd_input.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -5,10 +5,6 @@
* Copyright (C) 2001, 2002 Samuel Hocevar <sam at zoy.org>,
* Håkan Hjort <d95hjort at dtek.chalmers.se>
*
- * Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
- * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
- * $Id$
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -31,25 +27,21 @@
#define DVDINPUT_READ_DECRYPT (1 << 0)
-#define DVDINPUT_SEEK_MPEG (1 << 0)
-#define DVDINPUT_SEEK_KEY (1 << 1)
-
-
typedef struct dvd_input_s *dvd_input_t;
/**
- * Pointers which will be filled either the input meathods functions.
+ * Pointers which will be filled either the input methods functions.
*/
-extern dvd_input_t (*DVDinput_open) (const char *);
-extern int (*DVDinput_close) (dvd_input_t);
-extern int (*DVDinput_seek) (dvd_input_t, int, int);
-extern int (*DVDinput_title) (dvd_input_t, int);
-extern int (*DVDinput_read) (dvd_input_t, void *, int, int);
-extern char * (*DVDinput_error) (dvd_input_t);
+extern dvd_input_t (*dvdinput_open) (const char *);
+extern int (*dvdinput_close) (dvd_input_t);
+extern int (*dvdinput_seek) (dvd_input_t, int);
+extern int (*dvdinput_title) (dvd_input_t, int);
+extern int (*dvdinput_read) (dvd_input_t, void *, int, int);
+extern char * (*dvdinput_error) (dvd_input_t);
/**
* Setup function accessed by dvd_reader.c. Returns 1 if there is CSS support.
*/
-int DVDInputSetup(void);
+int dvdinput_setup(void);
#endif /* DVD_INPUT_H_INCLUDED */
Index: dvd_reader.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/dvd_reader.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- dvd_reader.c 25 May 2005 08:48:32 -0000 1.14
+++ dvd_reader.c 30 Jun 2005 22:48:26 -0000 1.15
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2001, 2002 Billy Biggs <vektor at dumbterm.net>,
- * Håkan Hjort <d95hjort at dtek.chalmers.se>
+ * Copyright (C) 2001, 2002, 2003 Billy Biggs <vektor at dumbterm.net>,
+ * Håkan Hjort <d95hjort at dtek.chalmers.se>,
+ * Björn Englund <d4bjorn at dtek.chalmers.se>
*
* Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
* detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
@@ -62,6 +63,9 @@
#include "dvd_udf.h"
#include "dvd_input.h"
#include "dvd_reader.h"
+#include "md5.h"
+
+#define DEFAULT_UDF_CACHE_LEVEL 0
struct dvd_reader_s {
/* Basic information. */
@@ -70,13 +74,17 @@
/* Hack for keeping track of the css status.
* 0: no css, 1: perhaps (need init of keys), 2: have done init */
int css_state;
- int css_title; /* Last title that we have called DVDinpute_title for. */
+ int css_title; /* Last title that we have called dvdinpute_title for. */
/* Information required for an image file. */
dvd_input_t dev;
/* Information required for a directory path drive. */
char *path_root;
+
+ /* Filesystem cache */
+ int udfcache_level; /* 0 - turned off, 1 - on */
+ void *udfcache;
};
struct dvd_file_s {
@@ -98,6 +106,42 @@
ssize_t filesize;
};
+/**
+ * Set the level of caching on udf
+ * level = 0 (no caching)
+ * level = 1 (caching filesystem info)
+ */
+int DVDUDFCacheLevel(dvd_reader_t *device, int level)
+{
+ struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
+
+ if(level > 0) {
+ level = 1;
+ } else if(level < 0) {
+ return dev->udfcache_level;
+ }
+
+ dev->udfcache_level = level;
+
+ return level;
+}
+
+void *GetUDFCacheHandle(dvd_reader_t *device)
+{
+ struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
+
+ return dev->udfcache;
+}
+
+void SetUDFCacheHandle(dvd_reader_t *device, void *cache)
+{
+ struct dvd_reader_s *dev = (struct dvd_reader_s *)device;
+
+ dev->udfcache = cache;
+}
+
+
+
/* Loop over all titles and call dvdcss_title to crack the keys. */
static int initAllCSSKeys( dvd_reader_t *dvd )
{
@@ -107,6 +151,10 @@
uint32_t start, len;
int title;
+ char *nokeys_str = getenv("DVDREAD_NOKEYS");
+ if(nokeys_str != NULL)
+ return 0;
+
fprintf( stderr, "\n" );
fprintf( stderr, "libdvdread: Attempting to retrieve all CSS keys\n" );
fprintf( stderr, "libdvdread: This can take a _long_ time, "
@@ -126,7 +174,7 @@
/* Perform CSS key cracking for this title. */
fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
filename, start );
- if( DVDinput_title( dvd->dev, (int)start ) < 0 ) {
+ if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)\n", filename, start);
}
gettimeofday( &t_e, NULL );
@@ -144,7 +192,7 @@
/* Perform CSS key cracking for this title. */
fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
filename, start );
- if( DVDinput_title( dvd->dev, (int)start ) < 0 ) {
+ if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)!!\n", filename, start);
}
gettimeofday( &t_e, NULL );
@@ -177,18 +225,8 @@
{
dvd_reader_t *dvd;
dvd_input_t dev;
-
- /* setup cache dir is no longer needed, it's now implemented in libdvdcss.c
- if(!dvdcss_cache_dir){
- dvdcss_cache_dir=get_path( "" );
- if ( dvdcss_cache_dir ) { mkdir( dvdcss_cache_dir,493 ); free( dvdcss_cache_dir ); }
- dvdcss_cache_dir=get_path( "DVDKeys" );
- if(dvdcss_cache_dir) mkdir( dvdcss_cache_dir,493 );
- }
- */
- /* open it */
- dev = DVDinput_open( location );
+ dev = dvdinput_open( location );
if( !dev ) {
fprintf( stderr, "libdvdread: Can't open %s for reading\n", location );
return 0;
@@ -200,6 +238,9 @@
dvd->dev = dev;
dvd->path_root = 0;
+ dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
+ dvd->udfcache = NULL;
+
if( have_css ) {
/* Only if DVDCSS_METHOD = title, a bit if it's disc or if
* DVDCSS_METHOD = key but region missmatch. Unfortunaly we
@@ -207,6 +248,7 @@
dvd->css_state = 1; /* Need key init. */
}
+ dvd->css_title = 0;
return dvd;
}
@@ -221,6 +263,12 @@
dvd->dev = 0;
dvd->path_root = strdup( path_root );
+ dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
+ dvd->udfcache = NULL;
+
+ dvd->css_state = 0; /* Only used in the UDF path */
+ dvd->css_title = 0; /* Only matters in the UDF path */
+
return dvd;
}
@@ -275,7 +323,8 @@
int ret, have_css;
char *dev_name = 0;
- if( !path ) return 0;
+ if( path == NULL )
+ return 0;
#ifdef WIN32
/* Stat doesn't work on devices under mingwin/cygwin. */
@@ -297,7 +346,7 @@
}
/* Try to open libdvdcss or fall back to standard functions */
- have_css = DVDInputSetup();
+ have_css = dvdinput_setup();
/* First check if this is a block/char device or a file*/
if( S_ISBLK( fileinfo.st_mode ) ||
@@ -445,10 +494,10 @@
void DVDClose( dvd_reader_t *dvd )
{
if( dvd ) {
- if( dvd->dev ) DVDinput_close( dvd->dev );
+ if( dvd->dev ) dvdinput_close( dvd->dev );
if( dvd->path_root ) free( dvd->path_root );
+ if( dvd->udfcache ) FreeUDFCache( dvd->udfcache );
free( dvd );
- dvd = 0;
}
}
@@ -545,7 +594,7 @@
/* Get the full path of the file. */
if( !findDVDFile( dvd, filename, full_path ) ) return 0;
- dev = DVDinput_open( full_path );
+ dev = dvdinput_open( full_path );
if( !dev ) return 0;
dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
@@ -609,8 +658,7 @@
// dvd->css_state = 2;
}
/*
- if( DVDinput_seek( dvd_file->dvd->dev,
- (int)start, DVDINPUT_SEEK_KEY ) < 0 ) {
+ if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) {
fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n",
filename );
}
@@ -636,7 +684,7 @@
memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
dvd_file->filesize = 0;
-
+
if( menu ) {
dvd_input_t dev;
@@ -650,7 +698,7 @@
return 0;
}
- dev = DVDinput_open( full_path );
+ dev = dvdinput_open( full_path );
if( dev == NULL ) {
free( dvd_file );
return 0;
@@ -663,7 +711,7 @@
}
dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
dvd_file->title_devs[ 0 ] = dev;
- DVDinput_seek( dvd_file->title_devs[0], 0, DVDINPUT_SEEK_KEY );
+ dvdinput_title( dvd_file->title_devs[0], 0);
dvd_file->filesize = dvd_file->title_sizes[ 0 ];
} else {
@@ -680,9 +728,9 @@
}
dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN;
- dvd_file->title_devs[ i ] = DVDinput_open( full_path );
+ dvd_file->title_devs[ i ] = dvdinput_open( full_path );
+ dvdinput_title( dvd_file->title_devs[ i ], 0 );
dvd_file->filesize += dvd_file->title_sizes[ i ];
- DVDinput_seek( dvd_file->title_devs[ i ], 0, DVDINPUT_SEEK_KEY );
}
if( !dvd_file->title_devs[ 0 ] ) {
free( dvd_file );
@@ -697,6 +745,10 @@
dvd_read_domain_t domain )
{
char filename[ MAX_UDF_FILE_NAME_LEN ];
+
+ /* Check arguments. */
+ if( dvd == NULL || titlenum < 0 )
+ return NULL;
switch( domain ) {
case DVD_READ_INFO_FILE:
@@ -730,7 +782,7 @@
break;
default:
fprintf( stderr, "libdvdread: Invalid domain for file open.\n" );
- return 0;
+ return NULL;
}
if( dvd->isImageFile ) {
@@ -750,7 +802,7 @@
} else {
for( i = 0; i < 9; ++i ) {
if( dvd_file->title_devs[ i ] ) {
- DVDinput_close( dvd_file->title_devs[i] );
+ dvdinput_close( dvd_file->title_devs[i] );
}
}
}
@@ -761,7 +813,7 @@
}
/* Internal, but used from dvd_udf.c */
-int DVDReadBlocksUDFRaw( dvd_reader_t *device, uint32_t lb_number,
+int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
size_t block_count, unsigned char *data,
int encrypted )
{
@@ -772,13 +824,13 @@
return 0;
}
- ret = DVDinput_seek( device->dev, (int) lb_number, DVDINPUT_NOFLAGS );
+ ret = dvdinput_seek( device->dev, (int) lb_number );
if( ret != (int) lb_number ) {
fprintf( stderr, "libdvdread: Can't seek to block %u\n", lb_number );
return 0;
}
- return DVDinput_read( device->dev, (char *) data,
+ return dvdinput_read( device->dev, (char *) data,
(int) block_count, encrypted );
}
@@ -792,8 +844,8 @@
size_t block_count, unsigned char *data,
int encrypted )
{
- return DVDReadBlocksUDFRaw( dvd_file->dvd, dvd_file->lb_start + offset,
- block_count, data, encrypted );
+ return UDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset,
+ block_count, data, encrypted );
}
/* This is using possibly several inputs and starting from an offset of '0'.
@@ -816,14 +868,13 @@
if( offset < dvd_file->title_sizes[ i ] ) {
if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) {
- off = DVDinput_seek( dvd_file->title_devs[ i ],
- (int)offset, DVDINPUT_NOFLAGS );
+ off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset );
if( off < 0 || off != (int)offset ) {
fprintf( stderr, "libdvdread: Can't seek to block %d\n",
offset );
return off < 0 ? off : 0;
}
- ret = DVDinput_read( dvd_file->title_devs[ i ], data,
+ ret = dvdinput_read( dvd_file->title_devs[ i ], data,
(int)block_count, encrypted );
break;
} else {
@@ -832,31 +883,29 @@
* (This is only true if you try and read >1GB at a time) */
/* Read part 1 */
- off = DVDinput_seek( dvd_file->title_devs[ i ],
- (int)offset, DVDINPUT_NOFLAGS );
+ off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset );
if( off < 0 || off != (int)offset ) {
fprintf( stderr, "libdvdread: Can't seek to block %d\n",
offset );
return off < 0 ? off : 0;
}
- ret = DVDinput_read( dvd_file->title_devs[ i ], data,
+ ret = dvdinput_read( dvd_file->title_devs[ i ], data,
(int)part1_size, encrypted );
if( ret < 0 ) return ret;
/* FIXME: This is wrong if i is the last file in the set.
* also error from this read will not show in ret. */
-
- /* Does the next part exist? If not then return now. */
- if( !dvd_file->title_devs[ i + 1 ] ) return ret;
+
+ /* Does the next part exist? If not then return now. */
+ if( !dvd_file->title_devs[ i + 1 ] ) return ret;
/* Read part 2 */
- off = DVDinput_seek( dvd_file->title_devs[ i + 1 ],
- 0, DVDINPUT_NOFLAGS );
+ off = dvdinput_seek( dvd_file->title_devs[ i + 1 ], 0 );
if( off < 0 || off != 0 ) {
fprintf( stderr, "libdvdread: Can't seek to block %d\n",
0 );
return off < 0 ? off : 0;
}
- ret2 = DVDinput_read( dvd_file->title_devs[ i + 1 ],
+ ret2 = dvdinput_read( dvd_file->title_devs[ i + 1 ],
data + ( part1_size
* (int64_t)DVD_VIDEO_LB_LEN ),
(int)(block_count - part1_size),
@@ -878,14 +927,20 @@
{
int ret;
+ /* Check arguments. */
+ if( dvd_file == NULL || offset < 0 || data == NULL )
+ return -1;
+
/* Hack, and it will still fail for multiple opens in a threaded app ! */
if( dvd_file->dvd->css_title != dvd_file->css_title ) {
dvd_file->dvd->css_title = dvd_file->css_title;
if( dvd_file->dvd->isImageFile ) {
- DVDinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start );
- } else {
- DVDinput_title( dvd_file->title_devs[ 0 ], (int)dvd_file->lb_start );
- }
+ dvdinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start );
+ }
+ /* Here each vobu has it's own dvdcss handle, so no need to update
+ else {
+ dvdinput_title( dvd_file->title_devs[ 0 ], (int)dvd_file->lb_start );
+ }*/
}
if( dvd_file->dvd->isImageFile ) {
@@ -901,11 +956,15 @@
int DVDFileSeek( dvd_file_t *dvd_file, int offset )
{
- if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) {
+ /* Check arguments. */
+ if( dvd_file == NULL || offset < 0 )
return -1;
- }
- dvd_file->seek_pos = (uint32_t) offset;
- return offset;
+
+ if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) {
+ return -1;
+ }
+ dvd_file->seek_pos = (uint32_t) offset;
+ return offset;
}
ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
@@ -914,10 +973,16 @@
unsigned int numsec, seek_sector, seek_byte;
int ret;
+ /* Check arguments. */
+ if( dvd_file == NULL || data == NULL )
+ return -1;
+
seek_sector = dvd_file->seek_pos / DVD_VIDEO_LB_LEN;
seek_byte = dvd_file->seek_pos % DVD_VIDEO_LB_LEN;
- numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) + 1;
+ numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) +
+ ( ( ( seek_byte + byte_size ) % DVD_VIDEO_LB_LEN ) ? 1 : 0 );
+
secbuf = (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN );
if( !secbuf ) {
fprintf( stderr, "libdvdread: Can't allocate memory "
@@ -947,5 +1012,139 @@
ssize_t DVDFileSize( dvd_file_t *dvd_file )
{
+ /* Check arguments. */
+ if( dvd_file == NULL )
+ return -1;
+
return dvd_file->filesize;
}
+
+int DVDDiscID( dvd_reader_t *dvd, unsigned char *discid )
+{
+ struct md5_ctx ctx;
+ int title;
+
+ /* Check arguments. */
+ if( dvd == NULL || discid == NULL )
+ return 0;
+
+ /* Go through the first 10 IFO:s, in order,
+ * and md5sum them, i.e VIDEO_TS.IFO and VTS_0?_0.IFO */
+ md5_init_ctx( &ctx );
+ for( title = 0; title < 10; title++ ) {
+ dvd_file_t *dvd_file = DVDOpenFile( dvd, title, DVD_READ_INFO_FILE );
+ if( dvd_file != NULL ) {
+ ssize_t bytes_read;
+ size_t file_size = dvd_file->filesize * DVD_VIDEO_LB_LEN;
+ char *buffer = malloc( file_size );
+
+ if( buffer == NULL ) {
+ fprintf( stderr, "libdvdread: DVDDiscId, failed to "
+ "allocate memory for file read!\n" );
+ return -1;
+ }
+ bytes_read = DVDReadBytes( dvd_file, buffer, file_size );
+ if( bytes_read != file_size ) {
+ fprintf( stderr, "libdvdread: DVDDiscId read returned %d bytes"
+ ", wanted %d\n", bytes_read, file_size );
+ DVDCloseFile( dvd_file );
+ return -1;
+ }
+
+ md5_process_bytes( buffer, file_size, &ctx );
+
+ DVDCloseFile( dvd_file );
+ free( buffer );
+ }
+ }
+ md5_finish_ctx( &ctx, discid );
+
+ return 0;
+}
+
+
+int DVDISOVolumeInfo( dvd_reader_t *dvd,
+ char *volid, unsigned int volid_size,
+ unsigned char *volsetid, unsigned int volsetid_size )
+{
+ unsigned char *buffer;
+ int ret;
+
+ /* Check arguments. */
+ if( dvd == NULL )
+ return 0;
+
+ if( dvd->dev == NULL ) {
+ /* No block access, so no ISO... */
+ return -1;
+ }
+
+ buffer = malloc( DVD_VIDEO_LB_LEN );
+ if( buffer == NULL ) {
+ fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
+ "allocate memory for file read!\n" );
+ return -1;
+ }
+
+ ret = UDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );
+ if( ret != 1 ) {
+ fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
+ "read ISO9660 Primary Volume Descriptor!\n" );
+ return -1;
+ }
+
+ if( (volid != NULL) && (volid_size > 0) ) {
+ unsigned int n;
+ for(n = 0; n < 32; n++) {
+ if(buffer[40+n] == 0x20) {
+ break;
+ }
+ }
+
+ if(volid_size > n+1) {
+ volid_size = n+1;
+ }
+
+ memcpy(volid, &buffer[40], volid_size-1);
+ volid[volid_size-1] = '\0';
+ }
+
+ if( (volsetid != NULL) && (volsetid_size > 0) ) {
+ if(volsetid_size > 128) {
+ volsetid_size = 128;
+ }
+ memcpy(volsetid, &buffer[190], volsetid_size);
+ }
+ return 0;
+}
+
+
+int DVDUDFVolumeInfo( dvd_reader_t *dvd,
+ char *volid, unsigned int volid_size,
+ unsigned char *volsetid, unsigned int volsetid_size )
+{
+ int ret;
+ /* Check arguments. */
+ if( dvd == NULL )
+ return -1;
+
+ if( dvd->dev == NULL ) {
+ /* No block access, so no UDF VolumeSet Identifier */
+ return -1;
+ }
+
+ if( (volid != NULL) && (volid_size > 0) ) {
+ ret = UDFGetVolumeIdentifier(dvd, volid, volid_size);
+ if(!ret) {
+ return -1;
+ }
+ }
+ if( (volsetid != NULL) && (volsetid_size > 0) ) {
+ ret = UDFGetVolumeSetIdentifier(dvd, volsetid, volsetid_size);
+ if(!ret) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
Index: dvd_reader.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/dvd_reader.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- dvd_reader.h 30 May 2003 17:38:51 -0000 1.3
+++ dvd_reader.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -3,7 +3,8 @@
/*
* Copyright (C) 2001, 2002 Billy Biggs <vektor at dumbterm.net>,
- * Håkan Hjort <d95hjort at dtek.chalmers.se>
+ * Håkan Hjort <d95hjort at dtek.chalmers.se>,
+ * Björn Englund <d4bjorn at dtek.chalmers.se>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,128 +24,241 @@
#include <sys/types.h>
/**
- * The length of one Logical Block of a DVD Video.
+ * The DVD access interface.
+ *
+ * This file contains the functions that form the interface to to
+ * reading files located on a DVD.
+ */
+
+/**
+ * The current version.
+ */
+#define DVDREAD_VERSION 904
+
+/**
+ * The length of one Logical Block of a DVD.
*/
#define DVD_VIDEO_LB_LEN 2048
/**
- * Maximum length of filenames for UDF.
+ * Maximum length of filenames allowed in UDF.
*/
#define MAX_UDF_FILE_NAME_LEN 2048
#ifdef __cplusplus
extern "C" {
#endif
-
+
+/**
+ * Opaque type that is used as a handle for one instance of an opened DVD.
+ */
typedef struct dvd_reader_s dvd_reader_t;
+
+/**
+ * Opaque type for a file read handle, much like a normal fd or FILE *.
+ */
typedef struct dvd_file_s dvd_file_t;
/**
- * dvd = DVDOpen(path);
- *
* Opens a block device of a DVD-ROM file, or an image file, or a directory
- * name for a mounted DVD or HD copy of a DVD. Returns 0 if we can't get any
- * of those methods to work.
+ * name for a mounted DVD or HD copy of a DVD.
*
* If the given file is a block device, or is the mountpoint for a block
* device, then that device is used for CSS authentication using libdvdcss.
* If no device is available, then no CSS authentication is performed,
* and we hope that the image is decrypted.
*
- * If the path given is a directory, then the files in that directory may be in
- * any one of these formats:
+ * If the path given is a directory, then the files in that directory may be
+ * in any one of these formats:
*
* path/VIDEO_TS/VTS_01_1.VOB
* path/video_ts/vts_01_1.vob
* path/VTS_01_1.VOB
* path/vts_01_1.vob
+ *
+ * @param path Specifies the the device, file or directory to be used.
+ * @return If successful a a read handle is returned. Otherwise 0 is returned.
+ *
+ * dvd = DVDOpen(path);
*/
dvd_reader_t *DVDOpen( const char * );
/**
- * DVDClose(dvd);
+ * Closes and cleans up the DVD reader object.
*
- * Closes and cleans up the DVD reader object. You must close all open files
- * before calling this function.
+ * You must close all open files before calling this function.
+ *
+ * @param dvd A read handle that should be closed.
+ *
+ * DVDClose(dvd);
*/
void DVDClose( dvd_reader_t * );
/**
- * INFO_FILE : VIDEO_TS.IFO (manager)
- * VTS_XX_0.IFO (title)
- *
- * INFO_BACKUP_FILE: VIDEO_TS.BUP (manager)
- * VTS_XX_0.BUP (title)
- *
- * MENU_VOBS : VIDEO_TS.VOB (manager)
- * VTS_XX_0.VOB (title)
- *
- * TITLE_VOBS : VTS_XX_[1-9].VOB (title)
- * All files in the title set are opened and
- * read as a single file.
+ *
*/
typedef enum {
- DVD_READ_INFO_FILE,
- DVD_READ_INFO_BACKUP_FILE,
- DVD_READ_MENU_VOBS,
- DVD_READ_TITLE_VOBS
+ DVD_READ_INFO_FILE, /**< VIDEO_TS.IFO or VTS_XX_0.IFO (title) */
+ DVD_READ_INFO_BACKUP_FILE, /**< VIDEO_TS.BUP or VTS_XX_0.BUP (title) */
+ DVD_READ_MENU_VOBS, /**< VIDEO_TS.VOB or VTS_XX_0.VOB (title) */
+ DVD_READ_TITLE_VOBS /**< VTS_XX_[1-9].VOB (title). All files in
+ the title set are opened and read as a
+ single file. */
} dvd_read_domain_t;
/**
- * dvd_file = DVDOpenFile(dvd, titlenum, domain);
+ * Opens a file on the DVD given the title number and domain.
*
- * Opens a file on the DVD given the title number and domain. If the title
- * number is 0, the video manager information is opened
- * (VIDEO_TS.[IFO,BUP,VOB]). Returns a file structure which may be used for
- * reads, or 0 if the file was not found.
- */
-dvd_file_t *DVDOpenFile( dvd_reader_t *, int,
- dvd_read_domain_t );
+ * If the title number is 0, the video manager information is opened
+ * (VIDEO_TS.[IFO,BUP,VOB]). Returns a file structure which may be
+ * used for reads, or 0 if the file was not found.
+ *
+ * @param dvd A dvd read handle.
+ * @param titlenum Which Video Title Set should be used, VIDEO_TS is 0.
+ * @param domain Which domain.
+ * @return If successful a a file read handle is returned, otherwise 0.
+ *
+ * dvd_file = DVDOpenFile(dvd, titlenum, domain); */
+dvd_file_t *DVDOpenFile( dvd_reader_t *, int, dvd_read_domain_t );
/**
- * DVDCloseFile(dvd_file);
- *
* Closes a file and frees the associated structure.
+ *
+ * @param dvd_file The file read handle to be closed.
+ *
+ * DVDCloseFile(dvd_file);
*/
void DVDCloseFile( dvd_file_t * );
/**
- * blocks_read = DVDReadBlocks(dvd_file, offset, block_count, data);
- *
* Reads block_count number of blocks from the file at the given block offset.
* Returns number of blocks read on success, -1 on error. This call is only
* for reading VOB data, and should not be used when reading the IFO files.
* When reading from an encrypted drive, blocks are decrypted using libdvdcss
* where required.
+ *
+ * @param dvd_file A file read handle.
+ * @param offset Block offset from the start of the file to start reading at.
+ * @param block_count Number of block to read.
+ * @param data Pointer to a buffer to write the data into.
+ * @return Returns number of blocks read on success, -1 on error.
+ *
+ * blocks_read = DVDReadBlocks(dvd_file, offset, block_count, data);
*/
ssize_t DVDReadBlocks( dvd_file_t *, int, size_t, unsigned char * );
/**
- * offset_set = DVDFileSeek(dvd_file, seek_offset);
- *
* Seek to the given position in the file. Returns the resulting position in
* bytes from the beginning of the file. The seek position is only used for
* byte reads from the file, the block read call always reads from the given
* offset.
+ *
+ * @param dvd_file A file read handle.
+ * @param seek_offset Byte offset from the start of the file to seek to.
+ * @return The resulting position in bytes from the beginning of the file.
+ *
+ * offset_set = DVDFileSeek(dvd_file, seek_offset);
*/
int DVDFileSeek( dvd_file_t *, int );
/**
- * bytes_read = DVDReadBytes(dvd_file, data, bytes);
- *
* Reads the given number of bytes from the file. This call can only be used
* on the information files, and may not be used for reading from a VOB. This
* reads from and increments the currrent seek position for the file.
+ *
+ * @param dvd_file A file read handle.
+ * @param data Pointer to a buffer to write the data into.
+ * @param bytes Number of bytes to read.
+ * @return Returns number of bytes read on success, -1 on error.
+ *
+ * bytes_read = DVDReadBytes(dvd_file, data, bytes);
*/
ssize_t DVDReadBytes( dvd_file_t *, void *, size_t );
/**
- * blocks = DVDFileSize(dvd_file);
- *
* Returns the file size in blocks.
+ *
+ * @param dvd_file A file read handle.
+ * @return The size of the file in blocks, -1 on error.
+ *
+ * blocks = DVDFileSize(dvd_file);
*/
ssize_t DVDFileSize( dvd_file_t * );
+/**
+ * Get a unique 128 bit disc ID.
+ * This is the MD5 sum of VIDEO_TS.IFO and the VTS_0?_0.IFO files
+ * in title order (those that exist).
+ * If you need a 'text' representation of the id, print it as a
+ * hexadecimal number, using lowercase letters, discid[0] first.
+ * I.e. the same format as the command-line 'md5sum' program uses.
+ *
+ * @param dvd A read handle to get the disc ID from
+ * @param discid The buffer to put the disc ID into. The buffer must
+ * have room for 128 bits (16 chars).
+ * @return 0 on success, -1 on error.
+ */
+int DVDDiscID( dvd_reader_t *, unsigned char * );
+
+/**
+ * Get the UDF VolumeIdentifier and VolumeSetIdentifier
+ * from the PrimaryVolumeDescriptor.
+ *
+ * @param dvd A read handle to get the disc ID from
+ * @param volid The buffer to put the VolumeIdentifier into.
+ * The VolumeIdentifier is latin-1 encoded (8bit unicode)
+ * null terminated and max 32 bytes (including '\0')
+ * @param volid_size No more than volid_size bytes will be copied to volid.
+ * If the VolumeIdentifier is truncated because of this
+ * it will still be null terminated.
+ * @param volsetid The buffer to put the VolumeSetIdentifier into.
+ * The VolumeIdentifier is 128 bytes as
+ * stored in the UDF PrimaryVolumeDescriptor.
+ * Note that this is not a null terminated string.
+ * @param volsetid_size At most volsetid_size bytes will be copied to volsetid.
+ * @return 0 on success, -1 on error.
+ */
+int DVDUDFVolumeInfo( dvd_reader_t *, char *, unsigned int,
+ unsigned char *, unsigned int );
+
+/**
+ * Get the ISO9660 VolumeIdentifier and VolumeSetIdentifier
+ *
+ * * Only use this function as fallback if DVDUDFVolumeInfo returns 0 *
+ * * this will happen on a disc mastered only with a iso9660 filesystem *
+ * * All video DVD discs have UDF filesystem *
+ *
+ * @param dvd A read handle to get the disc ID from
+ * @param volid The buffer to put the VolumeIdentifier into.
+ * The VolumeIdentifier is coded with '0-9','A-Z','_'
+ * null terminated and max 33 bytes (including '\0')
+ * @param volid_size No more than volid_size bytes will be copied to volid.
+ * If the VolumeIdentifier is truncated because of this
+ * it will still be null terminated.
+ * @param volsetid The buffer to put the VolumeSetIdentifier into.
+ * The VolumeIdentifier is 128 bytes as
+ * stored in the ISO9660 PrimaryVolumeDescriptor.
+ * Note that this is not a null terminated string.
+ * @param volsetid_size At most volsetid_size bytes will be copied to volsetid.
+ * @return 0 on success, -1 on error.
+ */
+int DVDISOVolumeInfo( dvd_reader_t *, char *, unsigned int,
+ unsigned char *, unsigned int );
+
+/**
+ * Sets the level of caching that is done when reading from a device
+ *
+ * @param dvd A read handle to get the disc ID from
+ * @param level The level of caching wanted.
+ * -1 - returns the current setting.
+ * 0 - UDF Cache turned off.
+ * 1 - (default level) Pointers to IFO files and some data from
+ * PrimaryVolumeDescriptor are cached.
+ *
+ * @return The level of caching.
+ */
+int DVDUDFCacheLevel( dvd_reader_t *, int );
+
#ifdef __cplusplus
};
#endif
Index: dvd_udf.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/dvd_udf.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- dvd_udf.c 11 Mar 2005 02:40:28 -0000 1.5
+++ dvd_udf.c 30 Jun 2005 22:48:26 -0000 1.6
@@ -5,8 +5,6 @@
* Modifications by:
* Billy Biggs <vektor at dumbterm.net>.
* Björn Englund <d4bjorn at dtek.chalmers.se>.
- * Joey Parrish <joey at nicewarrior.org>.
- * - updated from libdvdread 0.9.4 and removed udf caching
*
* Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
* detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
@@ -34,10 +32,11 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#include "config.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-//#include <assert.h>
#ifndef __MINGW32__
#include <sys/ioctl.h>
#endif
@@ -50,7 +49,7 @@
#include "dvd_udf.h"
/* Private but located in/shared with dvd_reader.c */
-extern int DVDReadBlocksUDFRaw( dvd_reader_t *device, uint32_t lb_number,
+extern int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
size_t block_count, unsigned char *data,
int encrypted );
@@ -64,7 +63,7 @@
while(count > 0) {
- ret = DVDReadBlocksUDFRaw(device, lb_number, count, data, encrypted);
+ ret = UDFReadBlocksRaw(device, lb_number, count, data, encrypted);
if(ret <= 0) {
/* One of the reads failed or nothing more to read, too bad.
@@ -128,6 +127,201 @@
uint8_t filetype;
};
+struct udf_cache {
+ int avdp_valid;
+ struct avdp_t avdp;
+ int pvd_valid;
+ struct pvd_t pvd;
+ int partition_valid;
+ struct Partition partition;
+ int rooticb_valid;
+ struct AD rooticb;
+ int lb_num;
+ struct lbudf *lbs;
+ int map_num;
+ struct icbmap *maps;
+};
+
+typedef enum {
+ PartitionCache, RootICBCache, LBUDFCache, MapCache, AVDPCache, PVDCache
+} UDFCacheType;
+
+extern void *GetUDFCacheHandle(dvd_reader_t *device);
+extern void SetUDFCacheHandle(dvd_reader_t *device, void *cache);
+
+void FreeUDFCache(void *cache)
+{
+ struct udf_cache *c = (struct udf_cache *)cache;
+ if(c == NULL) {
+ return;
+ }
+ if(c->lbs) {
+ free(c->lbs);
+ }
+ if(c->maps) {
+ free(c->maps);
+ }
+ free(c);
+}
+
+
+static int GetUDFCache(dvd_reader_t *device, UDFCacheType type,
+ uint32_t nr, void *data)
+{
+ int n;
+ struct udf_cache *c;
+
+ if(DVDUDFCacheLevel(device, -1) <= 0) {
+ return 0;
+ }
+
+ c = (struct udf_cache *)GetUDFCacheHandle(device);
+
+ if(c == NULL) {
+ return 0;
+ }
+
+ switch(type) {
+ case AVDPCache:
+ if(c->avdp_valid) {
+ *(struct avdp_t *)data = c->avdp;
+ return 1;
+ }
+ break;
+ case PVDCache:
+ if(c->pvd_valid) {
+ *(struct pvd_t *)data = c->pvd;
+ return 1;
+ }
+ break;
+ case PartitionCache:
+ if(c->partition_valid) {
+ *(struct Partition *)data = c->partition;
+ return 1;
+ }
+ break;
+ case RootICBCache:
+ if(c->rooticb_valid) {
+ *(struct AD *)data = c->rooticb;
+ return 1;
+ }
+ break;
+ case LBUDFCache:
+ for(n = 0; n < c->lb_num; n++) {
+ if(c->lbs[n].lb == nr) {
+ *(uint8_t **)data = c->lbs[n].data;
+ return 1;
+ }
+ }
+ break;
+ case MapCache:
+ for(n = 0; n < c->map_num; n++) {
+ if(c->maps[n].lbn == nr) {
+ *(struct icbmap *)data = c->maps[n];
+ return 1;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int SetUDFCache(dvd_reader_t *device, UDFCacheType type,
+ uint32_t nr, void *data)
+{
+ int n;
+ struct udf_cache *c;
+
+ if(DVDUDFCacheLevel(device, -1) <= 0) {
+ return 0;
+ }
+
+ c = (struct udf_cache *)GetUDFCacheHandle(device);
+
+ if(c == NULL) {
+ c = calloc(1, sizeof(struct udf_cache));
+ // fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache));
+ if(c == NULL) {
+ return 0;
+ }
+ SetUDFCacheHandle(device, c);
+ }
+
+
+ switch(type) {
+ case AVDPCache:
+ c->avdp = *(struct avdp_t *)data;
+ c->avdp_valid = 1;
+ break;
+ case PVDCache:
+ c->pvd = *(struct pvd_t *)data;
+ c->pvd_valid = 1;
+ break;
+ case PartitionCache:
+ c->partition = *(struct Partition *)data;
+ c->partition_valid = 1;
+ break;
+ case RootICBCache:
+ c->rooticb = *(struct AD *)data;
+ c->rooticb_valid = 1;
+ break;
+ case LBUDFCache:
+ for(n = 0; n < c->lb_num; n++) {
+ if(c->lbs[n].lb == nr) {
+ /* replace with new data */
+ c->lbs[n].data = *(uint8_t **)data;
+ c->lbs[n].lb = nr;
+ return 1;
+ }
+ }
+ c->lb_num++;
+ c->lbs = realloc(c->lbs, c->lb_num * sizeof(struct lbudf));
+ /*
+ fprintf(stderr, "realloc lb: %d * %d = %d\n",
+ c->lb_num, sizeof(struct lbudf),
+ c->lb_num * sizeof(struct lbudf));
+ */
+ if(c->lbs == NULL) {
+ c->lb_num = 0;
+ return 0;
+ }
+ c->lbs[n].data = *(uint8_t **)data;
+ c->lbs[n].lb = nr;
+ break;
+ case MapCache:
+ for(n = 0; n < c->map_num; n++) {
+ if(c->maps[n].lbn == nr) {
+ /* replace with new data */
+ c->maps[n] = *(struct icbmap *)data;
+ c->maps[n].lbn = nr;
+ return 1;
+ }
+ }
+ c->map_num++;
+ c->maps = realloc(c->maps, c->map_num * sizeof(struct icbmap));
+ /*
+ fprintf(stderr, "realloc maps: %d * %d = %d\n",
+ c->map_num, sizeof(struct icbmap),
+ c->map_num * sizeof(struct icbmap));
+ */
+ if(c->maps == NULL) {
+ c->map_num = 0;
+ return 0;
+ }
+ c->maps[n] = *(struct icbmap *)data;
+ c->maps[n].lbn = nr;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+
/* For direct data access, LSB first */
#define GETN1(p) ((uint8_t)data[p])
#define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8))
@@ -302,8 +496,16 @@
uint8_t LogBlock[DVD_VIDEO_LB_LEN];
uint32_t lbnum;
uint16_t TagID;
+ struct icbmap tmpmap;
lbnum = partition->Start + ICB.Location;
+ tmpmap.lbn = lbnum;
+ if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) {
+ *FileType = tmpmap.filetype;
+ *File = tmpmap.file;
+ return 1;
+ }
+
do {
if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
TagID = 0;
@@ -313,6 +515,9 @@
if( TagID == 261 ) {
UDFFileEntry( LogBlock, FileType, partition, File );
+ tmpmap.file = *File;
+ tmpmap.filetype = *FileType;
+ SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap);
return 1;
};
} while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 )
@@ -328,7 +533,8 @@
* return 1 on success, 0 on error;
*/
static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
- struct Partition *partition, struct AD *FileICB )
+ struct Partition *partition, struct AD *FileICB,
+ int cache_file_info)
{
char filename[ MAX_UDF_FILE_NAME_LEN ];
uint8_t directory[ 2 * DVD_VIDEO_LB_LEN ];
@@ -336,9 +542,78 @@
uint16_t TagID;
uint8_t filechar;
unsigned int p;
+ uint8_t *cached_dir = NULL;
+ uint32_t dir_lba;
+ struct AD tmpICB;
+ int found = 0;
+ int in_cache = 0;
/* Scan dir for ICB of file */
lbnum = partition->Start + Dir.Location;
+
+ if(DVDUDFCacheLevel(device, -1) > 0) {
+ /* caching */
+
+ if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) {
+ dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN;
+ if((cached_dir = malloc(dir_lba * DVD_VIDEO_LB_LEN)) == NULL) {
+ return 0;
+ }
+ if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <= 0 ) {
+ free(cached_dir);
+ cached_dir = NULL;
+ }
+ /*
+ if(cached_dir) {
+ fprintf(stderr, "malloc dir: %d\n",
+ dir_lba * DVD_VIDEO_LB_LEN);
+ }
+ */
+ SetUDFCache(device, LBUDFCache, lbnum, &cached_dir);
+ } else {
+ in_cache = 1;
+ }
+
+ if(cached_dir == NULL) {
+ return 0;
+ }
+
+ p = 0;
+
+ while( p < Dir.Length ) {
+ UDFDescriptor( &cached_dir[ p ], &TagID );
+ if( TagID == 257 ) {
+ p += UDFFileIdentifier( &cached_dir[ p ], &filechar,
+ filename, &tmpICB );
+ if(cache_file_info && !in_cache) {
+ uint8_t tmpFiletype;
+ struct AD tmpFile;
+
+ if( !strcasecmp( FileName, filename ) ) {
+ *FileICB = tmpICB;
+ found = 1;
+
+ }
+ UDFMapICB(device, tmpICB, &tmpFiletype,
+ partition, &tmpFile);
+ } else {
+ if( !strcasecmp( FileName, filename ) ) {
+ *FileICB = tmpICB;
+ return 1;
+ }
+ }
+ } else {
+ if(cache_file_info && (!in_cache) && found) {
+ return 1;
+ }
+ return 0;
+ }
+ }
+ if(cache_file_info && (!in_cache) && found) {
+ return 1;
+ }
+ return 0;
+ }
if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {
return 0;
@@ -380,6 +655,10 @@
int terminate;
struct avdp_t;
+ if(GetUDFCache(device, AVDPCache, 0, avdp)) {
+ return 1;
+ }
+
/* Find Anchor */
lastsector = 0;
lbnum = 256; /* Try #1, prime anchor */
@@ -427,6 +706,8 @@
avdp->rvds.location = MVDS_location;
avdp->rvds.length = MVDS_length;
+ SetUDFCache(device, AVDPCache, 0, avdp);
+
return 1;
}
@@ -514,8 +795,11 @@
strcat( tokenline, filename );
+ if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&
+ GetUDFCache(device, RootICBCache, 0, &RootICB))) {
/* Find partition, 0 is the standard location for DVD Video.*/
if( !UDFFindPartition( device, 0, &partition ) ) return 0;
+ SetUDFCache(device, PartitionCache, 0, &partition);
/* Find root dir ICB */
lbnum = partition.Start;
@@ -536,23 +820,30 @@
/* Sanity checks. */
if( TagID != 256 ) return 0;
if( RootICB.Partition != 0 ) return 0;
+ SetUDFCache(device, RootICBCache, 0, &RootICB);
+ }
/* Find root dir */
if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) return 0;
if( filetype != 4 ) return 0; /* Root dir should be dir */
{
+ int cache_file_info = 0;
/* Tokenize filepath */
token = strtok(tokenline, "/");
while( token != NULL ) {
- if( !UDFScanDir( device, File, token, &partition, &ICB)) {
+ if( !UDFScanDir( device, File, token, &partition, &ICB,
+ cache_file_info)) {
return 0;
}
if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {
return 0;
}
+ if(!strcmp(token, "VIDEO_TS")) {
+ cache_file_info = 1;
+ }
token = strtok( NULL, "/" );
}
}
@@ -636,12 +927,76 @@
{
uint8_t pvd_buf[DVD_VIDEO_LB_LEN];
+ if(GetUDFCache(device, PVDCache, 0, pvd)) {
+ return 1;
+ }
+
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);
+ SetUDFCache(device, PVDCache, 0, pvd);
return 1;
}
+
+/**
+ * Gets the Volume Identifier string, in 8bit unicode (latin-1)
+ * volid, place to put the string
+ * volid_size, size of the buffer volid points to
+ * returns the size of buffer needed for all data
+ */
+int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid,
+ unsigned int volid_size)
+{
+ struct pvd_t pvd;
+ unsigned int volid_len;
+
+ /* get primary volume descriptor */
+ if(!UDFGetPVD(device, &pvd)) {
+ return 0;
+ }
+
+ volid_len = pvd.VolumeIdentifier[31];
+ if(volid_len > 31) {
+ /* this field is only 32 bytes something is wrong */
+ volid_len = 31;
+ }
+ if(volid_size > volid_len) {
+ volid_size = volid_len;
+ }
+ Unicodedecode(pvd.VolumeIdentifier, volid_size, volid);
+
+ return volid_len;
+}
+
+/**
+ * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded)
+ * WARNING This is not a null terminated string
+ * volsetid, place to put the data
+ * volsetid_size, size of the buffer volsetid points to
+ * the buffer should be >=128 bytes to store the whole volumesetidentifier
+ * returns the size of the available volsetid information (128)
+ * or 0 on error
+ */
+int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid,
+ unsigned int volsetid_size)
+{
+ struct pvd_t pvd;
+
+ /* get primary volume descriptor */
+ if(!UDFGetPVD(device, &pvd)) {
+ return 0;
+ }
+
+
+ if(volsetid_size > 128) {
+ volsetid_size = 128;
+ }
+
+ memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size);
+
+ return 128;
+}
Index: dvd_udf.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/dvd_udf.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- dvd_udf.h 16 Aug 2002 22:37:48 -0000 1.1
+++ dvd_udf.h 30 Jun 2005 22:48:26 -0000 1.2
@@ -7,7 +7,8 @@
*
* Modifications by:
* Billy Biggs <vektor at dumbterm.net>.
- *
+ * Björn Englund <d4bjorn at dtek.chalmers.se>.
+ *
* dvdudf: parse and read the UDF volume information of a DVD Video
* Copyright (C) 1999 Christian Wolff for convergence integrated media
* GmbH The author can be reached at scarabaeus at convergence.de, the
@@ -47,6 +48,11 @@
*/
uint32_t UDFFindFile( dvd_reader_t *device, char *filename, uint32_t *size );
+void FreeUDFCache(void *cache);
+int UDFGetVolumeIdentifier(dvd_reader_t *device,
+ char *volid, unsigned int volid_size);
+int UDFGetVolumeSetIdentifier(dvd_reader_t *device,
+ uint8_t *volsetid, unsigned int volsetid_size);
#ifdef __cplusplus
};
#endif
Index: ifo_print.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/ifo_print.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ifo_print.c 11 Mar 2005 02:40:28 -0000 1.3
+++ ifo_print.c 30 Jun 2005 22:48:26 -0000 1.4
@@ -1,10 +1,7 @@
/*
- * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn at dtek.chalmers.se>,
- * Håkan Hjort <d95hjort at dtek.chalmers.se>
- *
- * Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
- * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
- * $Id$
+ * Copyright (C) 2000, 2001, 2002, 2003
+ * Björn Englund <d4bjorn at dtek.chalmers.se>,
+ * Håkan Hjort <d95hjort at dtek.chalmers.se>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,26 +18,27 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <string.h>
#include <ctype.h>
-//#include <assert.h>
-#include "config.h" // Needed for WORDS_BIGENDIAN
#include "ifo_types.h"
#include "ifo_read.h"
#include "ifo_print.h"
+#include "dvdread_internal.h"
/* Put this in some other file / package? It's used in nav_print too. */
-static void ifoPrint_time(int level, dvd_time_t *dtime) {
+static void ifoPrint_time(dvd_time_t *dtime) {
const char *rate;
- assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
- assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
- assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
- assert((dtime->frame_u&0xf) < 0xa);
+ CHECK_VALUE((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
+ CHECK_VALUE((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
+ CHECK_VALUE((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
+ CHECK_VALUE((dtime->frame_u&0xf) < 0xa);
printf("%02x:%02x:%02x.%02x",
dtime->hour,
@@ -79,7 +77,7 @@
printf("\n");
}
-static void ifoPrint_video_attributes(int level, video_attr_t *attr) {
+static void ifoPrint_video_attributes(video_attr_t *attr) {
/* The following test is shorter but not correct ISO C,
memcmp(attr,my_friendly_zeros, sizeof(video_attr_t)) */
@@ -90,6 +88,7 @@
&& attr->unknown1 == 0
&& attr->line21_cc_1 == 0
&& attr->line21_cc_2 == 0
+ && attr->bit_rate == 0
&& attr->video_format == 0
&& attr->letterboxed == 0
&& attr->film_mode == 0) {
@@ -149,7 +148,7 @@
}
printf("U%x ", attr->unknown1);
- assert(!attr->unknown1);
+ CHECK_VALUE(!attr->unknown1);
if(attr->line21_cc_1 || attr->line21_cc_2) {
printf("NTSC CC ");
@@ -158,6 +157,17 @@
if(attr->line21_cc_2)
printf("2 ");
}
+
+ switch(attr->bit_rate) {
+ case 0:
+ printf("Variable Bit Rate ");
+ break;
+ case 1:
+ printf("Constant Bit Rate ");
+ break;
+ default:
+ printf("(please send a bug report)");
+ }
{
int height = 480;
@@ -192,7 +202,7 @@
}
}
-static void ifoPrint_audio_attributes(int level, audio_attr_t *attr) {
+static void ifoPrint_audio_attributes(audio_attr_t *attr) {
if(attr->audio_format == 0
&& attr->multichannel_extension == 0
@@ -201,8 +211,10 @@
&& attr->quantization == 0
&& attr->sample_frequency == 0
&& attr->channels == 0
+ && attr->lang_code == 0
&& attr->lang_extension == 0
- && attr->unknown1 == 0
+ && attr->code_extension == 0
+ && attr->unknown3 == 0
&& attr->unknown1 == 0) {
printf("-- Unspecified --");
return;
@@ -240,10 +252,11 @@
switch(attr->lang_type) {
case 0:
// not specified
- assert(attr->lang_code == 0 || attr->lang_code == 0xffff);
+ CHECK_VALUE(attr->lang_code == 0 || attr->lang_code == 0xffff);
break;
case 1:
- printf("%c%c ", attr->lang_code>>8, attr->lang_code & 0xff);
+ printf("%c%c (%c) ", attr->lang_code>>8, attr->lang_code & 0xff,
+ attr->lang_extension ? attr->lang_extension : ' ');
break;
default:
printf("(please send a bug report) ");
@@ -294,7 +307,7 @@
printf("%dCh ", attr->channels + 1);
- switch(attr->lang_extension) {
+ switch(attr->code_extension) {
case 0:
printf("Not specified ");
break;
@@ -315,34 +328,64 @@
printf("(please send a bug report) ");
}
- printf("%d ", attr->unknown1);
- printf("%d ", attr->unknown2);
+ printf("%d ", attr->unknown3);
+ if(attr->application_mode == 1) {
+ printf("ca=%d ", attr->app_info.karaoke.channel_assignment);
+ printf("%d ", attr->app_info.karaoke.version);
+ if(attr->app_info.karaoke.mc_intro)
+ printf("mc intro ");
+ printf("%s ", attr->app_info.karaoke.mode ? "duet" : "solo");
+ printf("%d ", attr->app_info.karaoke.unknown4);
+ }
+ if(attr->application_mode == 2) {
+ if(attr->app_info.surround.dolby_encoded) {
+ printf("dolby surround ");
+ }
+ printf("%d ", attr->app_info.surround.unknown5);
+ printf("%d ", attr->app_info.surround.unknown6);
+ }
}
-static void ifoPrint_subp_attributes(int level, subp_attr_t *attr) {
+static void ifoPrint_subp_attributes(subp_attr_t *attr) {
if(attr->type == 0
+ && attr->code_mode == 0
&& attr->lang_code == 0
+ && attr->lang_extension == 0
&& attr->zero1 == 0
&& attr->zero2 == 0
- && attr->lang_extension== 0) {
+ && attr->code_extension == 0) {
printf("-- Unspecified --");
return;
}
- printf("type %02x ", attr->type);
-
- if(isalpha((int)(attr->lang_code >> 8))
- && isalpha((int)(attr->lang_code & 0xff))) {
- printf("%c%c ", attr->lang_code >> 8, attr->lang_code & 0xff);
+ switch(attr->code_mode) {
+ case 0:
+ printf("Coding Mode RLE ");
+ break;
+ case 1:
+ printf("Coding Mode Extended ");
+ break;
+ default:
+ printf("(please send a bug report) ");
+ }
+
+ if(attr->type == 1) {
+ if(isalpha((int)(attr->lang_code >> 8))
+ && isalpha((int)(attr->lang_code & 0xff))) {
+ printf("%c%c ", attr->lang_code >> 8, attr->lang_code & 0xff);
+ } else {
+ printf("%02x%02x ", attr->lang_code >> 8, attr->lang_code & 0xff);
+ }
} else {
- printf("%02x%02x ", 0xff & (unsigned)(attr->lang_code >> 8),
- 0xff & (unsigned)(attr->lang_code & 0xff));
+ printf("lang not specified ");
}
printf("%d ", attr->zero1);
printf("%d ", attr->zero2);
-
+ printf("%d ", attr->code_extension);
+
+ /* Is this correct? should it not be subp_code_ext here instead? */
switch(attr->lang_extension) {
case 0:
printf("Not specified ");
@@ -498,20 +541,20 @@
printf("Start sector of VMGM_VOBU_ADMAP: %08x\n",
vmgi_mat->vmgm_vobu_admap);
printf("Video attributes of VMGM_VOBS: ");
- ifoPrint_video_attributes(5, &vmgi_mat->vmgm_video_attr);
+ ifoPrint_video_attributes(&vmgi_mat->vmgm_video_attr);
printf("\n");
printf("VMGM Number of Audio attributes: %i\n",
vmgi_mat->nr_of_vmgm_audio_streams);
if(vmgi_mat->nr_of_vmgm_audio_streams > 0) {
printf("\tstream %i status: ", 1);
- ifoPrint_audio_attributes(5, &vmgi_mat->vmgm_audio_attr);
+ ifoPrint_audio_attributes(&vmgi_mat->vmgm_audio_attr);
printf("\n");
}
printf("VMGM Number of Sub-picture attributes: %i\n",
vmgi_mat->nr_of_vmgm_subp_streams);
if(vmgi_mat->nr_of_vmgm_subp_streams > 0) {
printf("\tstream %2i status: ", 1);
- ifoPrint_subp_attributes(5, &vmgi_mat->vmgm_subp_attr);
+ ifoPrint_subp_attributes(&vmgi_mat->vmgm_subp_attr);
printf("\n");
}
}
@@ -540,14 +583,14 @@
printf("Start sector of VTS_VOBU_ADMAP: %08x\n", vtsi_mat->vts_vobu_admap);
printf("Video attributes of VTSM_VOBS: ");
- ifoPrint_video_attributes(5, &vtsi_mat->vtsm_video_attr);
+ ifoPrint_video_attributes(&vtsi_mat->vtsm_video_attr);
printf("\n");
printf("VTSM Number of Audio attributes: %i\n",
vtsi_mat->nr_of_vtsm_audio_streams);
if(vtsi_mat->nr_of_vtsm_audio_streams > 0) {
printf("\tstream %i status: ", 1);
- ifoPrint_audio_attributes(5, &vtsi_mat->vtsm_audio_attr);
+ ifoPrint_audio_attributes(&vtsi_mat->vtsm_audio_attr);
printf("\n");
}
@@ -555,19 +598,19 @@
vtsi_mat->nr_of_vtsm_subp_streams);
if(vtsi_mat->nr_of_vtsm_subp_streams > 0) {
printf("\tstream %2i status: ", 1);
- ifoPrint_subp_attributes(5, &vtsi_mat->vtsm_subp_attr);
+ ifoPrint_subp_attributes(&vtsi_mat->vtsm_subp_attr);
printf("\n");
}
printf("Video attributes of VTS_VOBS: ");
- ifoPrint_video_attributes(5, &vtsi_mat->vts_video_attr);
+ ifoPrint_video_attributes(&vtsi_mat->vts_video_attr);
printf("\n");
printf("VTS Number of Audio attributes: %i\n",
vtsi_mat->nr_of_vts_audio_streams);
for(i = 0; i < vtsi_mat->nr_of_vts_audio_streams; i++) {
printf("\tstream %i status: ", i);
- ifoPrint_audio_attributes(5, &vtsi_mat->vts_audio_attr[i]);
+ ifoPrint_audio_attributes(&vtsi_mat->vts_audio_attr[i]);
printf("\n");
}
@@ -575,9 +618,11 @@
vtsi_mat->nr_of_vts_subp_streams);
for(i = 0; i < vtsi_mat->nr_of_vts_subp_streams; i++) {
printf("\tstream %2i status: ", i);
- ifoPrint_subp_attributes(5, &vtsi_mat->vts_subp_attr[i]);
+ ifoPrint_subp_attributes(&vtsi_mat->vts_subp_attr[i]);
printf("\n");
}
+
+ /* FIXME: Add printing of MultiChannel Extension */
}
@@ -631,7 +676,7 @@
for(i=0;i<nr;i++) {
printf("Cell: %3i ", i + 1);
- ifoPrint_time(5, &cell_playback[i].playback_time);
+ ifoPrint_time(&cell_playback[i].playback_time);
printf("\t");
if(cell_playback[i].block_mode || cell_playback[i].block_type) {
@@ -709,7 +754,7 @@
printf("Number of Cells: %i\n", pgc->nr_of_cells);
/* Check that time is 0:0:0:0 also if nr_of_programs==0 */
printf("Playback time: ");
- ifoPrint_time(5, &pgc->playback_time); printf("\n");
+ ifoPrint_time(&pgc->playback_time); printf("\n");
/* If no programs/no time then does this mean anything? */
printf("Prohibited user operations: ");
@@ -734,7 +779,12 @@
printf("GoUp PGC number: %i\n", pgc->goup_pgc_nr);
if(pgc->nr_of_programs != 0) {
printf("Still time: %i seconds (255=inf)\n", pgc->still_time);
- printf("PG Playback mode %02x\n", pgc->pg_playback_mode);
+ if(pgc->pg_playback_mode == 0)
+ printf("PG Playback mode: Sequential\n");
+ else if(!(pgc->pg_playback_mode & 0x80))
+ printf("PG Playback mode: Random %i\n", pgc->pg_playback_mode);
+ else
+ printf("PG Playback mode: Shuffle %i\n", pgc->pg_playback_mode & 0x7f );
}
if(pgc->nr_of_programs != 0) {
@@ -764,8 +814,23 @@
printf("\tNumber of PTTs: %i\n", tt_srpt->title[i].nr_of_ptts);
printf("\tNumber of angles: %i\n",
tt_srpt->title[i].nr_of_angles);
- printf("\tTitle playback type: %02x\n", /* XXX: TODO FIXME */
- *(uint8_t *)&(tt_srpt->title[i].pb_ty));
+ printf("\tTitle playback type: %s%s%s%s%s%s%s\n",
+ tt_srpt->title[i].pb_ty.multi_or_random_pgc_title ?
+ " One Random PGC Title or Multi PGC Title" :
+ " One Sequential PGC Title",
+ tt_srpt->title[i].pb_ty.jlc_exists_in_cell_cmd ?
+ "" : ", No Link/Jump/Call exists in Cell command",
+ tt_srpt->title[i].pb_ty.jlc_exists_in_prepost_cmd ?
+ "" : ", No Link/Jump/Call exists in Pre- and/or Post-command",
+ tt_srpt->title[i].pb_ty.jlc_exists_in_button_cmd ?
+ "" : ", No Link/Jump/Call exists in Button command",
+ tt_srpt->title[i].pb_ty.jlc_exists_in_tt_dom ?
+ "" : ", No Link/Jump/Call exists in TT_DOM",
+ tt_srpt->title[i].pb_ty.chapter_search_or_play ?
+ ", UOP1 (TT_Play and PTT_Search) prohibited" : "",
+ tt_srpt->title[i].pb_ty.title_or_time_play ?
+ ", UOP0 (Time_Play and Time_Search) prohibited" : ""
+ );
printf("\tParental ID field: %04x\n",
tt_srpt->title[i].parental_id);
printf("\tTitle set starting sector %08x\n",
@@ -780,6 +845,8 @@
vts_ptt_srpt->nr_of_srpts,
vts_ptt_srpt->last_byte);
for(i=0;i<vts_ptt_srpt->nr_of_srpts;i++) {
+ printf("\nVTS_PTT number %d has a offset %d relative to VTS_PTT_SRPT\n",
+ i + 1, vts_ptt_srpt->ttu_offset[i]);
for(j=0;j<vts_ptt_srpt->title[i].nr_of_ptts;j++) {
printf("VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n",
i + 1, j + 1,
@@ -790,40 +857,57 @@
}
-static void hexdump(uint8_t *ptr, int len) {
- while(len--)
- printf("%02x ", *ptr++);
-}
-
void ifoPrint_PTL_MAIT(ptl_mait_t *ptl_mait) {
- int i, j;
+ int i, level, vts;
printf("Number of Countries: %i\n", ptl_mait->nr_of_countries);
printf("Number of VTSs: %i\n", ptl_mait->nr_of_vtss);
- //printf("Last byte: %i\n", ptl_mait->last_byte);
+ printf("Last byte: %i\n", ptl_mait->last_byte);
for(i = 0; i < ptl_mait->nr_of_countries; i++) {
- printf("Country code: %c%c\n",
+
+ printf("Start byte: %i\n", ptl_mait->countries[i].pf_ptl_mai_start_byte);
+ printf("Parental Masks for country: %c%c\n",
ptl_mait->countries[i].country_code >> 8,
ptl_mait->countries[i].country_code & 0xff);
- /*
- printf("Start byte: %04x %i\n",
- ptl_mait->countries[i].pf_ptl_mai_start_byte,
- ptl_mait->countries[i].pf_ptl_mai_start_byte);
- */
- /* This seems to be pointing at a array with 8 2byte fields per VTS
- ? and one extra for the menu? always an odd number of VTSs on
- all the dics I tested so it might be padding to even also.
- If it is for the menu it probably the first entry. */
- for(j=0;j<8;j++) {
- hexdump( (uint8_t *)ptl_mait->countries - PTL_MAIT_COUNTRY_SIZE
- + ptl_mait->countries[i].pf_ptl_mai_start_byte
- + j*(ptl_mait->nr_of_vtss+1)*2, (ptl_mait->nr_of_vtss+1)*2);
+
+ for(vts = 0; vts <= ptl_mait->nr_of_vtss; vts++) {
+ if( vts == 0 ) {
+ printf("VMG ");
+ } else {
+ printf("VTS %2d ", vts);
+ }
+ for(level = 0; level < 8; level++) {
+ printf("%d: %04x ", level,
+ ptl_mait->countries[i].pf_ptl_mai[vts][level] );
+ }
printf("\n");
}
}
}
+void ifoPrint_VTS_TMAPT(vts_tmapt_t *vts_tmapt) {
+ unsigned int timeunit;
+ int i, j;
+
+ printf("Number of VTS_TMAPS: %i\n", vts_tmapt->nr_of_tmaps);
+ printf("Last byte: %i\n", vts_tmapt->last_byte);
+
+ for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
+ printf("TMAP %i\n", i + 1);
+ printf(" offset %d relative to VTS_TMAPTI\n", vts_tmapt->tmap_offset[i]);
+ printf(" Time unit (seconds): %i\n", vts_tmapt->tmap[i].tmu);
+ printf(" Number of entries: %i\n", vts_tmapt->tmap[i].nr_of_entries);
+ timeunit = vts_tmapt->tmap[i].tmu;
+ for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) {
+ unsigned int ac_time = timeunit * (j + 1);
+ printf("Time: %2i:%02i:%02i VOBU Sector: 0x%08x %s\n",
+ ac_time / (60 * 60), (ac_time / 60) % 60, ac_time % 60,
+ vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff,
+ (vts_tmapt->tmap[i].map_ent[j] >> 31) ? "discontinuity" : "");
+ }
+ }
+}
void ifoPrint_C_ADT(c_adt_t *c_adt) {
int i, entries;
@@ -870,9 +954,10 @@
printf("Number of Menu Language Units (PGCI_LU): %3i\n", pgci_ut->nr_of_lus);
for(i = 0; i < pgci_ut->nr_of_lus; i++) {
- printf("\nMenu Language Code: %c%c\n",
+ printf("\nMenu Language Code: %c%c (%c)\n",
pgci_ut->lu[i].lang_code >> 8,
- pgci_ut->lu[i].lang_code & 0xff);
+ pgci_ut->lu[i].lang_code & 0xff,
+ pgci_ut->lu[i].lang_extension ? pgci_ut->lu[i].lang_extension :' ');
printf("Menu Existence: %02x\n", pgci_ut->lu[i].exists);
ifoPrint_PGCIT(pgci_ut->lu[i].pgcit);
}
@@ -885,31 +970,31 @@
printf("VTS_CAT Application type: %08x\n", vts_attributes->vts_cat);
printf("Video attributes of VTSM_VOBS: ");
- ifoPrint_video_attributes(5, &vts_attributes->vtsm_vobs_attr);
+ ifoPrint_video_attributes(&vts_attributes->vtsm_vobs_attr);
printf("\n");
printf("Number of Audio streams: %i\n",
vts_attributes->nr_of_vtsm_audio_streams);
if(vts_attributes->nr_of_vtsm_audio_streams > 0) {
printf("\tstream %i attributes: ", 1);
- ifoPrint_audio_attributes(5, &vts_attributes->vtsm_audio_attr);
+ ifoPrint_audio_attributes(&vts_attributes->vtsm_audio_attr);
printf("\n");
}
printf("Number of Subpicture streams: %i\n",
vts_attributes->nr_of_vtsm_subp_streams);
if(vts_attributes->nr_of_vtsm_subp_streams > 0) {
printf("\tstream %2i attributes: ", 1);
- ifoPrint_subp_attributes(5, &vts_attributes->vtsm_subp_attr);
+ ifoPrint_subp_attributes(&vts_attributes->vtsm_subp_attr);
printf("\n");
}
printf("Video attributes of VTSTT_VOBS: ");
- ifoPrint_video_attributes(5, &vts_attributes->vtstt_vobs_video_attr);
+ ifoPrint_video_attributes(&vts_attributes->vtstt_vobs_video_attr);
printf("\n");
printf("Number of Audio streams: %i\n",
vts_attributes->nr_of_vtstt_audio_streams);
for(i = 0; i < vts_attributes->nr_of_vtstt_audio_streams; i++) {
printf("\tstream %i attributes: ", i);
- ifoPrint_audio_attributes(5, &vts_attributes->vtstt_audio_attr[i]);
+ ifoPrint_audio_attributes(&vts_attributes->vtstt_audio_attr[i]);
printf("\n");
}
@@ -917,7 +1002,7 @@
vts_attributes->nr_of_vtstt_subp_streams);
for(i = 0; i < vts_attributes->nr_of_vtstt_subp_streams; i++) {
printf("\tstream %2i attributes: ", i);
- ifoPrint_subp_attributes(5, &vts_attributes->vtstt_subp_attr[i]);
+ ifoPrint_subp_attributes(&vts_attributes->vtstt_subp_attr[i]);
printf("\n");
}
}
@@ -929,6 +1014,8 @@
printf("Number of Video Title Sets: %3i\n", vts_atrt->nr_of_vtss);
for(i = 0; i < vts_atrt->nr_of_vtss; i++) {
printf("\nVideo Title Set %i\n", i + 1);
+ printf(" offset %d relative to VMG_VTS_ATRT\n",
+ vts_atrt->vts_atrt_offsets[i]);
ifoPrint_VTS_ATTRIBUTES(&vts_atrt->vts[i]);
}
}
@@ -1022,6 +1109,14 @@
} else {
printf("No Menu PGCI Unit table present\n");
}
+
+ printf("\nTime Search table\n");
+ printf( "-----------------\n");
+ if(ifohandle->vts_tmapt) {
+ ifoPrint_VTS_TMAPT(ifohandle->vts_tmapt);
+ } else {
+ printf("No Time Search table present\n");
+ }
printf("\nMenu Cell Adress table\n");
printf( "-----------------\n");
Index: ifo_print.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/ifo_print.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ifo_print.h 11 Mar 2005 02:40:28 -0000 1.3
+++ ifo_print.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -53,6 +53,7 @@
void ifoPrint_PGC(pgc_t *);
void ifoPrint_PGCIT(pgcit_t *);
void ifoPrint_PGCI_UT(pgci_ut_t *);
+void ifoPrint_VTS_TMAPT(vts_tmapt_t *);
void ifoPrint_C_ADT(c_adt_t *);
void ifoPrint_VOBU_ADMAP(vobu_admap_t *);
Index: ifo_read.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/ifo_read.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ifo_read.c 11 Mar 2005 02:40:28 -0000 1.3
+++ ifo_read.c 30 Jun 2005 22:48:26 -0000 1.4
@@ -1,10 +1,7 @@
/*
- * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn at dtek.chalmers.se>,
- * Håkan Hjort <d95hjort at dtek.chalmers.se>
- *
- * Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
- * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
- * $Id$
+ * Copyright (C) 2000, 2001, 2002, 2003
+ * Björn Englund <d4bjorn at dtek.chalmers.se>,
+ * Håkan Hjort <d95hjort at dtek.chalmers.se>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,25 +18,29 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
+
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <inttypes.h>
#include <string.h>
-//#include <assert.h>
-
-#include "dvd_reader.h"
-#include "config.h" // Needed for WORDS_BIGENDIAN
#include "bswap.h"
#include "ifo_types.h"
#include "ifo_read.h"
+#include "dvd_reader.h"
+#include "dvdread_internal.h"
#ifndef DVD_BLOCK_LEN
#define DVD_BLOCK_LEN 2048
#endif
#ifndef NDEBUG
+#define CHECK_ZERO0(arg) \
+ if(arg != 0) { \
+ fprintf(stderr, "*** Zero check failed in %s:%i\n for %s = 0x%x\n", \
+ __FILE__, __LINE__, # arg, arg); \
+ }
#define CHECK_ZERO(arg) \
if(memcmp(my_friendly_zeros, &arg, sizeof(arg))) { \
unsigned int i_CZ; \
@@ -51,6 +52,7 @@
}
static const uint8_t my_friendly_zeros[2048];
#else
+#define CHECK_ZERO0(arg) (void)(arg)
#define CHECK_ZERO(arg) (void)(arg)
#endif
@@ -87,7 +89,7 @@
static void ifoFree_PGCIT_internal(pgcit_t *pgcit);
-static int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) {
+static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) {
return (DVDFileSeek(dvd_file, (int)offset) == (int)offset);
}
@@ -102,6 +104,8 @@
memset(ifofile, 0, sizeof(ifo_handle_t));
ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
+ if(!ifofile->file) /* Should really catch any error and try to fallback */
+ ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
if(!ifofile->file) {
if(title) {
fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title);
@@ -150,6 +154,7 @@
ifoRead_PGCI_UT(ifofile);
+ ifoRead_VTS_TMAPT(ifofile);
ifoRead_C_ADT(ifofile);
ifoRead_VOBU_ADMAP(ifofile);
@@ -184,6 +189,8 @@
memset(ifofile, 0, sizeof(ifo_handle_t));
ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_FILE);
+ if(!ifofile->file) /* Should really catch any error and try to fallback */
+ ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_BACKUP_FILE);
if(!ifofile->file) {
fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n");
free(ifofile);
@@ -215,6 +222,8 @@
}
ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE);
+ if(!ifofile->file) /* Should really catch any error and try to fallback */
+ ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE);
if(!ifofile->file) {
fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title);
free(ifofile);
@@ -320,33 +329,33 @@
CHECK_ZERO(vmgi_mat->zero_8);
CHECK_ZERO(vmgi_mat->zero_9);
CHECK_ZERO(vmgi_mat->zero_10);
- assert(vmgi_mat->vmg_last_sector != 0);
- assert(vmgi_mat->vmgi_last_sector != 0);
- assert(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector);
- assert(vmgi_mat->vmg_nr_of_volumes != 0);
- assert(vmgi_mat->vmg_this_volume_nr != 0);
- assert(vmgi_mat->vmg_this_volume_nr <= vmgi_mat->vmg_nr_of_volumes);
- assert(vmgi_mat->disc_side == 1 || vmgi_mat->disc_side == 2);
- assert(vmgi_mat->vmg_nr_of_title_sets != 0);
- assert(vmgi_mat->vmgi_last_byte >= 341);
- assert(vmgi_mat->vmgi_last_byte / DVD_BLOCK_LEN <=
+ CHECK_VALUE(vmgi_mat->vmg_last_sector != 0);
+ CHECK_VALUE(vmgi_mat->vmgi_last_sector != 0);
+ CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector);
+ CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector);
+ CHECK_VALUE(vmgi_mat->vmg_nr_of_volumes != 0);
+ CHECK_VALUE(vmgi_mat->vmg_this_volume_nr != 0);
+ CHECK_VALUE(vmgi_mat->vmg_this_volume_nr <= vmgi_mat->vmg_nr_of_volumes);
+ CHECK_VALUE(vmgi_mat->disc_side == 1 || vmgi_mat->disc_side == 2);
+ CHECK_VALUE(vmgi_mat->vmg_nr_of_title_sets != 0);
+ CHECK_VALUE(vmgi_mat->vmgi_last_byte >= 341);
+ CHECK_VALUE(vmgi_mat->vmgi_last_byte / DVD_BLOCK_LEN <=
vmgi_mat->vmgi_last_sector);
- /* It seems that first_play_pgc might be optional. */
- assert(vmgi_mat->first_play_pgc != 0 &&
- vmgi_mat->first_play_pgc < vmgi_mat->vmgi_last_byte);
- assert(vmgi_mat->vmgm_vobs == 0 ||
+ /* It seems that first_play_pgc is optional. */
+ CHECK_VALUE(vmgi_mat->first_play_pgc < vmgi_mat->vmgi_last_byte);
+ CHECK_VALUE(vmgi_mat->vmgm_vobs == 0 ||
(vmgi_mat->vmgm_vobs > vmgi_mat->vmgi_last_sector &&
vmgi_mat->vmgm_vobs < vmgi_mat->vmg_last_sector));
- assert(vmgi_mat->tt_srpt <= vmgi_mat->vmgi_last_sector);
- assert(vmgi_mat->vmgm_pgci_ut <= vmgi_mat->vmgi_last_sector);
- assert(vmgi_mat->ptl_mait <= vmgi_mat->vmgi_last_sector);
- assert(vmgi_mat->vts_atrt <= vmgi_mat->vmgi_last_sector);
- assert(vmgi_mat->txtdt_mgi <= vmgi_mat->vmgi_last_sector);
- assert(vmgi_mat->vmgm_c_adt <= vmgi_mat->vmgi_last_sector);
- assert(vmgi_mat->vmgm_vobu_admap <= vmgi_mat->vmgi_last_sector);
+ CHECK_VALUE(vmgi_mat->tt_srpt <= vmgi_mat->vmgi_last_sector);
+ CHECK_VALUE(vmgi_mat->vmgm_pgci_ut <= vmgi_mat->vmgi_last_sector);
+ CHECK_VALUE(vmgi_mat->ptl_mait <= vmgi_mat->vmgi_last_sector);
+ CHECK_VALUE(vmgi_mat->vts_atrt <= vmgi_mat->vmgi_last_sector);
+ CHECK_VALUE(vmgi_mat->txtdt_mgi <= vmgi_mat->vmgi_last_sector);
+ CHECK_VALUE(vmgi_mat->vmgm_c_adt <= vmgi_mat->vmgi_last_sector);
+ CHECK_VALUE(vmgi_mat->vmgm_vobu_admap <= vmgi_mat->vmgi_last_sector);
- assert(vmgi_mat->nr_of_vmgm_audio_streams <= 1);
- assert(vmgi_mat->nr_of_vmgm_subp_streams <= 1);
+ CHECK_VALUE(vmgi_mat->nr_of_vmgm_audio_streams <= 1);
+ CHECK_VALUE(vmgi_mat->nr_of_vmgm_subp_streams <= 1);
return 1;
}
@@ -422,34 +431,44 @@
CHECK_ZERO(vtsi_mat->zero_18);
CHECK_ZERO(vtsi_mat->zero_19);
CHECK_ZERO(vtsi_mat->zero_20);
- assert(vtsi_mat->vtsi_last_sector*2 <= vtsi_mat->vts_last_sector);
- assert(vtsi_mat->vtsi_last_byte/DVD_BLOCK_LEN <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->vtsm_vobs == 0 ||
- (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector &&
+ CHECK_ZERO(vtsi_mat->zero_21);
+ CHECK_VALUE(vtsi_mat->vtsi_last_sector*2 <= vtsi_mat->vts_last_sector);
+ CHECK_VALUE(vtsi_mat->vtsi_last_byte/DVD_BLOCK_LEN <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vtsm_vobs == 0 ||
+ (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector &&
vtsi_mat->vtsm_vobs < vtsi_mat->vts_last_sector));
- assert(vtsi_mat->vtstt_vobs == 0 ||
+ CHECK_VALUE(vtsi_mat->vtstt_vobs == 0 ||
(vtsi_mat->vtstt_vobs > vtsi_mat->vtsi_last_sector &&
vtsi_mat->vtstt_vobs < vtsi_mat->vts_last_sector));
- assert(vtsi_mat->vts_ptt_srpt <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->vts_pgcit <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->vtsm_pgci_ut <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->vts_tmapt <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->vtsm_c_adt <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->vtsm_vobu_admap <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->vts_c_adt <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->vts_vobu_admap <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vts_ptt_srpt <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vts_pgcit <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vtsm_pgci_ut <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vts_tmapt <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vtsm_c_adt <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vtsm_vobu_admap <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vts_c_adt <= vtsi_mat->vtsi_last_sector);
+ CHECK_VALUE(vtsi_mat->vts_vobu_admap <= vtsi_mat->vtsi_last_sector);
- assert(vtsi_mat->nr_of_vtsm_audio_streams <= 1);
- assert(vtsi_mat->nr_of_vtsm_subp_streams <= 1);
+ CHECK_VALUE(vtsi_mat->nr_of_vtsm_audio_streams <= 1);
+ CHECK_VALUE(vtsi_mat->nr_of_vtsm_subp_streams <= 1);
- assert(vtsi_mat->nr_of_vts_audio_streams <= 8);
+ CHECK_VALUE(vtsi_mat->nr_of_vts_audio_streams <= 8);
for(i = vtsi_mat->nr_of_vts_audio_streams; i < 8; i++)
CHECK_ZERO(vtsi_mat->vts_audio_attr[i]);
- assert(vtsi_mat->nr_of_vts_subp_streams <= 32);
+ CHECK_VALUE(vtsi_mat->nr_of_vts_subp_streams <= 32);
for(i = vtsi_mat->nr_of_vts_subp_streams; i < 32; i++)
CHECK_ZERO(vtsi_mat->vts_subp_attr[i]);
-
+
+ for(i = 0; i < 8; i++) {
+ CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero1);
+ CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero2);
+ CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero3);
+ CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero4);
+ CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero5);
+ CHECK_ZERO(vtsi_mat->vts_mu_audio_attr[i].zero6);
+ }
+
return 1;
}
@@ -470,7 +489,7 @@
B2N_16(cmd_tbl->nr_of_post);
B2N_16(cmd_tbl->nr_of_cell);
- assert(cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_cell<= 255);
+ CHECK_VALUE(cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_cell<= 255);
if(cmd_tbl->nr_of_pre != 0) {
unsigned int pre_cmds_size = cmd_tbl->nr_of_pre * COMMAND_DATA_SIZE;
@@ -572,9 +591,9 @@
B2N_32(cell_playback[i].last_sector);
/* Changed < to <= because this was false in the movie 'Pi'. */
- assert(cell_playback[i].last_vobu_start_sector <=
+ CHECK_VALUE(cell_playback[i].last_vobu_start_sector <=
cell_playback[i].last_sector);
- assert(cell_playback[i].first_sector <=
+ CHECK_VALUE(cell_playback[i].first_sector <=
cell_playback[i].last_vobu_start_sector);
}
@@ -627,7 +646,7 @@
B2N_32(pgc->palette[i]);
CHECK_ZERO(pgc->zero_1);
- assert(pgc->nr_of_programs <= pgc->nr_of_cells);
+ CHECK_VALUE(pgc->nr_of_programs <= pgc->nr_of_cells);
/* verify time (look at print_time) */
for(i = 0; i < 8; i++)
@@ -641,13 +660,13 @@
if(pgc->nr_of_programs == 0) {
CHECK_ZERO(pgc->still_time);
CHECK_ZERO(pgc->pg_playback_mode); // ??
- assert(pgc->program_map_offset == 0);
- assert(pgc->cell_playback_offset == 0);
- assert(pgc->cell_position_offset == 0);
+ CHECK_VALUE(pgc->program_map_offset == 0);
+ CHECK_VALUE(pgc->cell_playback_offset == 0);
+ CHECK_VALUE(pgc->cell_position_offset == 0);
} else {
- assert(pgc->program_map_offset != 0);
- assert(pgc->cell_playback_offset != 0);
- assert(pgc->cell_position_offset != 0);
+ CHECK_VALUE(pgc->program_map_offset != 0);
+ CHECK_VALUE(pgc->cell_playback_offset != 0);
+ CHECK_VALUE(pgc->cell_position_offset != 0);
}
if(pgc->command_tbl_offset != 0) {
@@ -728,11 +747,10 @@
if(!ifofile->vmgi_mat)
return 0;
- /* It seems that first_play_pgc might be optional after all. */
- if(ifofile->vmgi_mat->first_play_pgc == 0) { /* mandatory */
- ifofile->first_play_pgc = 0;
- return 0; /* change this to a 1 if it's optional. */
- }
+ /* It seems that first_play_pgc is optional after all. */
+ ifofile->first_play_pgc = 0;
+ if(ifofile->vmgi_mat->first_play_pgc == 0)
+ return 1;
ifofile->first_play_pgc = (pgc_t *)malloc(sizeof(pgc_t));
if(!ifofile->first_play_pgc)
@@ -825,22 +843,22 @@
CHECK_ZERO(tt_srpt->zero_1);
- assert(tt_srpt->nr_of_srpts != 0);
- assert(tt_srpt->nr_of_srpts < 100); // ??
- assert((int)tt_srpt->nr_of_srpts * sizeof(title_info_t) <= info_length);
+ CHECK_VALUE(tt_srpt->nr_of_srpts != 0);
+ CHECK_VALUE(tt_srpt->nr_of_srpts < 100); // ??
+ CHECK_VALUE((int)tt_srpt->nr_of_srpts * sizeof(title_info_t) <= info_length);
for(i = 0; i < tt_srpt->nr_of_srpts; i++) {
- assert(tt_srpt->title[i].pb_ty.zero_1 == 0);
- assert(tt_srpt->title[i].nr_of_angles != 0);
- assert(tt_srpt->title[i].nr_of_angles < 10);
- //assert(tt_srpt->title[i].nr_of_ptts != 0);
+ CHECK_VALUE(tt_srpt->title[i].pb_ty.zero_1 == 0);
+ CHECK_VALUE(tt_srpt->title[i].nr_of_angles != 0);
+ CHECK_VALUE(tt_srpt->title[i].nr_of_angles < 10);
+ //CHECK_VALUE(tt_srpt->title[i].nr_of_ptts != 0);
// XXX: this assertion breaks Ghostbusters:
- assert(tt_srpt->title[i].nr_of_ptts < 1000); // ??
- assert(tt_srpt->title[i].title_set_nr != 0);
- assert(tt_srpt->title[i].title_set_nr < 100); // ??
- assert(tt_srpt->title[i].vts_ttn != 0);
- assert(tt_srpt->title[i].vts_ttn < 100); // ??
- //assert(tt_srpt->title[i].title_set_sector != 0);
+ CHECK_VALUE(tt_srpt->title[i].nr_of_ptts < 1000); // ??
+ CHECK_VALUE(tt_srpt->title[i].title_set_nr != 0);
+ CHECK_VALUE(tt_srpt->title[i].title_set_nr < 100); // ??
+ CHECK_VALUE(tt_srpt->title[i].vts_ttn != 0);
+ CHECK_VALUE(tt_srpt->title[i].vts_ttn < 100); // ??
+ //CHECK_VALUE(tt_srpt->title[i].title_set_sector != 0);
}
// Make this a function
@@ -906,8 +924,8 @@
B2N_32(vts_ptt_srpt->last_byte);
CHECK_ZERO(vts_ptt_srpt->zero_1);
- assert(vts_ptt_srpt->nr_of_srpts != 0);
- assert(vts_ptt_srpt->nr_of_srpts < 100); // ??
+ CHECK_VALUE(vts_ptt_srpt->nr_of_srpts != 0);
+ CHECK_VALUE(vts_ptt_srpt->nr_of_srpts < 100); // ??
info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE;
@@ -931,8 +949,10 @@
Magic Knight Rayearth Daybreak is mastered very strange and has
Titles with 0 PTTs. They all have a data[i] offsets beyond the end of
of the vts_ptt_srpt structure. */
- assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1 + 4);
+ CHECK_VALUE(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1 + 4);
}
+
+ vts_ptt_srpt->ttu_offset = data;
vts_ptt_srpt->title = malloc(vts_ptt_srpt->nr_of_srpts * sizeof(ttu_t));
if(!vts_ptt_srpt->title) {
@@ -951,7 +971,7 @@
Magic Knight Rayearth Daybreak is mastered very strange and has
Titles with 0 PTTs. */
if(n < 0) n = 0;
- assert(n % 4 == 0);
+ CHECK_VALUE(n % 4 == 0);
vts_ptt_srpt->title[i].nr_of_ptts = n / 4;
vts_ptt_srpt->title[i].ptt = malloc(n * sizeof(ptt_info_t));
@@ -965,14 +985,13 @@
}
for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
/* The assert placed here because of Magic Knight Rayearth Daybreak */
- assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1);
+ CHECK_VALUE(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1);
vts_ptt_srpt->title[i].ptt[j].pgcn
= *(uint16_t*)(((char *)data) + data[i] + 4*j - VTS_PTT_SRPT_SIZE);
vts_ptt_srpt->title[i].ptt[j].pgn
= *(uint16_t*)(((char *)data) + data[i] + 4*j + 2 - VTS_PTT_SRPT_SIZE);
}
}
- free(data);
for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
@@ -982,12 +1001,12 @@
}
for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) {
- assert(vts_ptt_srpt->title[i].nr_of_ptts < 1000); // ??
+ CHECK_VALUE(vts_ptt_srpt->title[i].nr_of_ptts < 1000); // ??
for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) {
- assert(vts_ptt_srpt->title[i].ptt[j].pgcn != 0 );
- assert(vts_ptt_srpt->title[i].ptt[j].pgcn < 1000); // ??
- assert(vts_ptt_srpt->title[i].ptt[j].pgn != 0);
- assert(vts_ptt_srpt->title[i].ptt[j].pgn < 100); // ??
+ CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgcn != 0 );
+ CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgcn < 1000); // ??
+ CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgn != 0);
+ CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgn < 100); // ??
}
}
@@ -1003,6 +1022,7 @@
int i;
for(i = 0; i < ifofile->vts_ptt_srpt->nr_of_srpts; i++)
free(ifofile->vts_ptt_srpt->title[i].ptt);
+ free(ifofile->vts_ptt_srpt->ttu_offset);
free(ifofile->vts_ptt_srpt->title);
free(ifofile->vts_ptt_srpt);
ifofile->vts_ptt_srpt = 0;
@@ -1013,7 +1033,7 @@
int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) {
ptl_mait_t *ptl_mait;
int info_length;
- unsigned int i;
+ unsigned int i, j;
if(!ifofile)
return 0;
@@ -1024,8 +1044,7 @@
if(ifofile->vmgi_mat->ptl_mait == 0)
return 1;
- if(!DVDFileSeek_(ifofile->file,
- ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN))
+ if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN))
return 0;
ptl_mait = (ptl_mait_t *)malloc(sizeof(ptl_mait_t));
@@ -1044,26 +1063,29 @@
B2N_16(ptl_mait->nr_of_vtss);
B2N_32(ptl_mait->last_byte);
- info_length = ptl_mait->last_byte + 1 - PTL_MAIT_SIZE;
-
- assert(ptl_mait->nr_of_countries != 0);
- assert(ptl_mait->nr_of_countries < 100); // ??
- assert(ptl_mait->nr_of_vtss != 0);
- assert(ptl_mait->nr_of_vtss < 100); // ??
- assert(ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE <= info_length);
+ CHECK_VALUE(ptl_mait->nr_of_countries != 0);
+ CHECK_VALUE(ptl_mait->nr_of_countries < 100); // ??
+ CHECK_VALUE(ptl_mait->nr_of_vtss != 0);
+ CHECK_VALUE(ptl_mait->nr_of_vtss < 100); // ??
+ CHECK_VALUE(ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE
+ <= ptl_mait->last_byte + 1 - PTL_MAIT_SIZE);
- /* Change this to read and 'translate' the tables too.
- I.e don't read so much here */
+ info_length = ptl_mait->nr_of_countries * sizeof(ptl_mait_country_t);
ptl_mait->countries = (ptl_mait_country_t *)malloc(info_length);
if(!ptl_mait->countries) {
free(ptl_mait);
ifofile->ptl_mait = 0;
return 0;
}
- if(!(DVDReadBytes(ifofile->file, ptl_mait->countries, info_length))) {
- fprintf(stderr, "libdvdread: Unable to read PTL_MAIT.\n");
- ifoFree_PTL_MAIT(ifofile);
- return 0;
+
+ for(i = 0; i < ptl_mait->nr_of_countries; i++) {
+ if(!(DVDReadBytes(ifofile->file, &ptl_mait->countries[i], PTL_MAIT_COUNTRY_SIZE))) {
+ fprintf(stderr, "libdvdread: Unable to read PTL_MAIT.\n");
+ free(ptl_mait->countries);
+ free(ptl_mait);
+ ifofile->ptl_mait = 0;
+ return 0;
+ }
}
for(i = 0; i < ptl_mait->nr_of_countries; i++) {
@@ -1074,25 +1096,221 @@
for(i = 0; i < ptl_mait->nr_of_countries; i++) {
CHECK_ZERO(ptl_mait->countries[i].zero_1);
CHECK_ZERO(ptl_mait->countries[i].zero_2);
- assert(ptl_mait->countries[i].pf_ptl_mai_start_byte +
- 8 * (ptl_mait->nr_of_vtss + 1) * 2 <= ptl_mait->last_byte + 1);
+ CHECK_VALUE(ptl_mait->countries[i].pf_ptl_mai_start_byte
+ + 8*2 * (ptl_mait->nr_of_vtss + 1) <= ptl_mait->last_byte + 1);
}
+ for(i = 0; i < ptl_mait->nr_of_countries; i++) {
+ uint16_t *pf_temp;
+
+ if(!DVDFileSeek_(ifofile->file,
+ ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN
+ + ptl_mait->countries[i].pf_ptl_mai_start_byte)) {
+ fprintf(stderr, "libdvdread: Unable to seak PTL_MAIT table.\n");
+ free(ptl_mait->countries);
+ free(ptl_mait);
+ return 0;
+ }
+ info_length = (ptl_mait->nr_of_vtss + 1) * sizeof(pf_level_t);
+ pf_temp = (uint16_t *)malloc(info_length);
+ if(!pf_temp) {
+ for(j = 0; j < i ; j++) {
+ free(ptl_mait->countries[j].pf_ptl_mai);
+ }
+ free(ptl_mait->countries);
+ free(ptl_mait);
+ return 0;
+ }
+ if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) {
+ fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table.\n");
+ free(pf_temp);
+ for(j = 0; j < i ; j++) {
+ free(ptl_mait->countries[j].pf_ptl_mai);
+ }
+ free(ptl_mait->countries);
+ free(ptl_mait);
+ return 0;
+ }
+ for (j = 0; j < ((ptl_mait->nr_of_vtss + 1) * 8); j++) {
+ B2N_16(pf_temp[j]);
+ }
+ ptl_mait->countries[i].pf_ptl_mai = (pf_level_t *)malloc(info_length);
+ if(!ptl_mait->countries[i].pf_ptl_mai) {
+ free(pf_temp);
+ for(j = 0; j < i ; j++) {
+ free(ptl_mait->countries[j].pf_ptl_mai);
+ }
+ free(ptl_mait->countries);
+ free(ptl_mait);
+ return 0;
+ }
+ { /* Transpose the array so we can use C indexing. */
+ int level, vts;
+ for(level = 0; level < 8; level++) {
+ for(vts = 0; vts <= ptl_mait->nr_of_vtss; vts++) {
+ ptl_mait->countries[i].pf_ptl_mai[vts][level] =
+ pf_temp[(7-level)*(ptl_mait->nr_of_vtss+1) + vts];
+ }
+ }
+ free(pf_temp);
+ }
+ }
return 1;
}
-
void ifoFree_PTL_MAIT(ifo_handle_t *ifofile) {
+ unsigned int i;
+
if(!ifofile)
return;
if(ifofile->ptl_mait) {
+ for(i = 0; i < ifofile->ptl_mait->nr_of_countries; i++) {
+ free(ifofile->ptl_mait->countries[i].pf_ptl_mai);
+ }
free(ifofile->ptl_mait->countries);
free(ifofile->ptl_mait);
ifofile->ptl_mait = 0;
}
}
+int ifoRead_VTS_TMAPT(ifo_handle_t *ifofile) {
+ vts_tmapt_t *vts_tmapt;
+ uint32_t *vts_tmap_srp;
+ unsigned int offset;
+ int info_length;
+ unsigned int i, j;
+
+ if(!ifofile)
+ return 0;
+
+ if(!ifofile->vtsi_mat)
+ return 0;
+
+ if(ifofile->vtsi_mat->vts_tmapt == 0) { /* optional(?) */
+ ifofile->vts_tmapt = NULL;
+ fprintf(stderr,"Please send bug report - no VTS_TMAPT ?? \n");
+ return 1;
+ }
+
+ offset = ifofile->vtsi_mat->vts_tmapt * DVD_BLOCK_LEN;
+
+ if(!DVDFileSeek_(ifofile->file, offset))
+ return 0;
+
+ vts_tmapt = (vts_tmapt_t *)malloc(sizeof(vts_tmapt_t));
+ if(!vts_tmapt)
+ return 0;
+
+ ifofile->vts_tmapt = vts_tmapt;
+
+ if(!(DVDReadBytes(ifofile->file, vts_tmapt, VTS_TMAPT_SIZE))) {
+ fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
+ free(vts_tmapt);
+ ifofile->vts_tmapt = NULL;
+ return 0;
+ }
+
+ B2N_16(vts_tmapt->nr_of_tmaps);
+ B2N_32(vts_tmapt->last_byte);
+
+ CHECK_ZERO(vts_tmapt->zero_1);
+
+ info_length = vts_tmapt->nr_of_tmaps * 4;
+
+ vts_tmap_srp = (uint32_t *)malloc(info_length);
+ if(!vts_tmap_srp) {
+ free(vts_tmapt);
+ ifofile->vts_tmapt = NULL;
+ return 0;
+ }
+
+ vts_tmapt->tmap_offset = vts_tmap_srp;
+
+ if(!(DVDReadBytes(ifofile->file, vts_tmap_srp, info_length))) {
+ fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n");
+ free(vts_tmap_srp);
+ free(vts_tmapt);
+ ifofile->vts_tmapt = NULL;
+ return 0;
+ }
+
+ for (i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
+ B2N_32(vts_tmap_srp[i]);
+ }
+
+
+ info_length = vts_tmapt->nr_of_tmaps * sizeof(vts_tmap_t);
+
+ vts_tmapt->tmap = (vts_tmap_t *)malloc(info_length);
+ if(!vts_tmapt->tmap) {
+ free(vts_tmap_srp);
+ free(vts_tmapt);
+ ifofile->vts_tmapt = NULL;
+ return 0;
+ }
+
+ memset(vts_tmapt->tmap, 0, info_length); /* So ifoFree_VTS_TMAPT works. */
+
+ for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
+ if(!DVDFileSeek_(ifofile->file, offset + vts_tmap_srp[i])) {
+ ifoFree_VTS_TMAPT(ifofile);
+ return 0;
+ }
+
+ if(!(DVDReadBytes(ifofile->file, &vts_tmapt->tmap[i], VTS_TMAP_SIZE))) {
+ fprintf(stderr, "libdvdread: Unable to read VTS_TMAP.\n");
+ ifoFree_VTS_TMAPT(ifofile);
+ return 0;
+ }
+
+ B2N_16(vts_tmapt->tmap[i].nr_of_entries);
+ CHECK_ZERO(vts_tmapt->tmap[i].zero_1);
+
+ if(vts_tmapt->tmap[i].nr_of_entries == 0) { /* Early out if zero entries */
+ vts_tmapt->tmap[i].map_ent = NULL;
+ continue;
+ }
+
+ info_length = vts_tmapt->tmap[i].nr_of_entries * sizeof(map_ent_t);
+
+ vts_tmapt->tmap[i].map_ent = (map_ent_t *)malloc(info_length);
+ if(!vts_tmapt->tmap[i].map_ent) {
+ ifoFree_VTS_TMAPT(ifofile);
+ return 0;
+ }
+
+ if(!(DVDReadBytes(ifofile->file, vts_tmapt->tmap[i].map_ent, info_length))) {
+ fprintf(stderr, "libdvdread: Unable to read VTS_TMAP_ENT.\n");
+ ifoFree_VTS_TMAPT(ifofile);
+ return 0;
+ }
+
+ for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++)
+ B2N_32(vts_tmapt->tmap[i].map_ent[j]);
+ }
+
+ return 1;
+}
+
+void ifoFree_VTS_TMAPT(ifo_handle_t *ifofile) {
+ unsigned int i;
+
+ if(!ifofile)
+ return;
+
+ if(ifofile->vts_tmapt) {
+ for(i = 0; i < ifofile->vts_tmapt->nr_of_tmaps; i++)
+ if(ifofile->vts_tmapt->tmap[i].map_ent)
+ free(ifofile->vts_tmapt->tmap[i].map_ent);
+ free(ifofile->vts_tmapt->tmap);
+ free(ifofile->vts_tmapt->tmap_offset);
+ free(ifofile->vts_tmapt);
+ ifofile->vts_tmapt = NULL;
+ }
+}
+
+
int ifoRead_TITLE_C_ADT(ifo_handle_t *ifofile) {
if(!ifofile)
@@ -1168,7 +1386,7 @@
/* assert(c_adt->nr_of_vobs > 0);
Magic Knight Rayearth Daybreak is mastered very strange and has
Titles with a VOBS that has no cells. */
- assert(info_length % sizeof(cell_adr_t) == 0);
+ CHECK_VALUE(info_length % sizeof(cell_adr_t) == 0);
/* assert(info_length / sizeof(cell_adr_t) >= c_adt->nr_of_vobs);
Enemy of the State region 2 (de) has Titles where nr_of_vobs field
@@ -1194,10 +1412,10 @@
B2N_32(c_adt->cell_adr_table[i].last_sector);
CHECK_ZERO(c_adt->cell_adr_table[i].zero_1);
- assert(c_adt->cell_adr_table[i].vob_id > 0);
- assert(c_adt->cell_adr_table[i].vob_id <= c_adt->nr_of_vobs);
- assert(c_adt->cell_adr_table[i].cell_id > 0);
- assert(c_adt->cell_adr_table[i].start_sector <
+ CHECK_VALUE(c_adt->cell_adr_table[i].vob_id > 0);
+ CHECK_VALUE(c_adt->cell_adr_table[i].vob_id <= c_adt->nr_of_vobs);
+ CHECK_VALUE(c_adt->cell_adr_table[i].cell_id > 0);
+ CHECK_VALUE(c_adt->cell_adr_table[i].start_sector <
c_adt->cell_adr_table[i].last_sector);
}
@@ -1301,7 +1519,7 @@
/* assert(info_length > 0);
Magic Knight Rayearth Daybreak is mastered very strange and has
Titles with a VOBS that has no VOBUs. */
- assert(info_length % sizeof(uint32_t) == 0);
+ CHECK_VALUE(info_length % sizeof(uint32_t) == 0);
vobu_admap->vobu_start_sectors = (uint32_t *)malloc(info_length);
if(!vobu_admap->vobu_start_sectors) {
@@ -1387,7 +1605,7 @@
/* assert(pgcit->nr_of_pgci_srp != 0);
Magic Knight Rayearth Daybreak is mastered very strange and has
Titles with 0 PTTs. */
- assert(pgcit->nr_of_pgci_srp < 10000); // ?? seen max of 1338
+ CHECK_VALUE(pgcit->nr_of_pgci_srp < 10000); // ?? seen max of 1338
info_length = pgcit->nr_of_pgci_srp * PGCI_SRP_SIZE;
data = malloc(info_length);
@@ -1410,12 +1628,12 @@
ptr += PGCI_LU_SIZE;
B2N_16(pgcit->pgci_srp[i].ptl_id_mask);
B2N_32(pgcit->pgci_srp[i].pgc_start_byte);
- assert(pgcit->pgci_srp[i].unknown1 == 0);
+ CHECK_VALUE(pgcit->pgci_srp[i].unknown1 == 0);
}
free(data);
for(i = 0; i < pgcit->nr_of_pgci_srp; i++)
- assert(pgcit->pgci_srp[i].pgc_start_byte + PGC_SIZE <= pgcit->last_byte+1);
+ CHECK_VALUE(pgcit->pgci_srp[i].pgc_start_byte + PGC_SIZE <= pgcit->last_byte+1);
for(i = 0; i < pgcit->nr_of_pgci_srp; i++) {
pgcit->pgci_srp[i].pgc = malloc(sizeof(pgc_t));
@@ -1507,9 +1725,9 @@
B2N_32(pgci_ut->last_byte);
CHECK_ZERO(pgci_ut->zero_1);
- assert(pgci_ut->nr_of_lus != 0);
- assert(pgci_ut->nr_of_lus < 100); // ?? 3-4 ?
- assert((uint32_t)pgci_ut->nr_of_lus * PGCI_LU_SIZE < pgci_ut->last_byte);
+ CHECK_VALUE(pgci_ut->nr_of_lus != 0);
+ CHECK_VALUE(pgci_ut->nr_of_lus < 100); // ?? 3-4 ?
+ CHECK_VALUE((uint32_t)pgci_ut->nr_of_lus * PGCI_LU_SIZE < pgci_ut->last_byte);
info_length = pgci_ut->nr_of_lus * PGCI_LU_SIZE;
data = malloc(info_length);
@@ -1542,7 +1760,6 @@
free(data);
for(i = 0; i < pgci_ut->nr_of_lus; i++) {
- CHECK_ZERO(pgci_ut->lu[i].zero_1);
// Maybe this is only defined for v1.1 and later titles?
/* If the bits in 'lu[i].exists' are enumerated abcd efgh then:
VTS_x_yy.IFO VIDEO_TS.IFO
@@ -1552,7 +1769,7 @@
d == 0x86 "Angle"
e == 0x87 "PTT"
*/
- assert((pgci_ut->lu[i].exists & 0x07) == 0);
+ CHECK_VALUE((pgci_ut->lu[i].exists & 0x07) == 0);
}
for(i = 0; i < pgci_ut->nr_of_lus; i++) {
@@ -1634,21 +1851,21 @@
CHECK_ZERO(vts_attributes->zero_5);
CHECK_ZERO(vts_attributes->zero_6);
CHECK_ZERO(vts_attributes->zero_7);
- assert(vts_attributes->nr_of_vtsm_audio_streams <= 1);
- assert(vts_attributes->nr_of_vtsm_subp_streams <= 1);
- assert(vts_attributes->nr_of_vtstt_audio_streams <= 8);
+ CHECK_VALUE(vts_attributes->nr_of_vtsm_audio_streams <= 1);
+ CHECK_VALUE(vts_attributes->nr_of_vtsm_subp_streams <= 1);
+ CHECK_VALUE(vts_attributes->nr_of_vtstt_audio_streams <= 8);
for(i = vts_attributes->nr_of_vtstt_audio_streams; i < 8; i++)
CHECK_ZERO(vts_attributes->vtstt_audio_attr[i]);
- assert(vts_attributes->nr_of_vtstt_subp_streams <= 32);
+ CHECK_VALUE(vts_attributes->nr_of_vtstt_subp_streams <= 32);
{
unsigned int nr_coded;
- assert(vts_attributes->last_byte + 1 >= VTS_ATTRIBUTES_MIN_SIZE);
+ CHECK_VALUE(vts_attributes->last_byte + 1 >= VTS_ATTRIBUTES_MIN_SIZE);
nr_coded = (vts_attributes->last_byte + 1 - VTS_ATTRIBUTES_MIN_SIZE)/6;
// This is often nr_coded = 70, how do you know how many there really are?
if(nr_coded > 32) { // We haven't read more from disk/file anyway
nr_coded = 32;
}
- assert(vts_attributes->nr_of_vtstt_subp_streams <= nr_coded);
+ CHECK_VALUE(vts_attributes->nr_of_vtstt_subp_streams <= nr_coded);
for(i = vts_attributes->nr_of_vtstt_subp_streams; i < nr_coded; i++)
CHECK_ZERO(vts_attributes->vtstt_subp_attr[i]);
}
@@ -1692,9 +1909,9 @@
B2N_32(vts_atrt->last_byte);
CHECK_ZERO(vts_atrt->zero_1);
- assert(vts_atrt->nr_of_vtss != 0);
- assert(vts_atrt->nr_of_vtss < 100); //??
- assert((uint32_t)vts_atrt->nr_of_vtss * (4 + VTS_ATTRIBUTES_MIN_SIZE) +
+ CHECK_VALUE(vts_atrt->nr_of_vtss != 0);
+ CHECK_VALUE(vts_atrt->nr_of_vtss < 100); //??
+ CHECK_VALUE((uint32_t)vts_atrt->nr_of_vtss * (4 + VTS_ATTRIBUTES_MIN_SIZE) +
VTS_ATRT_SIZE < vts_atrt->last_byte + 1);
info_length = vts_atrt->nr_of_vtss * sizeof(uint32_t);
@@ -1704,6 +1921,9 @@
ifofile->vts_atrt = 0;
return 0;
}
+
+ vts_atrt->vts_atrt_offsets = data;
+
if(!(DVDReadBytes(ifofile->file, data, info_length))) {
free(data);
free(vts_atrt);
@@ -1713,7 +1933,7 @@
for(i = 0; i < vts_atrt->nr_of_vtss; i++) {
B2N_32(data[i]);
- assert(data[i] + VTS_ATTRIBUTES_MIN_SIZE < vts_atrt->last_byte + 1);
+ CHECK_VALUE(data[i] + VTS_ATTRIBUTES_MIN_SIZE < vts_atrt->last_byte + 1);
}
info_length = vts_atrt->nr_of_vtss * sizeof(vts_attributes_t);
@@ -1735,10 +1955,9 @@
}
// This assert cant be in ifoRead_VTS_ATTRIBUTES
- assert(offset + vts_atrt->vts[i].last_byte <= vts_atrt->last_byte + 1);
+ CHECK_VALUE(offset + vts_atrt->vts[i].last_byte <= vts_atrt->last_byte + 1);
// Is this check correct?
}
- free(data);
return 1;
}
@@ -1750,6 +1969,7 @@
if(ifofile->vts_atrt) {
free(ifofile->vts_atrt->vts);
+ free(ifofile->vts_atrt->vts_atrt_offsets);
free(ifofile->vts_atrt);
ifofile->vts_atrt = 0;
}
Index: ifo_read.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/ifo_read.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ifo_read.h 11 Mar 2005 02:40:28 -0000 1.3
+++ ifo_read.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -114,8 +114,7 @@
*
* Reads in the first play program chain data, filling the
* ifofile->first_play_pgc structure. This data is only located in the video
- * manager information file. This structure is mandatory, and must be included
- * in the VMGI file. **Possibly this is only optional.**
+ * manager information file (VMGI). This structure is optional.
*/
int ifoRead_FP_PGC(ifo_handle_t *);
@@ -141,7 +140,17 @@
* VTSI files, this fills the ifofile->vtsm_pgci_ut structure.
*/
int ifoRead_PGCI_UT(ifo_handle_t *);
-
+
+/**
+ * okay = ifoRead_VTS_TMAPT(ifofile);
+ *
+ * Reads in the VTS Time Map Table, this data is only located in the video
+ * title set information file. This fills the ifofile->vts_tmapt structure
+ * and all its substructures. When pressent enables VOBU level time-based
+ * seeking for One_Sequential_PGC_Titles.
+ */
+int ifoRead_VTS_TMAPT(ifo_handle_t *);
+
/**
* okay = ifoRead_C_ADT(ifofile);
*
@@ -209,6 +218,7 @@
void ifoFree_FP_PGC(ifo_handle_t *);
void ifoFree_PGCIT(ifo_handle_t *);
void ifoFree_PGCI_UT(ifo_handle_t *);
+void ifoFree_VTS_TMAPT(ifo_handle_t *);
void ifoFree_C_ADT(ifo_handle_t *);
void ifoFree_TITLE_C_ADT(ifo_handle_t *);
void ifoFree_VOBU_ADMAP(ifo_handle_t *);
Index: ifo_types.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/ifo_types.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ifo_types.h 11 Mar 2005 02:40:28 -0000 1.3
+++ ifo_types.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -63,7 +63,7 @@
uint8_t hour;
uint8_t minute;
uint8_t second;
- uint8_t frame_u; // The two high bits are the frame rate.
+ uint8_t frame_u; /* The two high bits are the frame rate. */
} ATTRIBUTE_PACKED dvd_time_t;
/**
@@ -87,7 +87,8 @@
unsigned int line21_cc_1 : 1;
unsigned int line21_cc_2 : 1;
- unsigned int unknown1 : 2;
+ unsigned int unknown1 : 1;
+ unsigned int bit_rate : 1;
unsigned int picture_size : 2;
unsigned int letterboxed : 1;
@@ -102,14 +103,15 @@
unsigned int letterboxed : 1;
unsigned int picture_size : 2;
- unsigned int unknown1 : 2;
+ unsigned int bit_rate : 1;
+ unsigned int unknown1 : 1;
unsigned int line21_cc_2 : 1;
unsigned int line21_cc_1 : 1;
#endif
} ATTRIBUTE_PACKED video_attr_t;
/**
- * Audio Attributes. (Incomplete/Wrong?)
+ * Audio Attributes.
*/
typedef struct {
#ifdef WORDS_BIGENDIAN
@@ -134,13 +136,99 @@
unsigned int quantization : 2;
#endif
uint16_t lang_code;
- uint8_t lang_code2; // ??
uint8_t lang_extension;
- uint16_t unknown2;
+ uint8_t code_extension;
+ uint8_t unknown3;
+ union {
+ struct ATTRIBUTE_PACKED {
+#ifdef WORDS_BIGENDIAN
+ unsigned int unknown4 : 1;
+ unsigned int channel_assignment : 3;
+ unsigned int version : 2;
+ unsigned int mc_intro : 1; /* probably 0: true, 1:false */
+ unsigned int mode : 1; /* Karaoke mode 0: solo 1: duet */
+#else
+ unsigned int mode : 1;
+ unsigned int mc_intro : 1;
+ unsigned int version : 2;
+ unsigned int channel_assignment : 3;
+ unsigned int unknown4 : 1;
+#endif
+ } karaoke;
+ struct ATTRIBUTE_PACKED {
+#ifdef WORDS_BIGENDIAN
+ unsigned int unknown5 : 4;
+ unsigned int dolby_encoded : 1; /* suitable for surround decoding */
+ unsigned int unknown6 : 3;
+#else
+ unsigned int unknown6 : 3;
+ unsigned int dolby_encoded : 1;
+ unsigned int unknown5 : 4;
+#endif
+ } surround;
+ } app_info;
} ATTRIBUTE_PACKED audio_attr_t;
+
+/**
+ * MultiChannel Extension
+ */
+typedef struct {
+#ifdef WORDS_BIGENDIAN
+ unsigned int zero1 : 7;
+ unsigned int ach0_gme : 1;
+
+ unsigned int zero2 : 7;
+ unsigned int ach1_gme : 1;
+
+ unsigned int zero3 : 4;
+ unsigned int ach2_gv1e : 1;
+ unsigned int ach2_gv2e : 1;
+ unsigned int ach2_gm1e : 1;
+ unsigned int ach2_gm2e : 1;
+
+ unsigned int zero4 : 4;
+ unsigned int ach3_gv1e : 1;
+ unsigned int ach3_gv2e : 1;
+ unsigned int ach3_gmAe : 1;
+ unsigned int ach3_se2e : 1;
+
+ unsigned int zero5 : 4;
+ unsigned int ach4_gv1e : 1;
+ unsigned int ach4_gv2e : 1;
+ unsigned int ach4_gmBe : 1;
+ unsigned int ach4_seBe : 1;
+#else
+ unsigned int ach0_gme : 1;
+ unsigned int zero1 : 7;
+
+ unsigned int ach1_gme : 1;
+ unsigned int zero2 : 7;
+
+ unsigned int ach2_gm2e : 1;
+ unsigned int ach2_gm1e : 1;
+ unsigned int ach2_gv2e : 1;
+ unsigned int ach2_gv1e : 1;
+ unsigned int zero3 : 4;
+
+ unsigned int ach3_se2e : 1;
+ unsigned int ach3_gmAe : 1;
+ unsigned int ach3_gv2e : 1;
+ unsigned int ach3_gv1e : 1;
+ unsigned int zero4 : 4;
+
+ unsigned int ach4_seBe : 1;
+ unsigned int ach4_gmBe : 1;
+ unsigned int ach4_gv2e : 1;
+ unsigned int ach4_gv1e : 1;
+ unsigned int zero5 : 4;
+#endif
+ uint8_t zero6[19];
+} ATTRIBUTE_PACKED multichannel_ext_t;
+
+
/**
- * Subpicture Attributes.(Incomplete/Wrong)
+ * Subpicture Attributes.
*/
typedef struct {
/*
@@ -153,11 +241,19 @@
* language: indicates language if type == 1
* lang extension: if type == 1 contains the lang extension
*/
- uint8_t type;
- uint8_t zero1;
+#ifdef WORDS_BIGENDIAN
+ unsigned int code_mode : 3;
+ unsigned int zero1 : 3;
+ unsigned int type : 2;
+#else
+ unsigned int type : 2;
+ unsigned int zero1 : 3;
+ unsigned int code_mode : 3;
+#endif
+ uint8_t zero2;
uint16_t lang_code;
- uint8_t lang_extension;
- uint8_t zero2;
+ uint8_t lang_extension;
+ uint8_t code_extension;
} ATTRIBUTE_PACKED subp_attr_t;
@@ -193,8 +289,8 @@
unsigned int stc_discontinuity: 1;
unsigned int seamless_angle : 1;
- unsigned int unknown1 : 1;
- unsigned int restricted : 1;
+ unsigned int playback_mode : 1; /**< When set, enter StillMode after each VOBU */
+ unsigned int restricted : 1; /**< ?? drop out of fastforward? */
unsigned int unknown2 : 6;
#else
unsigned int seamless_angle : 1;
@@ -206,7 +302,7 @@
unsigned int unknown2 : 6;
unsigned int restricted : 1;
- unsigned int unknown1 : 1;
+ unsigned int playback_mode : 1;
#endif
uint8_t still_time;
uint8_t cell_cmd_nr;
@@ -239,65 +335,65 @@
*/
typedef struct {
#ifdef WORDS_BIGENDIAN
- unsigned int zero : 7; // 25-31
- unsigned int video_pres_mode_change : 1; // 24
+ unsigned int zero : 7; /* 25-31 */
+ unsigned int video_pres_mode_change : 1; /* 24 */
- unsigned int karaoke_audio_pres_mode_change : 1; // 23
- unsigned int angle_change : 1; // 22
- unsigned int subpic_stream_change : 1; // 21
- unsigned int audio_stream_change : 1; // 20
- unsigned int pause_on : 1; // 19
- unsigned int still_off : 1; // 18
- unsigned int button_select_or_activate : 1; // 17
- unsigned int resume : 1; // 16
-
- unsigned int chapter_menu_call : 1; // 15
- unsigned int angle_menu_call : 1; // 14
- unsigned int audio_menu_call : 1; // 13
- unsigned int subpic_menu_call : 1; // 12
- unsigned int root_menu_call : 1; // 11
- unsigned int title_menu_call : 1; // 10
- unsigned int backward_scan : 1; // 9
- unsigned int forward_scan : 1; // 8
-
- unsigned int next_pg_search : 1; // 7
- unsigned int prev_or_top_pg_search : 1; // 6
- unsigned int time_or_chapter_search : 1; // 5
- unsigned int go_up : 1; // 4
- unsigned int stop : 1; // 3
- unsigned int title_play : 1; // 2
- unsigned int chapter_search_or_play : 1; // 1
- unsigned int title_or_time_play : 1; // 0
+ unsigned int karaoke_audio_pres_mode_change : 1; /* 23 */
+ unsigned int angle_change : 1;
+ unsigned int subpic_stream_change : 1;
+ unsigned int audio_stream_change : 1;
+ unsigned int pause_on : 1;
+ unsigned int still_off : 1;
+ unsigned int button_select_or_activate : 1;
+ unsigned int resume : 1; /* 16 */
+
+ unsigned int chapter_menu_call : 1; /* 15 */
+ unsigned int angle_menu_call : 1;
+ unsigned int audio_menu_call : 1;
+ unsigned int subpic_menu_call : 1;
+ unsigned int root_menu_call : 1;
+ unsigned int title_menu_call : 1;
+ unsigned int backward_scan : 1;
+ unsigned int forward_scan : 1; /* 8 */
+
+ unsigned int next_pg_search : 1; /* 7 */
+ unsigned int prev_or_top_pg_search : 1;
+ unsigned int time_or_chapter_search : 1;
+ unsigned int go_up : 1;
+ unsigned int stop : 1;
+ unsigned int title_play : 1;
+ unsigned int chapter_search_or_play : 1;
+ unsigned int title_or_time_play : 1; /* 0 */
#else
- unsigned int video_pres_mode_change : 1; // 24
- unsigned int zero : 7; // 25-31
+ unsigned int video_pres_mode_change : 1; /* 24 */
+ unsigned int zero : 7; /* 25-31 */
- unsigned int resume : 1; // 16
- unsigned int button_select_or_activate : 1; // 17
- unsigned int still_off : 1; // 18
- unsigned int pause_on : 1; // 19
- unsigned int audio_stream_change : 1; // 20
- unsigned int subpic_stream_change : 1; // 21
- unsigned int angle_change : 1; // 22
- unsigned int karaoke_audio_pres_mode_change : 1; // 23
-
- unsigned int forward_scan : 1; // 8
- unsigned int backward_scan : 1; // 9
- unsigned int title_menu_call : 1; // 10
- unsigned int root_menu_call : 1; // 11
- unsigned int subpic_menu_call : 1; // 12
- unsigned int audio_menu_call : 1; // 13
- unsigned int angle_menu_call : 1; // 14
- unsigned int chapter_menu_call : 1; // 15
-
- unsigned int title_or_time_play : 1; // 0
- unsigned int chapter_search_or_play : 1; // 1
- unsigned int title_play : 1; // 2
- unsigned int stop : 1; // 3
- unsigned int go_up : 1; // 4
- unsigned int time_or_chapter_search : 1; // 5
- unsigned int prev_or_top_pg_search : 1; // 6
- unsigned int next_pg_search : 1; // 7
+ unsigned int resume : 1; /* 16 */
+ unsigned int button_select_or_activate : 1;
+ unsigned int still_off : 1;
+ unsigned int pause_on : 1;
+ unsigned int audio_stream_change : 1;
+ unsigned int subpic_stream_change : 1;
+ unsigned int angle_change : 1;
+ unsigned int karaoke_audio_pres_mode_change : 1; /* 23 */
+
+ unsigned int forward_scan : 1; /* 8 */
+ unsigned int backward_scan : 1;
+ unsigned int title_menu_call : 1;
+ unsigned int root_menu_call : 1;
+ unsigned int subpic_menu_call : 1;
+ unsigned int audio_menu_call : 1;
+ unsigned int angle_menu_call : 1;
+ unsigned int chapter_menu_call : 1; /* 15 */
+
+ unsigned int title_or_time_play : 1; /* 0 */
+ unsigned int chapter_search_or_play : 1;
+ unsigned int title_play : 1;
+ unsigned int stop : 1;
+ unsigned int go_up : 1;
+ unsigned int time_or_chapter_search : 1;
+ unsigned int prev_or_top_pg_search : 1;
+ unsigned int next_pg_search : 1; /* 7 */
#endif
} ATTRIBUTE_PACKED user_ops_t;
@@ -365,7 +461,7 @@
*/
typedef struct {
uint16_t lang_code;
- uint8_t zero_1;
+ uint8_t lang_extension;
uint8_t exists;
uint32_t lang_start_byte;
pgcit_t *pgcit;
@@ -401,7 +497,7 @@
uint16_t nr_of_vobs; /* VOBs */
uint16_t zero_1;
uint32_t last_byte;
- cell_adr_t *cell_adr_table;
+ cell_adr_t *cell_adr_table; /* No explicit size given. */
} ATTRIBUTE_PACKED c_adt_t;
#define C_ADT_SIZE 8
@@ -457,11 +553,11 @@
video_attr_t vmgm_video_attr;
uint8_t zero_7;
- uint8_t nr_of_vmgm_audio_streams; // should be 0 or 1
+ uint8_t nr_of_vmgm_audio_streams; /* should be 0 or 1 */
audio_attr_t vmgm_audio_attr;
audio_attr_t zero_8[7];
uint8_t zero_9[17];
- uint8_t nr_of_vmgm_subp_streams; // should be 0 or 1
+ uint8_t nr_of_vmgm_subp_streams; /* should be 0 or 1 */
subp_attr_t vmgm_subp_attr;
subp_attr_t zero_10[27]; /* XXX: how much 'padding' here? */
} ATTRIBUTE_PACKED vmgi_mat_t;
@@ -469,21 +565,21 @@
typedef struct {
#ifdef WORDS_BIGENDIAN
unsigned int zero_1 : 1;
- unsigned int multi_or_random_pgc_title : 1; // 0 == one sequential pgc title
+ unsigned int multi_or_random_pgc_title : 1; /* 0: one sequential pgc title */
unsigned int jlc_exists_in_cell_cmd : 1;
unsigned int jlc_exists_in_prepost_cmd : 1;
unsigned int jlc_exists_in_button_cmd : 1;
unsigned int jlc_exists_in_tt_dom : 1;
- unsigned int chapter_search_or_play : 1; // UOP 1
- unsigned int title_or_time_play : 1; // UOP 0
+ unsigned int chapter_search_or_play : 1; /* UOP 1 */
+ unsigned int title_or_time_play : 1; /* UOP 0 */
#else
- unsigned int title_or_time_play : 1; // UOP 0
- unsigned int chapter_search_or_play : 1; // UOP 1
+ unsigned int title_or_time_play : 1;
+ unsigned int chapter_search_or_play : 1;
unsigned int jlc_exists_in_tt_dom : 1;
unsigned int jlc_exists_in_button_cmd : 1;
unsigned int jlc_exists_in_prepost_cmd : 1;
unsigned int jlc_exists_in_cell_cmd : 1;
- unsigned int multi_or_random_pgc_title : 1; // 0 == one sequential pgc title
+ unsigned int multi_or_random_pgc_title : 1;
unsigned int zero_1 : 1;
#endif
} ATTRIBUTE_PACKED playback_type_t;
@@ -512,6 +608,13 @@
} ATTRIBUTE_PACKED tt_srpt_t;
#define TT_SRPT_SIZE 8
+
+/**
+ * Parental Management Information Unit Table.
+ * Level 1 (US: G), ..., 7 (US: NC-17), 8
+ */
+typedef uint16_t pf_level_t[8];
+
/**
* Parental Management Information Unit Table.
*/
@@ -520,7 +623,7 @@
uint16_t zero_1;
uint16_t pf_ptl_mai_start_byte;
uint16_t zero_2;
- /* uint16_t *pf_ptl_mai // table of nr_of_vtss+1 x 8 */
+ pf_level_t *pf_ptl_mai; /* table of (nr_of_vtss + 1), video_ts is first */
} ATTRIBUTE_PACKED ptl_mait_country_t;
#define PTL_MAIT_COUNTRY_SIZE 8
@@ -544,12 +647,12 @@
video_attr_t vtsm_vobs_attr;
uint8_t zero_1;
- uint8_t nr_of_vtsm_audio_streams; // should be 0 or 1
+ uint8_t nr_of_vtsm_audio_streams; /* should be 0 or 1 */
audio_attr_t vtsm_audio_attr;
audio_attr_t zero_2[7];
uint8_t zero_3[16];
uint8_t zero_4;
- uint8_t nr_of_vtsm_subp_streams; // should be 0 or 1
+ uint8_t nr_of_vtsm_subp_streams; /* should be 0 or 1 */
subp_attr_t vtsm_subp_attr;
subp_attr_t zero_5[27];
@@ -575,6 +678,7 @@
uint16_t zero_1;
uint32_t last_byte;
vts_attributes_t *vts;
+ uint32_t *vts_atrt_offsets; /* offsets table for each vts_attributes */
} ATTRIBUTE_PACKED vts_atrt_t;
#define VTS_ATRT_SIZE 8
@@ -585,18 +689,18 @@
uint32_t last_byte; /* offsets are relative here */
uint16_t offsets[100]; /* == nr_of_srpts + 1 (first is disc title) */
#if 0
- uint16_t unknown; // 0x48 ?? 0x48 words (16bit) info following
+ uint16_t unknown; /* 0x48 ?? 0x48 words (16bit) info following */
uint16_t zero_1;
- uint8_t type_of_info;//?? 01 == disc, 02 == Title, 04 == Title part
+ uint8_t type_of_info; /* ?? 01 == disc, 02 == Title, 04 == Title part */
uint8_t unknown1;
uint8_t unknown2;
uint8_t unknown3;
- uint8_t unknown4;//?? allways 0x30 language?, text format?
+ uint8_t unknown4; /* ?? allways 0x30 language?, text format? */
uint8_t unknown5;
- uint16_t offset; // from first
+ uint16_t offset; /* from first */
- char text[12]; // ended by 0x09
+ char text[12]; /* ended by 0x09 */
#endif
} ATTRIBUTE_PACKED txtdt_t;
@@ -656,7 +760,7 @@
uint32_t vts_ptt_srpt; /* sector */
uint32_t vts_pgcit; /* sector */
uint32_t vtsm_pgci_ut; /* sector */
- uint32_t vts_tmapt; /* sector */ // XXX: FIXME TODO Implement
+ uint32_t vts_tmapt; /* sector */
uint32_t vtsm_c_adt; /* sector */
uint32_t vtsm_vobu_admap; /* sector */
uint32_t vts_c_adt; /* sector */
@@ -665,11 +769,11 @@
video_attr_t vtsm_video_attr;
uint8_t zero_14;
- uint8_t nr_of_vtsm_audio_streams; // should be 0 or 1
+ uint8_t nr_of_vtsm_audio_streams; /* should be 0 or 1 */
audio_attr_t vtsm_audio_attr;
audio_attr_t zero_15[7];
uint8_t zero_16[17];
- uint8_t nr_of_vtsm_subp_streams; // should be 0 or 1
+ uint8_t nr_of_vtsm_subp_streams; /* should be 0 or 1 */
subp_attr_t vtsm_subp_attr;
subp_attr_t zero_17[27];
uint8_t zero_18[2];
@@ -681,6 +785,8 @@
uint8_t zero_20[17];
uint8_t nr_of_vts_subp_streams;
subp_attr_t vts_subp_attr[32];
+ uint16_t zero_21;
+ multichannel_ext_t vts_mu_audio_attr[8];
/* XXX: how much 'padding' here, if any? */
} ATTRIBUTE_PACKED vtsi_mat_t;
@@ -708,10 +814,41 @@
uint16_t zero_1;
uint32_t last_byte;
ttu_t *title;
+ uint32_t *ttu_offset; /* offset table for each ttu */
} ATTRIBUTE_PACKED vts_ptt_srpt_t;
#define VTS_PTT_SRPT_SIZE 8
+/**
+ * Time Map Entry.
+ */
+/* Should this be bit field at all or just the uint32_t? */
+typedef uint32_t map_ent_t;
+
+/**
+ * Time Map.
+ */
+typedef struct {
+ uint8_t tmu; /* Time unit, in seconds */
+ uint8_t zero_1;
+ uint16_t nr_of_entries;
+ map_ent_t *map_ent;
+} ATTRIBUTE_PACKED vts_tmap_t;
+#define VTS_TMAP_SIZE 4
+
+/**
+ * Time Map Table.
+ */
+typedef struct {
+ uint16_t nr_of_tmaps;
+ uint16_t zero_1;
+ uint32_t last_byte;
+ vts_tmap_t *tmap;
+ uint32_t *tmap_offset; /* offset table for each tmap */
+} ATTRIBUTE_PACKED vts_tmapt_t;
+#define VTS_TMAPT_SIZE 8
+
+
#if PRAGMA_PACK
#pragma pack()
#endif
@@ -743,7 +880,7 @@
vtsi_mat_t *vtsi_mat;
vts_ptt_srpt_t *vts_ptt_srpt;
pgcit_t *vts_pgcit;
- int *vts_tmapt; // FIXME add/correct the type
+ vts_tmapt_t *vts_tmapt;
c_adt_t *vts_c_adt;
vobu_admap_t *vts_vobu_admap;
} ifo_handle_t;
Index: nav_print.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/nav_print.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- nav_print.c 11 Mar 2005 02:40:28 -0000 1.3
+++ nav_print.c 30 Jun 2005 22:48:26 -0000 1.4
@@ -1,9 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort at dtek.chalmers.se>
- *
- * Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
- * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
- * $Id$
+ * Copyright (C) 2000, 2001, 2002, 2003 Håkan Hjort <d95hjort at dtek.chalmers.se>
*
* Much of the contents in this file is based on VOBDUMP.
*
@@ -27,21 +23,21 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
+
#include <stdio.h>
#include <inttypes.h>
-//#include <assert.h>
-#include "config.h" // Needed for WORDS_BIGENDIAN
#include "nav_types.h"
#include "nav_print.h"
-
+#include "dvdread_internal.h"
static void print_time(dvd_time_t *dtime) {
const char *rate;
- assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
- assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
- assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
- assert((dtime->frame_u&0xf) < 0xa);
+ CHECK_VALUE((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa);
+ CHECK_VALUE((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa);
+ CHECK_VALUE((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa);
+ CHECK_VALUE((dtime->frame_u&0xf) < 0xa);
printf("%02x:%02x:%02x.%02x",
dtime->hour,
Index: nav_print.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/nav_print.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- nav_print.h 11 Mar 2005 02:40:28 -0000 1.3
+++ nav_print.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -2,8 +2,8 @@
#define NAV_PRINT_H_INCLUDED
/*
- * Copyright (C) 2001 Billy Biggs <vektor at dumbterm.net>,
- * Håkan Hjort <d95hjort at dtek.chalmers.se>
+ * Copyright (C) 2001, 2002 Billy Biggs <vektor at dumbterm.net>,
+ * Håkan Hjort <d95hjort at dtek.chalmers.se>
*
* Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
* detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
@@ -26,17 +26,25 @@
#include "nav_types.h"
+/**
+ * Pretty printing of the NAV packets, PCI and DSI structs.
+ */
+
#ifdef __cplusplus
extern "C" {
#endif
/**
* Prints information contained in the PCI to stdout.
+ *
+ * @param pci Pointer to the PCI data structure to be printed.
*/
void navPrint_PCI(pci_t *);
/**
* Prints information contained in the DSI to stdout.
+ *
+ * @param dsi Pointer to the DSI data structure to be printed.
*/
void navPrint_DSI(dsi_t *);
Index: nav_read.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/nav_read.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- nav_read.c 11 Mar 2005 02:40:28 -0000 1.5
+++ nav_read.c 30 Jun 2005 22:48:26 -0000 1.6
@@ -1,9 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort at dtek.chalmers.se>
- *
- * Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
- * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
- * $Id$
+ * Copyright (C) 2000, 2001, 2002, 2003 Håkan Hjort <d95hjort at dtek.chalmers.se>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,20 +16,21 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
+
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
-//#include <assert.h>
-#include "config.h" // Needed for WORDS_BIGENDIAN
#include "bswap.h"
#include "nav_types.h"
#include "nav_read.h"
+#include "dvdread_internal.h"
void navRead_PCI(pci_t *pci, unsigned char *buffer) {
- int i, j, k;
+ int i, j;
- assert(sizeof(pci_t) == PCI_BYTES - 1); // -1 for substream id
+ CHECK_VALUE(sizeof(pci_t) == PCI_BYTES - 1); // -1 for substream id
memcpy(pci, buffer, sizeof(pci_t));
@@ -61,84 +58,99 @@
for(j = 0; j < 2; j++)
B2N_32(pci->hli.btn_colit.btn_coli[i][j]);
-#if !defined(WORDS_BIGENDIAN)
+ /* NOTE: I've had to change the structure from the disk layout to get
+ * the packing to work with Sun's Forte C compiler. */
+
/* pci hli btni */
for(i = 0; i < 36; i++) {
- char tmp[6], swap;
- memcpy(tmp, &(pci->hli.btnit[i]), 6);
- /* This is a B2N_24() */
- swap = tmp[0]; tmp[0] = tmp[2]; tmp[2] = swap;
- /* This is a B2N_24() */
- swap = tmp[3]; tmp[3] = tmp[5]; tmp[5] = swap;
- memcpy(&(pci->hli.btnit[i]), tmp, 6);
- }
+ char tmp[sizeof(pci->hli.btnit[i])], swap;
+ memcpy(tmp, &(pci->hli.btnit[i]), sizeof(pci->hli.btnit[i]));
+ /* Byte 4 to 7 are 'rotated' was: ABCD EFGH IJ is: ABCG DEFH IJ */
+ swap = tmp[6];
+ tmp[6] = tmp[5];
+ tmp[5] = tmp[4];
+ tmp[4] = tmp[3];
+ tmp[3] = swap;
+
+ /* Then there are the two B2N_24(..) calls */
+#ifndef WORDS_BIGENDIAN
+ swap = tmp[0];
+ tmp[0] = tmp[2];
+ tmp[2] = swap;
+
+ swap = tmp[4];
+ tmp[4] = tmp[6];
+ tmp[6] = swap;
#endif
+ memcpy(&(pci->hli.btnit[i]), tmp, sizeof(pci->hli.btnit[i]));
+ }
+#ifndef NDEBUG
/* Asserts */
/* pci pci gi */
- assert(pci->pci_gi.zero1 == 0);
+ CHECK_VALUE(pci->pci_gi.zero1 == 0);
/* pci hli hli_gi */
- assert(pci->hli.hl_gi.zero1 == 0);
- assert(pci->hli.hl_gi.zero2 == 0);
- assert(pci->hli.hl_gi.zero3 == 0);
- assert(pci->hli.hl_gi.zero4 == 0);
- assert(pci->hli.hl_gi.zero5 == 0);
+ CHECK_VALUE(pci->hli.hl_gi.zero1 == 0);
+ CHECK_VALUE(pci->hli.hl_gi.zero2 == 0);
+ CHECK_VALUE(pci->hli.hl_gi.zero3 == 0);
+ CHECK_VALUE(pci->hli.hl_gi.zero4 == 0);
+ CHECK_VALUE(pci->hli.hl_gi.zero5 == 0);
/* Are there buttons defined here? */
if((pci->hli.hl_gi.hli_ss & 0x03) != 0) {
- assert(pci->hli.hl_gi.btn_ns != 0);
- assert(pci->hli.hl_gi.btngr_ns != 0);
+ CHECK_VALUE(pci->hli.hl_gi.btn_ns != 0);
+ CHECK_VALUE(pci->hli.hl_gi.btngr_ns != 0);
} else {
- assert((pci->hli.hl_gi.btn_ns != 0 && pci->hli.hl_gi.btngr_ns != 0)
+ CHECK_VALUE((pci->hli.hl_gi.btn_ns != 0 && pci->hli.hl_gi.btngr_ns != 0)
|| (pci->hli.hl_gi.btn_ns == 0 && pci->hli.hl_gi.btngr_ns == 0));
}
/* pci hli btnit */
for(i = 0; i < pci->hli.hl_gi.btngr_ns; i++) {
for(j = 0; j < (36 / pci->hli.hl_gi.btngr_ns); j++) {
-#ifdef HAVE_ASSERT_H
int n = (36 / pci->hli.hl_gi.btngr_ns) * i + j;
-#endif
- assert(pci->hli.btnit[n].zero1 == 0);
- assert(pci->hli.btnit[n].zero2 == 0);
- assert(pci->hli.btnit[n].zero3 == 0);
- assert(pci->hli.btnit[n].zero4 == 0);
- assert(pci->hli.btnit[n].zero5 == 0);
- assert(pci->hli.btnit[n].zero6 == 0);
+ CHECK_VALUE(pci->hli.btnit[n].zero1 == 0);
+ CHECK_VALUE(pci->hli.btnit[n].zero2 == 0);
+ CHECK_VALUE(pci->hli.btnit[n].zero3 == 0);
+ CHECK_VALUE(pci->hli.btnit[n].zero4 == 0);
+ CHECK_VALUE(pci->hli.btnit[n].zero5 == 0);
+ CHECK_VALUE(pci->hli.btnit[n].zero6 == 0);
if (j < pci->hli.hl_gi.btn_ns) {
- assert(pci->hli.btnit[n].x_start <= pci->hli.btnit[n].x_end);
- assert(pci->hli.btnit[n].y_start <= pci->hli.btnit[n].y_end);
- assert(pci->hli.btnit[n].up <= pci->hli.hl_gi.btn_ns);
- assert(pci->hli.btnit[n].down <= pci->hli.hl_gi.btn_ns);
- assert(pci->hli.btnit[n].left <= pci->hli.hl_gi.btn_ns);
- assert(pci->hli.btnit[n].right <= pci->hli.hl_gi.btn_ns);
+ CHECK_VALUE(pci->hli.btnit[n].x_start <= pci->hli.btnit[n].x_end);
+ CHECK_VALUE(pci->hli.btnit[n].y_start <= pci->hli.btnit[n].y_end);
+ CHECK_VALUE(pci->hli.btnit[n].up <= pci->hli.hl_gi.btn_ns);
+ CHECK_VALUE(pci->hli.btnit[n].down <= pci->hli.hl_gi.btn_ns);
+ CHECK_VALUE(pci->hli.btnit[n].left <= pci->hli.hl_gi.btn_ns);
+ CHECK_VALUE(pci->hli.btnit[n].right <= pci->hli.hl_gi.btn_ns);
//vmcmd_verify(pci->hli.btnit[n].cmd);
} else {
- assert(pci->hli.btnit[n].btn_coln == 0);
- assert(pci->hli.btnit[n].auto_action_mode == 0);
- assert(pci->hli.btnit[n].x_start == 0);
- assert(pci->hli.btnit[n].y_start == 0);
- assert(pci->hli.btnit[n].x_end == 0);
- assert(pci->hli.btnit[n].y_end == 0);
- assert(pci->hli.btnit[n].up == 0);
- assert(pci->hli.btnit[n].down == 0);
- assert(pci->hli.btnit[n].left == 0);
- assert(pci->hli.btnit[n].right == 0);
+ int k;
+ CHECK_VALUE(pci->hli.btnit[n].btn_coln == 0);
+ CHECK_VALUE(pci->hli.btnit[n].auto_action_mode == 0);
+ CHECK_VALUE(pci->hli.btnit[n].x_start == 0);
+ CHECK_VALUE(pci->hli.btnit[n].y_start == 0);
+ CHECK_VALUE(pci->hli.btnit[n].x_end == 0);
+ CHECK_VALUE(pci->hli.btnit[n].y_end == 0);
+ CHECK_VALUE(pci->hli.btnit[n].up == 0);
+ CHECK_VALUE(pci->hli.btnit[n].down == 0);
+ CHECK_VALUE(pci->hli.btnit[n].left == 0);
+ CHECK_VALUE(pci->hli.btnit[n].right == 0);
for (k = 0; k < 8; k++)
- assert(pci->hli.btnit[n].cmd.bytes[k] == 0); //CHECK_ZERO?
+ CHECK_VALUE(pci->hli.btnit[n].cmd.bytes[k] == 0); //CHECK_ZERO?
}
}
}
+#endif /* !NDEBUG */
}
void navRead_DSI(dsi_t *dsi, unsigned char *buffer) {
int i;
- assert(sizeof(dsi_t) == DSI_BYTES - 1); // -1 for substream id
+ CHECK_VALUE(sizeof(dsi_t) == DSI_BYTES - 1); // -1 for substream id
memcpy(dsi, buffer, sizeof(dsi_t));
@@ -187,6 +199,6 @@
/* Asserts */
/* dsi dsi gi */
- assert(dsi->dsi_gi.zero1 == 0);
+ CHECK_VALUE(dsi->dsi_gi.zero1 == 0);
}
Index: nav_read.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/nav_read.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- nav_read.h 11 Mar 2005 02:40:28 -0000 1.3
+++ nav_read.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -2,7 +2,7 @@
#define NAV_READ_H_INCLUDED
/*
- * Copyright (C) 2000, 2001 Håkan Hjort <d95hjort at dtek.chalmers.se>.
+ * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort at dtek.chalmers.se>.
*
* Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
* detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
@@ -25,17 +25,27 @@
#include "nav_types.h"
+/**
+ * Parsing of NAV data, PCI and DSI parts.
+ */
+
#ifdef __cplusplus
extern "C" {
#endif
/**
- * Reads the PCI packet data pointed to into pci struct.
- */
+ * Reads the PCI packet data pointed to into th pci struct.
+ *
+ * @param pci Pointer to the PCI data structure to be filled in.
+ * @param bufffer Pointer to the buffer of the on disc PCI data.
+ */
void navRead_PCI(pci_t *, unsigned char *);
/**
* Reads the DSI packet data pointed to into dsi struct.
+ *
+ * @param dsi Pointer to the DSI data structure to be filled in.
+ * @param bufffer Pointer to the buffer of the on disc DSI data.
*/
void navRead_DSI(dsi_t *, unsigned char *);
Index: nav_types.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdvdkit2/nav_types.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- nav_types.h 11 Mar 2005 02:40:28 -0000 1.3
+++ nav_types.h 30 Jun 2005 22:48:26 -0000 1.4
@@ -2,7 +2,7 @@
#define NAV_TYPES_H_INCLUDED
/*
- * Copyright (C) 2000, 2001 Håkan Hjort <d95hjort at dtek.chalmers.se>
+ * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort at dtek.chalmers.se>
*
* Modified for use with MPlayer, changes contained in libdvdread_changes.diff.
* detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
@@ -34,7 +34,7 @@
*/
#include <inttypes.h>
-#include "ifo_types.h" // only dvd_time_t, vm_cmd_t and user_ops_t
+#include "ifo_types.h" /* only dvd_time_t, vm_cmd_t and user_ops_t */
#undef ATTRIBUTE_PACKED
@@ -74,14 +74,14 @@
* PCI General Information
*/
typedef struct {
- uint32_t nv_pck_lbn;
- uint16_t vobu_cat;
- uint16_t zero1;
- user_ops_t vobu_uop_ctl;
- uint32_t vobu_s_ptm;
- uint32_t vobu_e_ptm;
- uint32_t vobu_se_e_ptm;
- dvd_time_t e_eltm;
+ uint32_t nv_pck_lbn; /**< sector address of this nav pack */
+ uint16_t vobu_cat; /**< 'category' of vobu */
+ uint16_t zero1; /**< reserved */
+ user_ops_t vobu_uop_ctl; /**< UOP of vobu */
+ uint32_t vobu_s_ptm; /**< start presentation time of vobu */
+ uint32_t vobu_e_ptm; /**< end presentation time of vobu */
+ uint32_t vobu_se_e_ptm; /**< end ptm of sequence end in vobu */
+ dvd_time_t e_eltm; /**< Cell elapsed time */
char vobu_isrc[32];
} ATTRIBUTE_PACKED pci_gi_t;
@@ -89,26 +89,32 @@
* Non Seamless Angle Information
*/
typedef struct {
- uint32_t nsml_agl_dsta[9];
+ uint32_t nsml_agl_dsta[9]; /**< address of destination vobu in AGL_C#n */
} ATTRIBUTE_PACKED nsml_agli_t;
/**
* Highlight General Information
+ *
+ * For btngrX_dsp_ty the bits have the following meaning:
+ * 000b: normal 4/3 only buttons
+ * XX1b: wide (16/9) buttons
+ * X1Xb: letterbox buttons
+ * 1XXb: pan&scan buttons
*/
typedef struct {
- uint16_t hli_ss; ///< only low 2 bits
- uint32_t hli_s_ptm;
- uint32_t hli_e_ptm;
- uint32_t btn_se_e_ptm;
+ uint16_t hli_ss; /**< status, only low 2 bits 0: no buttons, 1: different 2: equal 3: eual except for button cmds */
+ uint32_t hli_s_ptm; /**< start ptm of hli */
+ uint32_t hli_e_ptm; /**< end ptm of hli */
+ uint32_t btn_se_e_ptm; /**< end ptm of button select */
#ifdef WORDS_BIGENDIAN
- unsigned int zero1 : 2;
- unsigned int btngr_ns : 2;
- unsigned int zero2 : 1;
- unsigned int btngr1_dsp_ty : 3;
- unsigned int zero3 : 1;
- unsigned int btngr2_dsp_ty : 3;
- unsigned int zero4 : 1;
- unsigned int btngr3_dsp_ty : 3;
+ unsigned int zero1 : 2; /**< reserved */
+ unsigned int btngr_ns : 2; /**< number of button groups 1, 2 or 3 with 36/18/12 buttons */
+ unsigned int zero2 : 1; /**< reserved */
+ unsigned int btngr1_dsp_ty : 3; /**< display type of subpic stream for button group 1 */
+ unsigned int zero3 : 1; /**< reserved */
+ unsigned int btngr2_dsp_ty : 3; /**< display type of subpic stream for button group 2 */
+ unsigned int zero4 : 1; /**< reserved */
+ unsigned int btngr3_dsp_ty : 3; /**< display type of subpic stream for button group 3 */
#else
unsigned int btngr1_dsp_ty : 3;
unsigned int zero2 : 1;
@@ -119,56 +125,69 @@
unsigned int btngr2_dsp_ty : 3;
unsigned int zero3 : 1;
#endif
- uint8_t btn_ofn;
- uint8_t btn_ns; ///< only low 6 bits
- uint8_t nsl_btn_ns; ///< only low 6 bits
- uint8_t zero5;
- uint8_t fosl_btnn; ///< only low 6 bits
- uint8_t foac_btnn; ///< only low 6 bits
+ uint8_t btn_ofn; /**< button offset number range 0-255 */
+ uint8_t btn_ns; /**< number of valid buttons <= 36/18/12 (low 6 bits) */
+ uint8_t nsl_btn_ns; /**< number of buttons selectable by U_BTNNi (low 6 bits) nsl_btn_ns <= btn_ns */
+ uint8_t zero5; /**< reserved */
+ uint8_t fosl_btnn; /**< forcedly selected button (low 6 bits) */
+ uint8_t foac_btnn; /**< forcedly activated button (low 6 bits) */
} ATTRIBUTE_PACKED hl_gi_t;
/**
* Button Color Information Table
+ * Each entry beeing a 32bit word that contains the color indexs and alpha
+ * values to use. They are all represented by 4 bit number and stored
+ * like this [Ci3, Ci2, Ci1, Ci0, A3, A2, A1, A0]. The actual palette
+ * that the indexes reference is in the PGC.
+ * @TODO split the uint32_t into a struct
*/
typedef struct {
- uint32_t btn_coli[3][2];
+ uint32_t btn_coli[3][2]; /**< [button color number-1][select:0/action:1] */
} ATTRIBUTE_PACKED btn_colit_t;
/**
* Button Information
+ *
+ * NOTE: I've had to change the structure from the disk layout to get
+ * the packing to work with Sun's Forte C compiler.
+ * The 4 and 7 bytes are 'rotated' was: ABC DEF GHIJ is: ABCG DEFH IJ
*/
typedef struct {
#ifdef WORDS_BIGENDIAN
- unsigned int btn_coln : 2;
- unsigned int x_start : 10;
- unsigned int zero1 : 2;
- unsigned int x_end : 10;
- unsigned int auto_action_mode : 2;
- unsigned int y_start : 10;
- unsigned int zero2 : 2;
- unsigned int y_end : 10;
-
- unsigned int zero3 : 2;
- unsigned int up : 6;
- unsigned int zero4 : 2;
- unsigned int down : 6;
- unsigned int zero5 : 2;
- unsigned int left : 6;
- unsigned int zero6 : 2;
- unsigned int right : 6;
+ unsigned int btn_coln : 2; /**< button color number */
+ unsigned int x_start : 10; /**< x start offset within the overlay */
+ unsigned int zero1 : 2; /**< reserved */
+ unsigned int x_end : 10; /**< x end offset within the overlay */
+
+ unsigned int zero3 : 2; /**< reserved */
+ unsigned int up : 6; /**< button index when pressing up */
+
+ unsigned int auto_action_mode : 2; /**< 0: no, 1: activated if selected */
+ unsigned int y_start : 10; /**< y start offset within the overlay */
+ unsigned int zero2 : 2; /**< reserved */
+ unsigned int y_end : 10; /**< y end offset within the overlay */
+
+ unsigned int zero4 : 2; /**< reserved */
+ unsigned int down : 6; /**< button index when pressing down */
+ unsigned int zero5 : 2; /**< reserved */
+ unsigned int left : 6; /**< button index when pressing left */
+ unsigned int zero6 : 2; /**< reserved */
+ unsigned int right : 6; /**< button index when pressing right */
#else
unsigned int x_end : 10;
unsigned int zero1 : 2;
unsigned int x_start : 10;
unsigned int btn_coln : 2;
+
+ unsigned int up : 6;
+ unsigned int zero3 : 2;
+
unsigned int y_end : 10;
unsigned int zero2 : 2;
unsigned int y_start : 10;
unsigned int auto_action_mode : 2;
- unsigned int up : 6;
- unsigned int zero3 : 2;
unsigned int down : 6;
unsigned int zero4 : 2;
unsigned int left : 6;
@@ -206,27 +225,27 @@
*/
typedef struct {
uint32_t nv_pck_scr;
- uint32_t nv_pck_lbn;
- uint32_t vobu_ea;
- uint32_t vobu_1stref_ea;
- uint32_t vobu_2ndref_ea;
- uint32_t vobu_3rdref_ea;
- uint16_t vobu_vob_idn;
- uint8_t zero1;
- uint8_t vobu_c_idn;
- dvd_time_t c_eltm;
+ uint32_t nv_pck_lbn; /**< sector address of this nav pack */
+ uint32_t vobu_ea; /**< end address of this VOBU */
+ uint32_t vobu_1stref_ea; /**< end address of the 1st reference image */
+ uint32_t vobu_2ndref_ea; /**< end address of the 2nd reference image */
+ uint32_t vobu_3rdref_ea; /**< end address of the 3rd reference image */
+ uint16_t vobu_vob_idn; /**< VOB Id number that this VOBU is part of */
+ uint8_t zero1; /**< reserved */
+ uint8_t vobu_c_idn; /**< Cell Id number that this VOBU is part of */
+ dvd_time_t c_eltm; /**< Cell elapsed time */
} ATTRIBUTE_PACKED dsi_gi_t;
/**
* Seamless Playback Information
*/
typedef struct {
- uint16_t category; ///< category of seamless VOBU
- uint32_t ilvu_ea; ///< end address of interleaved Unit (sectors)
- uint32_t ilvu_sa; ///< start address of next interleaved unit (sectors)
- uint16_t size; ///< size of next interleaved unit (sectors)
- uint32_t vob_v_s_s_ptm; ///< video start ptm in vob
- uint32_t vob_v_e_e_ptm; ///< video end ptm in vob
+ uint16_t category; /**< 'category' of seamless VOBU */
+ uint32_t ilvu_ea; /**< end address of interleaved Unit */
+ uint32_t ilvu_sa; /**< start address of next interleaved unit */
+ uint16_t size; /**< size of next interleaved unit */
+ uint32_t vob_v_s_s_ptm; /**< video start ptm in vob */
+ uint32_t vob_v_e_e_ptm; /**< video end ptm in vob */
struct {
uint32_t stp_ptm1;
uint32_t stp_ptm2;
@@ -239,8 +258,8 @@
* Seamless Angle Infromation for one angle
*/
typedef struct {
- uint32_t address; ///< Sector offset to next ILVU, high bit is before/after
- uint16_t size; ///< Byte size of the ILVU poited to by address.
+ uint32_t address; /**< offset to next ILVU, high bit is before/after */
+ uint16_t size; /**< byte size of the ILVU pointed to by address */
} ATTRIBUTE_PACKED sml_agl_data_t;
/**
@@ -254,11 +273,11 @@
* VOBU Search Information
*/
typedef struct {
- uint32_t next_video; ///< Next vobu that contains video
- uint32_t fwda[19]; ///< Forwards, time
+ uint32_t next_video; /**< Next vobu that contains video */
+ uint32_t fwda[19]; /**< Forwards, time */
uint32_t next_vobu;
uint32_t prev_vobu;
- uint32_t bwda[19]; ///< Backwards, time
+ uint32_t bwda[19]; /**< Backwards, time */
uint32_t prev_video;
} ATTRIBUTE_PACKED vobu_sri_t;
@@ -268,8 +287,8 @@
* Synchronous Information
*/
typedef struct {
- uint16_t a_synca[8]; ///< Sector offset to first audio packet for this VOBU
- uint32_t sp_synca[32]; ///< Sector offset to first subpicture packet
+ uint16_t a_synca[8]; /**< offset to first audio packet for this VOBU */
+ uint32_t sp_synca[32]; /**< offset to first subpicture packet */
} ATTRIBUTE_PACKED synci_t;
/**
More information about the MPlayer-cvslog
mailing list