Mercurial > libdvdnav.hg
annotate searching.c @ 224:f19fce15577b src
fix assertion failure when someone asks for the position between an Exit
command and the following get_next_block() call
author | mroi |
---|---|
date | Wed, 07 Jan 2004 19:35:12 +0000 |
parents | 6b1bfe8f5283 |
children | 99d33725395d |
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, |
195 | 38 uint64_t time) { |
114 | 39 /* FIXME: Time search the current PGC based on the xxx table */ |
193 | 40 return DVDNAV_STATUS_OK; |
0 | 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. */ |
195 | 47 static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t 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; | |
195 | 74 int32_t found = 0; |
24 | 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; | |
193 | 94 return DVDNAV_STATUS_OK; |
24 | 95 } else { |
76 | 96 fprintf(MSG_OUT, "libdvdnav: Could not locate block\n"); |
193 | 97 return DVDNAV_STATUS_ERR; |
24 | 98 } |
99 } | |
76 | 100 fprintf(MSG_OUT, "libdvdnav: admap not located\n"); |
193 | 101 return DVDNAV_STATUS_ERR; |
24 | 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, |
195 | 105 uint64_t offset, int32_t origin) { |
0 | 106 uint32_t target = 0; |
107 uint32_t length = 0; | |
114 | 108 uint32_t first_cell_nr, last_cell_nr, cell_nr; |
195 | 109 int32_t 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."); | |
193 | 116 return DVDNAV_STATUS_ERR; |
114 | 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) { |
193 | 121 return DVDNAV_STATUS_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); | |
193 | 129 return DVDNAV_STATUS_ERR; |
114 | 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); |
193 | 141 return DVDNAV_STATUS_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); |
193 | 149 return DVDNAV_STATUS_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); |
193 | 157 return DVDNAV_STATUS_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); |
193 | 165 return DVDNAV_STATUS_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 |
193 | 201 if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) { |
133
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); |
193 | 211 return DVDNAV_STATUS_OK; |
133
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); |
193 | 220 return DVDNAV_STATUS_ERR; |
0 | 221 } |
222 | |
195 | 223 dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int32_t part) { |
224 int32_t title, old_part; | |
114 | 225 |
193 | 226 if (dvdnav_current_title_info(this, &title, &old_part) == DVDNAV_STATUS_OK) |
114 | 227 return dvdnav_part_play(this, title, part); |
193 | 228 return DVDNAV_STATUS_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."); | |
193 | 235 return DVDNAV_STATUS_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); | |
193 | 242 return DVDNAV_STATUS_ERR; |
114 | 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); |
193 | 252 return DVDNAV_STATUS_ERR; |
0 | 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 |
193 | 261 return DVDNAV_STATUS_OK; |
0 | 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."); | |
193 | 268 return DVDNAV_STATUS_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); | |
193 | 275 return DVDNAV_STATUS_ERR; |
114 | 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); |
193 | 285 return DVDNAV_STATUS_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 | |
193 | 294 return DVDNAV_STATUS_OK; |
114 | 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."); | |
193 | 302 return DVDNAV_STATUS_ERR; |
114 | 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); | |
193 | 309 return DVDNAV_STATUS_ERR; |
114 | 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); |
193 | 327 return DVDNAV_STATUS_ERR; |
122
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 |
193 | 340 return DVDNAV_STATUS_OK; |
0 | 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."); | |
193 | 348 return DVDNAV_STATUS_ERR; |
0 | 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); | |
193 | 355 return DVDNAV_STATUS_ERR; |
114 | 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); |
193 | 369 return DVDNAV_STATUS_OK; |
162
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); | |
193 | 381 return DVDNAV_STATUS_OK; |
114 | 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); |
193 | 386 return DVDNAV_STATUS_ERR; |
114 | 387 } |
0 | 388 } |
389 | |
195 | 390 dvdnav_status_t dvdnav_get_position(dvdnav_t *this, uint32_t *pos, |
391 uint32_t *len) { | |
0 | 392 uint32_t cur_sector; |
195 | 393 int32_t 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."); | |
193 | 399 return DVDNAV_STATUS_ERR; |
114 | 400 } |
401 if(!this->started) { | |
402 printerr("Virtual DVD machine not started."); | |
193 | 403 return DVDNAV_STATUS_ERR; |
114 | 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); |
224
f19fce15577b
fix assertion failure when someone asks for the position between an Exit
mroi
parents:
195
diff
changeset
|
408 if(!state->pgc || this->vm->stopped) { |
114 | 409 printerr("No current PGC."); |
410 pthread_mutex_unlock(&this->vm_lock); | |
193 | 411 return DVDNAV_STATUS_ERR; |
0 | 412 } |
181
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
413 if (this->position_current.hop_channel != this->vm->hop_channel || |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
414 this->position_current.domain != state->domain || |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
415 this->position_current.vts != state->vtsN || |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
416 this->position_current.cell_restart != state->cell_restart) { |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
417 printerr("New position not yet determined."); |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
418 pthread_mutex_unlock(&this->vm_lock); |
193 | 419 return DVDNAV_STATUS_ERR; |
181
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
420 } |
114 | 421 |
0 | 422 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
423 cur_sector = this->vobu.vobu_start + this->vobu.blockN; |
0 | 424 |
132 | 425 if (this->pgc_based) { |
426 first_cell_nr = 1; | |
427 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 428 } else { |
132 | 429 /* Find start cell of program. */ |
430 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
431 /* Find end cell of program */ | |
432 if(state->pgN < state->pgc->nr_of_programs) | |
433 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
434 else | |
435 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 436 } |
132 | 437 |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
438 *pos = -1; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
439 *len = 0; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
440 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
|
441 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
|
442 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
|
443 /* 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
|
444 * 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
|
445 *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
|
446 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
447 *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
|
448 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
449 |
166 | 450 assert((signed)*pos != -1); |
0 | 451 |
114 | 452 pthread_mutex_unlock(&this->vm_lock); |
0 | 453 |
193 | 454 return DVDNAV_STATUS_OK; |
0 | 455 } |
456 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
457 dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *this, |
195 | 458 uint32_t *pos, |
459 uint32_t *len) { | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
460 uint32_t cur_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
461 uint32_t first_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
462 uint32_t last_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
463 cell_playback_t *first_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
464 cell_playback_t *last_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
465 dvd_state_t *state; |
114 | 466 |
467 if(!this || !pos || !len) { | |
468 printerr("Passed a NULL pointer."); | |
193 | 469 return DVDNAV_STATUS_ERR; |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
470 } |
114 | 471 |
472 state = &(this->vm->state); | |
473 if(!state->pgc) { | |
474 printerr("No current PGC."); | |
193 | 475 return DVDNAV_STATUS_ERR; |
114 | 476 } |
477 | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
478 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
479 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
|
480 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
481 /* 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
|
482 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
|
483 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
|
484 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
|
485 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
|
486 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
487 *pos = cur_sector - first_cell->first_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
488 *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
|
489 |
193 | 490 return DVDNAV_STATUS_OK; |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
491 } |