summaryrefslogtreecommitdiffstats
path: root/contrib/libdvdnav/A08-dvdnav-dup.patch
blob: ce6072a4ce16fb3b4257d0f62a8db245bfef9dc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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);