summaryrefslogtreecommitdiffstats
path: root/libmpdvdkit2/dvd_input.c
diff options
context:
space:
mode:
authoraurel <aurel@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-06-30 22:48:26 +0000
committeraurel <aurel@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-06-30 22:48:26 +0000
commiteb3c1b5cedfc1b7d35a2d261780979b00170946e (patch)
treeccc33eb81679684b7f2ca3d7c610d721375c4ea5 /libmpdvdkit2/dvd_input.c
parentc8fbf4405d7b433f0dc622bc9dcf81d0ceb5ef36 (diff)
downloadmpv-eb3c1b5cedfc1b7d35a2d261780979b00170946e.tar.bz2
mpv-eb3c1b5cedfc1b7d35a2d261780979b00170946e.tar.xz
update libdvdread to v0.9.4
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@15875 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdvdkit2/dvd_input.c')
-rw-r--r--libmpdvdkit2/dvd_input.c257
1 files changed, 223 insertions, 34 deletions
diff --git a/libmpdvdkit2/dvd_input.c b/libmpdvdkit2/dvd_input.c
index a5c0e7f0d4..840d8e2086 100644
--- a/libmpdvdkit2/dvd_input.c
+++ b/libmpdvdkit2/dvd_input.c
@@ -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"
-
-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);
+/* 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);
-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 @@ struct dvd_input_s {
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 @@ static dvd_input_t css_open(const char *target)
/* 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 @@ static char *css_error(dvd_input_t dev)
/**
* 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 @@ static int css_close(dvd_input_t dev)
+
+
+
+/**
+ * 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;
+ }
}