Mercurial > libdvdnav.hg
annotate searching.c @ 167:e9987c07e255 src
some code beautification:
* rename vm_resume to vm_jump_resume for consistency's sake
* functions in vm.c do not return dvdnav_status_t, but simple C boolean
(that is 1 or 0)
* set the pgcN for the first play PGC
author | mroi |
---|---|
date | Mon, 21 Apr 2003 13:24:31 +0000 |
parents | 3bfaec0c1288 |
children | 5d9770cb2961 |
rev | line source |
---|---|
131 | 1 /* |
0 | 2 * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> |
3 * | |
4 * This file is part of libdvdnav, a DVD navigation library. | |
5 * | |
6 * libdvdnav is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * libdvdnav is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |
19 * | |
20 * $Id$ | |
21 * | |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include "config.h" | |
26 #endif | |
27 | |
114 | 28 #include <assert.h> |
0 | 29 #include "dvdnav_internal.h" |
30 | |
114 | 31 /* |
32 #define LOG_DEBUG | |
33 */ | |
34 | |
0 | 35 /* Searching API calls */ |
36 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
37 dvdnav_status_t dvdnav_time_search(dvdnav_t *this, |
0 | 38 unsigned long int time) { |
114 | 39 /* FIXME: Time search the current PGC based on the xxx table */ |
0 | 40 return S_OK; |
41 } | |
42 | |
24 | 43 /* Scan the ADMAP for a particular block number. */ |
44 /* Return placed in vobu. */ | |
45 /* Returns error status */ | |
114 | 46 /* FIXME: Maybe need to handle seeking outside current cell. */ |
166 | 47 static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int domain, uint32_t seekto_block, uint32_t *vobu) { |
24 | 48 vobu_admap_t *admap = NULL; |
114 | 49 |
50 #ifdef LOG_DEBUG | |
51 fprintf(MSG_OUT, "libdvdnav: Seeking to target %u ...\n", seekto_block); | |
52 #endif | |
24 | 53 *vobu = -1; |
54 | |
55 /* Search through the VOBU_ADMAP for the nearest VOBU | |
56 * to the target block */ | |
57 switch(domain) { | |
114 | 58 case FP_DOMAIN: |
59 case VMGM_DOMAIN: | |
60 admap = this->vm->vmgi->menu_vobu_admap; | |
61 break; | |
62 case VTSM_DOMAIN: | |
63 admap = this->vm->vtsi->menu_vobu_admap; | |
64 break; | |
65 case VTS_DOMAIN: | |
66 admap = this->vm->vtsi->vts_vobu_admap; | |
67 break; | |
68 default: | |
69 fprintf(MSG_OUT, "libdvdnav: Error: Unknown domain for seeking.\n"); | |
24 | 70 } |
71 if(admap) { | |
166 | 72 uint32_t address = 0; |
73 uint32_t vobu_start, next_vobu; | |
24 | 74 int found = 0; |
75 | |
76 /* Search through ADMAP for best sector */ | |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
77 vobu_start = SRI_END_OF_CELL; |
24 | 78 /* FIXME: Implement a faster search algorithm */ |
79 while((!found) && ((address<<2) < admap->last_byte)) { | |
80 next_vobu = admap->vobu_start_sectors[address]; | |
81 | |
76 | 82 /* fprintf(MSG_OUT, "libdvdnav: Found block %u\n", next_vobu); */ |
24 | 83 |
84 if(vobu_start <= seekto_block && | |
85 next_vobu > seekto_block) { | |
86 found = 1; | |
87 } else { | |
88 vobu_start = next_vobu; | |
89 } | |
90 address ++; | |
91 } | |
92 if(found) { | |
93 *vobu = vobu_start; | |
94 return S_OK; | |
95 } else { | |
76 | 96 fprintf(MSG_OUT, "libdvdnav: Could not locate block\n"); |
24 | 97 return S_ERR; |
98 } | |
99 } | |
76 | 100 fprintf(MSG_OUT, "libdvdnav: admap not located\n"); |
24 | 101 return S_ERR; |
102 } | |
103 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
104 dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, |
114 | 105 unsigned long int offset, int origin) { |
0 | 106 uint32_t target = 0; |
107 uint32_t length = 0; | |
114 | 108 uint32_t first_cell_nr, last_cell_nr, cell_nr; |
0 | 109 int found; |
114 | 110 cell_playback_t *cell; |
0 | 111 dvd_state_t *state; |
112 dvdnav_status_t result; | |
113 | |
114 | 114 if(this->position_current.still != 0) { |
115 printerr("Cannot seek in a still frame."); | |
116 return S_ERR; | |
117 } | |
0 | 118 |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
119 result = dvdnav_get_position(this, &target, &length); |
0 | 120 if(!result) { |
114 | 121 return S_ERR; |
0 | 122 } |
123 | |
114 | 124 pthread_mutex_lock(&this->vm_lock); |
125 state = &(this->vm->state); | |
126 if(!state->pgc) { | |
127 printerr("No current PGC."); | |
128 pthread_mutex_unlock(&this->vm_lock); | |
129 return S_ERR; | |
130 } | |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
131 #ifdef LOG_DEBUG |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
132 fprintf(MSG_OUT, "libdvdnav: seeking to offset=%lu pos=%u length=%u\n", offset, target, length); |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
133 fprintf(MSG_OUT, "libdvdnav: Before cellN=%u blockN=%u\n", state->cellN, state->blockN); |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
134 #endif |
114 | 135 |
0 | 136 switch(origin) { |
137 case SEEK_SET: | |
138 if(offset > length) { | |
114 | 139 printerr("Request to seek behind end."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
140 pthread_mutex_unlock(&this->vm_lock); |
114 | 141 return S_ERR; |
0 | 142 } |
143 target = offset; | |
144 break; | |
145 case SEEK_CUR: | |
146 if(target + offset > length) { | |
114 | 147 printerr("Request to seek behind end."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
148 pthread_mutex_unlock(&this->vm_lock); |
114 | 149 return S_ERR; |
0 | 150 } |
151 target += offset; | |
152 break; | |
153 case SEEK_END: | |
154 if(length - offset < 0) { | |
114 | 155 printerr("Request to seek before start."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
156 pthread_mutex_unlock(&this->vm_lock); |
114 | 157 return S_ERR; |
0 | 158 } |
159 target = length - offset; | |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
160 break; |
0 | 161 default: |
162 /* Error occured */ | |
114 | 163 printerr("Illegal seek mode."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
164 pthread_mutex_unlock(&this->vm_lock); |
114 | 165 return S_ERR; |
0 | 166 } |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
167 |
132 | 168 if (this->pgc_based) { |
169 first_cell_nr = 1; | |
170 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 171 } else { |
132 | 172 /* Find start cell of program. */ |
173 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
174 /* Find end cell of program */ | |
175 if(state->pgN < state->pgc->nr_of_programs) | |
176 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
177 else | |
178 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 179 } |
132 | 180 |
114 | 181 found = 0; |
0 | 182 for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { |
183 cell = &(state->pgc->cell_playback[cell_nr-1]); | |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
184 length = cell->last_sector - cell->first_sector + 1; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
185 if (target >= length) { |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
186 target -= length; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
187 } else { |
131 | 188 /* convert the target sector from Cell-relative to absolute physical sector */ |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
189 target += cell->first_sector; |
114 | 190 found = 1; |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
191 break; |
0 | 192 } |
193 } | |
194 | |
114 | 195 if(found) { |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
196 int32_t vobu; |
114 | 197 #ifdef LOG_DEBUG |
76 | 198 fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n", |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
199 cell_nr, first_cell_nr, last_cell_nr); |
114 | 200 #endif |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
201 if (dvdnav_scan_admap(this, state->domain, target, &vobu) == S_OK) { |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
202 int32_t start = state->pgc->cell_playback[cell_nr-1].first_sector; |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
203 |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
204 if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) { |
114 | 205 #ifdef LOG_DEBUG |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
206 fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
207 state->cellN, state->blockN, target, vobu, start); |
114 | 208 #endif |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
209 this->vm->hop_channel += HOP_SEEK; |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
210 pthread_mutex_unlock(&this->vm_lock); |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
211 return S_OK; |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
212 } |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
213 } |
0 | 214 } |
114 | 215 |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
216 fprintf(MSG_OUT, "libdvdnav: Error when seeking\n"); |
76 | 217 fprintf(MSG_OUT, "libdvdnav: FIXME: Implement seeking to location %u\n", target); |
114 | 218 printerr("Error when seeking."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
219 pthread_mutex_unlock(&this->vm_lock); |
114 | 220 return S_ERR; |
0 | 221 } |
222 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
223 dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int part) { |
114 | 224 int title, old_part; |
225 | |
226 if (dvdnav_current_title_info(this, &title, &old_part) == S_OK) | |
227 return dvdnav_part_play(this, title, part); | |
228 return S_ERR; | |
0 | 229 } |
230 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
231 dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *this) { |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
232 |
114 | 233 if(!this) { |
234 printerr("Passed a NULL pointer."); | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
235 return S_ERR; |
114 | 236 } |
237 | |
238 pthread_mutex_lock(&this->vm_lock); | |
239 if(!this->vm->state.pgc) { | |
240 printerr("No current PGC."); | |
241 pthread_mutex_unlock(&this->vm_lock); | |
242 return S_ERR; | |
243 } | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
244 |
114 | 245 #ifdef LOG_DEBUG |
113 | 246 fprintf(MSG_OUT, "libdvdnav: previous chapter\n"); |
114 | 247 #endif |
248 if (!vm_jump_prev_pg(this->vm)) { | |
249 fprintf(MSG_OUT, "libdvdnav: previous chapter failed.\n"); | |
250 printerr("Skip to previous chapter failed."); | |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
251 pthread_mutex_unlock(&this->vm_lock); |
0 | 252 return S_ERR; |
253 } | |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
254 this->position_current.still = 0; |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
255 this->vm->hop_channel++; |
114 | 256 #ifdef LOG_DEBUG |
76 | 257 fprintf(MSG_OUT, "libdvdnav: previous chapter done\n"); |
114 | 258 #endif |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
259 pthread_mutex_unlock(&this->vm_lock); |
0 | 260 |
261 return S_OK; | |
262 } | |
263 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
264 dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) { |
0 | 265 |
114 | 266 if(!this) { |
267 printerr("Passed a NULL pointer."); | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
268 return S_ERR; |
114 | 269 } |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
270 |
114 | 271 pthread_mutex_lock(&this->vm_lock); |
272 if(!this->vm->state.pgc) { | |
273 printerr("No current PGC."); | |
274 pthread_mutex_unlock(&this->vm_lock); | |
275 return S_ERR; | |
276 } | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
277 |
114 | 278 #ifdef LOG_DEBUG |
279 fprintf(MSG_OUT, "libdvdnav: top chapter\n"); | |
280 #endif | |
281 if (!vm_jump_top_pg(this->vm)) { | |
282 fprintf(MSG_OUT, "libdvdnav: top chapter failed.\n"); | |
283 printerr("Skip to top chapter failed."); | |
113 | 284 pthread_mutex_unlock(&this->vm_lock); |
285 return S_ERR; | |
0 | 286 } |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
287 this->position_current.still = 0; |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
288 this->vm->hop_channel++; |
114 | 289 #ifdef LOG_DEBUG |
290 fprintf(MSG_OUT, "libdvdnav: top chapter done\n"); | |
291 #endif | |
292 pthread_mutex_unlock(&this->vm_lock); | |
293 | |
294 return S_OK; | |
295 } | |
296 | |
297 dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) { | |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
298 vm_t *try_vm; |
114 | 299 |
300 if(!this) { | |
301 printerr("Passed a NULL pointer."); | |
302 return S_ERR; | |
303 } | |
304 | |
305 pthread_mutex_lock(&this->vm_lock); | |
306 if(!this->vm->state.pgc) { | |
307 printerr("No current PGC."); | |
308 pthread_mutex_unlock(&this->vm_lock); | |
309 return S_ERR; | |
310 } | |
311 | |
312 #ifdef LOG_DEBUG | |
313 fprintf(MSG_OUT, "libdvdnav: next chapter\n"); | |
314 #endif | |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
315 /* make a copy of current VM and try to navigate the copy to the next PG */ |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
316 try_vm = vm_new_copy(this->vm); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
317 if (!vm_jump_next_pg(try_vm) || try_vm->stopped) { |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
318 vm_free_copy(try_vm); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
319 /* next_pg failed, try to jump at least to the next cell */ |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
320 try_vm = vm_new_copy(this->vm); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
321 vm_get_next_cell(try_vm); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
322 if (try_vm->stopped) { |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
323 vm_free_copy(try_vm); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
324 fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n"); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
325 printerr("Skip to next chapter failed."); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
326 pthread_mutex_unlock(&this->vm_lock); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
327 return S_ERR; |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
328 } |
114 | 329 } |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
330 /* merge changes on success */ |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
331 vm_merge(this->vm, try_vm); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
332 vm_free_copy(try_vm); |
114 | 333 this->position_current.still = 0; |
334 this->vm->hop_channel++; | |
335 #ifdef LOG_DEBUG | |
76 | 336 fprintf(MSG_OUT, "libdvdnav: next chapter done\n"); |
114 | 337 #endif |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
338 pthread_mutex_unlock(&this->vm_lock); |
0 | 339 |
340 return S_OK; | |
341 } | |
342 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
343 dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { |
125 | 344 vm_t *try_vm; |
114 | 345 |
346 if(!this) { | |
347 printerr("Passed a NULL pointer."); | |
0 | 348 return S_ERR; |
349 } | |
350 | |
114 | 351 pthread_mutex_lock(&this->vm_lock); |
352 if(!this->vm->state.pgc) { | |
353 printerr("No current PGC."); | |
354 pthread_mutex_unlock(&this->vm_lock); | |
355 return S_ERR; | |
356 } | |
357 | |
125 | 358 /* make a copy of current VM and try to navigate the copy to the menu */ |
359 try_vm = vm_new_copy(this->vm); | |
162
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
360 if ( (menu == DVD_MENU_Escape) && (this->vm->state.domain != VTS_DOMAIN)) { |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
361 /* Try resume */ |
167 | 362 if (vm_jump_resume(try_vm) && !try_vm->stopped) { |
162
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
363 /* merge changes on success */ |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
364 vm_merge(this->vm, try_vm); |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
365 vm_free_copy(try_vm); |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
366 this->position_current.still = 0; |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
367 this->vm->hop_channel++; |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
368 pthread_mutex_unlock(&this->vm_lock); |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
369 return S_OK; |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
370 } |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
371 } |
166 | 372 if (menu == DVD_MENU_Escape) menu = DVD_MENU_Root; |
162
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
373 |
125 | 374 if (vm_jump_menu(try_vm, menu) && !try_vm->stopped) { |
375 /* merge changes on success */ | |
376 vm_merge(this->vm, try_vm); | |
377 vm_free_copy(try_vm); | |
129 | 378 this->position_current.still = 0; |
114 | 379 this->vm->hop_channel++; |
380 pthread_mutex_unlock(&this->vm_lock); | |
381 return S_OK; | |
382 } else { | |
125 | 383 vm_free_copy(try_vm); |
384 printerr("No such menu or menu not reachable."); | |
114 | 385 pthread_mutex_unlock(&this->vm_lock); |
386 return S_ERR; | |
387 } | |
0 | 388 } |
389 | |
114 | 390 dvdnav_status_t dvdnav_get_position(dvdnav_t *this, unsigned int *pos, |
0 | 391 unsigned int *len) { |
392 uint32_t cur_sector; | |
166 | 393 int cell_nr, first_cell_nr, last_cell_nr; |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
394 cell_playback_t *cell; |
0 | 395 dvd_state_t *state; |
114 | 396 |
397 if(!this || !pos || !len) { | |
398 printerr("Passed a NULL pointer."); | |
399 return S_ERR; | |
400 } | |
401 if(!this->started) { | |
402 printerr("Virtual DVD machine not started."); | |
403 return S_ERR; | |
404 } | |
405 | |
406 pthread_mutex_lock(&this->vm_lock); | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
407 state = &(this->vm->state); |
114 | 408 if(!state->pgc) { |
409 printerr("No current PGC."); | |
410 pthread_mutex_unlock(&this->vm_lock); | |
411 return S_ERR; | |
0 | 412 } |
114 | 413 |
0 | 414 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
415 cur_sector = this->vobu.vobu_start + this->vobu.blockN; |
0 | 416 |
132 | 417 if (this->pgc_based) { |
418 first_cell_nr = 1; | |
419 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 420 } else { |
132 | 421 /* Find start cell of program. */ |
422 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
423 /* Find end cell of program */ | |
424 if(state->pgN < state->pgc->nr_of_programs) | |
425 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
426 else | |
427 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 428 } |
132 | 429 |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
430 *pos = -1; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
431 *len = 0; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
432 for (cell_nr = first_cell_nr; cell_nr <= last_cell_nr; cell_nr++) { |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
433 cell = &(state->pgc->cell_playback[cell_nr-1]); |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
434 if (cell_nr == state->cellN) { |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
435 /* the current sector is in this cell, |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
436 * pos is length of PG up to here + sector's offset in this cell */ |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
437 *pos = *len + cur_sector - cell->first_sector; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
438 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
439 *len += cell->last_sector - cell->first_sector + 1; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
440 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
441 |
166 | 442 assert((signed)*pos != -1); |
0 | 443 |
114 | 444 pthread_mutex_unlock(&this->vm_lock); |
0 | 445 |
446 return S_OK; | |
447 } | |
448 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
449 dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *this, |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
450 unsigned int *pos, |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
451 unsigned int *len) { |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
452 uint32_t cur_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
453 uint32_t first_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
454 uint32_t last_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
455 cell_playback_t *first_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
456 cell_playback_t *last_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
457 dvd_state_t *state; |
114 | 458 |
459 if(!this || !pos || !len) { | |
460 printerr("Passed a NULL pointer."); | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
461 return S_ERR; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
462 } |
114 | 463 |
464 state = &(this->vm->state); | |
465 if(!state->pgc) { | |
466 printerr("No current PGC."); | |
467 return S_ERR; | |
468 } | |
469 | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
470 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
471 cur_sector = this->vobu.vobu_start + this->vobu.blockN; |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
472 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
473 /* Now find first and last cells in title. */ |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
474 first_cell_nr = state->pgc->program_map[0]; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
475 first_cell = &(state->pgc->cell_playback[first_cell_nr-1]); |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
476 last_cell_nr = state->pgc->nr_of_cells; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
477 last_cell = &(state->pgc->cell_playback[last_cell_nr-1]); |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
478 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
479 *pos = cur_sector - first_cell->first_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
480 *len = last_cell->last_sector - first_cell->first_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
481 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
482 return S_OK; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
483 } |