summaryrefslogtreecommitdiffstats
path: root/contrib/libdvdnav/A08-dvdnav-dup.patch
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libdvdnav/A08-dvdnav-dup.patch')
-rw-r--r--contrib/libdvdnav/A08-dvdnav-dup.patch137
1 files changed, 137 insertions, 0 deletions
diff --git a/contrib/libdvdnav/A08-dvdnav-dup.patch b/contrib/libdvdnav/A08-dvdnav-dup.patch
new file mode 100644
index 000000000..ce6072a4c
--- /dev/null
+++ b/contrib/libdvdnav/A08-dvdnav-dup.patch
@@ -0,0 +1,137 @@
+Index: src/dvdnav.c
+===================================================================
+--- libdvdnav.orig/src/dvdnav.c (revision 1168)
++++ libdvdnav/src/dvdnav.c (working copy)
+@@ -71,6 +71,67 @@
+ return DVDNAV_STATUS_OK;
+ }
+
++dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src) {
++ dvdnav_t *this;
++
++ (*dest) = NULL;
++ this = (dvdnav_t*)malloc(sizeof(dvdnav_t));
++ if(!this)
++ return DVDNAV_STATUS_ERR;
++
++ memcpy(this, src, sizeof(dvdnav_t));
++ this->file = NULL;
++
++ pthread_mutex_init(&this->vm_lock, NULL);
++
++ this->vm = vm_new_copy(src->vm);
++ if(!this->vm) {
++ printerr("Error initialising the DVD VM.");
++ pthread_mutex_destroy(&this->vm_lock);
++ free(this);
++ return DVDNAV_STATUS_ERR;
++ }
++
++ /* Start the read-ahead cache. */
++ this->cache = dvdnav_read_cache_new(this);
++
++ (*dest) = this;
++ return DVDNAV_STATUS_OK;
++}
++
++dvdnav_status_t dvdnav_free_dup(dvdnav_t *this) {
++
++#ifdef LOG_DEBUG
++ fprintf(MSG_OUT, "libdvdnav: free_dup:called\n");
++#endif
++
++ if (this->file) {
++ pthread_mutex_lock(&this->vm_lock);
++ DVDCloseFile(this->file);
++#ifdef LOG_DEBUG
++ fprintf(MSG_OUT, "libdvdnav: close:file closing\n");
++#endif
++ this->file = NULL;
++ pthread_mutex_unlock(&this->vm_lock);
++ }
++
++ /* Free the VM */
++ if(this->vm)
++ vm_free_copy(this->vm);
++
++ pthread_mutex_destroy(&this->vm_lock);
++
++ /* We leave the final freeing of the entire structure to the cache,
++ * because we don't know, if there are still buffers out in the wild,
++ * that must return first. */
++ if(this->cache)
++ dvdnav_read_cache_free(this->cache);
++ else
++ free(this);
++
++ return DVDNAV_STATUS_OK;
++}
++
+ dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) {
+ dvdnav_t *this;
+ struct timeval time;
+Index: src/dvdnav/dvdnav.h
+===================================================================
+--- libdvdnav.orig/src/dvdnav/dvdnav.h (revision 1168)
++++ libdvdnav/src/dvdnav/dvdnav.h (working copy)
+@@ -89,6 +89,9 @@
+ */
+ dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path);
+
++dvdnav_status_t dvdnav_dup(dvdnav_t **dest, dvdnav_t *src);
++dvdnav_status_t dvdnav_free_dup(dvdnav_t *this);
++
+ /*
+ * Closes a dvdnav_t previously opened with dvdnav_open(), freeing any
+ * memory associated with it.
+Index: src/vm/vm.c
+===================================================================
+--- libdvdnav.orig/src/vm/vm.c (revision 1168)
++++ libdvdnav/src/vm/vm.c (working copy)
+@@ -96,6 +98,7 @@
+
+ static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang);
+ static pgcit_t* get_PGCIT(vm_t *vm);
++static void vm_close(vm_t *vm);
+
+
+ /* Helper functions */
+@@ -262,7 +265,7 @@
+ }
+
+ void vm_free_vm(vm_t *vm) {
+- vm_stop(vm);
++ vm_close(vm);
+ free(vm);
+ }
+
+@@ -289,12 +292,20 @@
+
+ int vm_start(vm_t *vm) {
+ /* Set pgc to FP (First Play) pgc */
++ if (vm->stopped) {
++ vm_reset(vm, NULL);
++ vm->stopped = 0;
++ }
+ set_FP_PGC(vm);
+ process_command(vm, play_PGC(vm));
+ return !vm->stopped;
+ }
+
+ void vm_stop(vm_t *vm) {
++ vm->stopped = 1;
++}
++
++static void vm_close(vm_t *vm) {
+ if(vm->vmgi) {
+ ifoClose(vm->vmgi);
+ vm->vmgi=NULL;
+@@ -346,7 +357,7 @@
+
+ if (vm->dvd && dvdroot) {
+ /* a new dvd device has been requested */
+- vm_stop(vm);
++ vm_close(vm);
+ }
+ if (!vm->dvd) {
+ vm->dvd = DVDOpen(dvdroot);