Mercurial > libdvdnav.hg
annotate searching.c @ 249:5d643668f1e3 src
I added this code myself a long time ago, but now I am quite convinced that
it is wrong: Why would we filter out SPU stream change events that switch
SPUs off? This breaks watching the trailer on the RC2 of "Girl, interrupted",
because you always get unwanted subtitles.
When I added this code, it fixed a problem with the RC2 of "Terminator", but
I cannot reproduce this problem any more. Back then, the menu highlights would
not show up, but they do now. I assume the problem really got fixed with proper
support for forced subtitles in xine, so this crappy workaround here can go
away.
After all, this way it is more symmetric to audio stream change events,
because these are not filtered.
author | mroi |
---|---|
date | Sun, 12 Sep 2004 15:12:43 +0000 |
parents | f19fce15577b |
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 } |