OSDN Git Service

import original 0.9.5 release
[handbrake-jp/handbrake-jp.git] / contrib / libdvdnav / A08-dvdnav-dup.patch
diff --git a/contrib/libdvdnav/A08-dvdnav-dup.patch b/contrib/libdvdnav/A08-dvdnav-dup.patch
new file mode 100644 (file)
index 0000000..ce6072a
--- /dev/null
@@ -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);