[libdvdnav-devel] add dvdnav_open_stream

Thomas Guillem git at videolan.org
Tue Jan 27 16:59:32 CET 2015


libdvdnav | branch: master | Thomas Guillem <tom at gllm.fr> | Fri Oct 17 15:45:34 2014 +0200| [48102c2a5252e2e4ce3e2d71154c79ba8e339de9] | committer: Jean-Baptiste Kempf

add dvdnav_open_stream

open a DVD Device using external read/seek callbacks (see libdvdcss).

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/libdvdnav.git/?a=commit;h=48102c2a5252e2e4ce3e2d71154c79ba8e339de9
---

 ChangeLog           |    3 +++
 configure.ac        |    2 +-
 src/dvdnav.c        |   26 ++++++++++++++++++++------
 src/dvdnav/dvdnav.h |   16 +++++++++++-----
 src/vm/vm.c         |   12 ++++++++----
 src/vm/vm.h         |    3 ++-
 6 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 93e53dc..8cc42a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+libdvdnav (5.0.3)
+ * added dvdnav_open_stream to read from external read/seek callbacks
+
 libdvdnav (5.0.2)
  * fixed 2 wrong asserts (LP #1236939, #570790)
  * fixed 2 crashes (in dvdnav_get_position and dvdnav_get_position_in_title)
diff --git a/configure.ac b/configure.ac
index b29d879..786efbe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,7 +97,7 @@ esac
 AC_SUBST(THREAD_LIBS)
 AC_SUBST(THREAD_CFLAGS)
 
-PKG_CHECK_MODULES([DVDREAD], [dvdread])
+PKG_CHECK_MODULES([DVDREAD], [dvdread >= 5.0.2])
 
 dnl ---------------------------------------------
 dnl Check for bitfield compiler flag
diff --git a/src/dvdnav.c b/src/dvdnav.c
index 69bc4f8..ae267d5 100644
--- a/src/dvdnav.c
+++ b/src/dvdnav.c
@@ -145,7 +145,9 @@ dvdnav_status_t dvdnav_free_dup(dvdnav_t *this) {
   return DVDNAV_STATUS_OK;
 }
 
-dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
+static dvdnav_status_t dvdnav_open_common(dvdnav_t** dest, const char *path,
+                                          void *stream,
+                                          dvdnav_stream_cb *stream_cb) {
   dvdnav_t *this;
   struct timeval time;
 
@@ -167,15 +169,18 @@ dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
     printerr("Error initialising the DVD VM.");
     goto fail;
   }
-  if(!vm_reset(this->vm, path)) {
+  if(!vm_reset(this->vm, path, stream, stream_cb)) {
     printerr("Error starting the VM / opening the DVD device.");
     goto fail;
   }
 
   /* Set the path. */
-  this->path = strdup(path);
-  if(!this->path)
-    goto fail;
+  if(path != NULL)
+  {
+    this->path = strdup(path);
+    if(!this->path)
+      goto fail;
+  }
 
   /* Pre-open and close a file so that the CSS-keys are cached. */
   this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), 0, DVD_READ_MENU_VOBS);
@@ -203,6 +208,15 @@ fail:
   return DVDNAV_STATUS_ERR;
 }
 
+dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
+  return dvdnav_open_common(dest, path, NULL, NULL);
+}
+
+dvdnav_status_t dvdnav_open_stream(dvdnav_t** dest,
+                                   void *stream, dvdnav_stream_cb *stream_cb) {
+  return dvdnav_open_common(dest, NULL, stream, stream_cb);
+}
+
 dvdnav_status_t dvdnav_close(dvdnav_t *this) {
 
 #ifdef LOG_DEBUG
@@ -250,7 +264,7 @@ dvdnav_status_t dvdnav_reset(dvdnav_t *this) {
 #ifdef LOG_DEBUG
   fprintf(MSG_OUT, "libdvdnav: reseting vm\n");
 #endif
-  if(!vm_reset(this->vm, NULL)) {
+  if(!vm_reset(this->vm, NULL, NULL, NULL)) {
     printerr("Error restarting the VM.");
     pthread_mutex_unlock(&this->vm_lock);
     return DVDNAV_STATUS_ERR;
diff --git a/src/dvdnav/dvdnav.h b/src/dvdnav/dvdnav.h
index 4254534..8894fe5 100644
--- a/src/dvdnav/dvdnav.h
+++ b/src/dvdnav/dvdnav.h
@@ -55,6 +55,8 @@ typedef struct dvdnav_s dvdnav_t;
 /* Status as reported by most of libdvdnav's functions */
 typedef int32_t dvdnav_status_t;
 
+typedef dvd_reader_stream_cb dvdnav_stream_cb;
+
 /*
  * Unless otherwise stated, all functions return DVDNAV_STATUS_OK if
  * they succeeded, otherwise DVDNAV_STATUS_ERR is returned and the error may
@@ -73,15 +75,19 @@ typedef int32_t dvdnav_status_t;
  */
 
 /*
- * Attempts to open the DVD drive at the specified path and pre-cache
- * the CSS-keys. libdvdread is used to access the DVD, so any source
- * supported by libdvdread can be given with "path". Currently,
- * libdvdread can access: DVD drives, DVD image files, DVD file-by-file
- * copies.
+ * Attempts to open the DVD drive at the specified path or using external
+ * seek/read functions (dvdnav_open_stream) and pre-cache the CSS-keys.
+ * libdvdread is used to access the DVD, so any source supported by libdvdread
+ * can be given with "path" or "stream_cb".  Currently, using dvdnav_open,
+ * libdvdread can access : DVD drives, DVD image files, DVD file-by-file
+ * copies. Using dvdnav_open_stream, libdvdread can access any kind of DVD
+ * storage via custom implementation of seek/read functions.
  *
  * The resulting dvdnav_t handle will be written to *dest.
  */
 dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path);
+dvdnav_status_t
+dvdnav_open_stream(dvdnav_t **dest, void *stream, dvdnav_stream_cb *stream_cb);
 
 dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src);
 dvdnav_status_t dvdnav_free_dup(dvdnav_t * _this);
diff --git a/src/vm/vm.c b/src/vm/vm.c
index 1e87376..869dd05 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -292,7 +292,7 @@ dvd_reader_t *vm_get_dvd_reader(vm_t *vm) {
 
 int vm_start(vm_t *vm) {
   if (vm->stopped) {
-    if (!vm_reset(vm, NULL))
+    if (!vm_reset(vm, NULL, NULL, NULL))
       return 0;
 
     vm->stopped = 0;
@@ -325,7 +325,8 @@ static void vm_close(vm_t *vm) {
   vm->stopped = 1;
 }
 
-int vm_reset(vm_t *vm, const char *dvdroot) {
+int vm_reset(vm_t *vm, const char *dvdroot,
+             void *stream, dvdnav_stream_cb *stream_cb) {
   /*  Setup State */
   memset(vm->state.registers.SPRM, 0, sizeof(vm->state.registers.SPRM));
   memset(vm->state.registers.GPRM, 0, sizeof(vm->state.registers.GPRM));
@@ -362,12 +363,15 @@ int vm_reset(vm_t *vm, const char *dvdroot) {
 
   vm->hop_channel                = 0;
 
-  if (vm->dvd && dvdroot) {
+  if (vm->dvd && (dvdroot || (stream && stream_cb))) {
     /* a new dvd device has been requested */
     vm_close(vm);
   }
   if (!vm->dvd) {
-    vm->dvd = DVDOpen(dvdroot);
+    if(dvdroot)
+        vm->dvd = DVDOpen(dvdroot);
+    else if(stream && stream_cb)
+        vm->dvd = DVDOpenStream(stream, (dvd_reader_stream_cb *)stream_cb);
     if(!vm->dvd) {
       fprintf(MSG_OUT, "libdvdnav: vm: failed to open/read the DVD\n");
       return 0;
diff --git a/src/vm/vm.h b/src/vm/vm.h
index 57498d2..e4b01c2 100644
--- a/src/vm/vm.h
+++ b/src/vm/vm.h
@@ -114,7 +114,8 @@ dvd_reader_t *vm_get_dvd_reader(vm_t *vm);
 /* Basic Handling */
 int  vm_start(vm_t *vm);
 void vm_stop(vm_t *vm);
-int  vm_reset(vm_t *vm, const char *dvdroot);
+int  vm_reset(vm_t *vm, const char *dvdroot, void *stream,
+              dvdnav_stream_cb *stream_cb);
 
 /* copying and merging  - useful for try-running an operation */
 vm_t *vm_new_copy(vm_t *vm);



More information about the libdvdnav-devel mailing list