Mercurial > libdvdnav.hg
annotate searching.c @ 288:ce4230602517 src
moved away from dvdnav_internal.h inclusion of various system headers
author | nicodvb |
---|---|
date | Sat, 21 Apr 2007 11:56:41 +0000 |
parents | 52877d182e96 |
children | 54b6a000f6da |
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> |
278 | 29 #include <inttypes.h> |
288
ce4230602517
moved away from dvdnav_internal.h inclusion of various system headers
nicodvb
parents:
285
diff
changeset
|
30 #include <stdio.h> |
ce4230602517
moved away from dvdnav_internal.h inclusion of various system headers
nicodvb
parents:
285
diff
changeset
|
31 #include <string.h> |
285
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
32 #include "dvd_types.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
33 #include "nav_types.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
34 #include "ifo_types.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
35 #include "remap.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
36 #include "vm/decoder.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
37 #include "vm/vm.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
38 #include "vm/vmcmd.h" |
52877d182e96
moved all header inclusions from .h to .c files; my word, I've never seen such a horrible entanglement as in this mess
nicodvb
parents:
278
diff
changeset
|
39 #include "dvdnav.h" |
0 | 40 #include "dvdnav_internal.h" |
41 | |
114 | 42 /* |
43 #define LOG_DEBUG | |
44 */ | |
45 | |
0 | 46 /* Searching API calls */ |
47 | |
24 | 48 /* Scan the ADMAP for a particular block number. */ |
49 /* Return placed in vobu. */ | |
50 /* Returns error status */ | |
114 | 51 /* FIXME: Maybe need to handle seeking outside current cell. */ |
195 | 52 static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_t seekto_block, uint32_t *vobu) { |
24 | 53 vobu_admap_t *admap = NULL; |
114 | 54 |
55 #ifdef LOG_DEBUG | |
56 fprintf(MSG_OUT, "libdvdnav: Seeking to target %u ...\n", seekto_block); | |
57 #endif | |
24 | 58 *vobu = -1; |
59 | |
60 /* Search through the VOBU_ADMAP for the nearest VOBU | |
61 * to the target block */ | |
62 switch(domain) { | |
114 | 63 case FP_DOMAIN: |
64 case VMGM_DOMAIN: | |
65 admap = this->vm->vmgi->menu_vobu_admap; | |
66 break; | |
67 case VTSM_DOMAIN: | |
68 admap = this->vm->vtsi->menu_vobu_admap; | |
69 break; | |
70 case VTS_DOMAIN: | |
71 admap = this->vm->vtsi->vts_vobu_admap; | |
72 break; | |
73 default: | |
74 fprintf(MSG_OUT, "libdvdnav: Error: Unknown domain for seeking.\n"); | |
24 | 75 } |
76 if(admap) { | |
166 | 77 uint32_t address = 0; |
78 uint32_t vobu_start, next_vobu; | |
195 | 79 int32_t found = 0; |
24 | 80 |
81 /* Search through ADMAP for best sector */ | |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
82 vobu_start = SRI_END_OF_CELL; |
24 | 83 /* FIXME: Implement a faster search algorithm */ |
84 while((!found) && ((address<<2) < admap->last_byte)) { | |
85 next_vobu = admap->vobu_start_sectors[address]; | |
86 | |
76 | 87 /* fprintf(MSG_OUT, "libdvdnav: Found block %u\n", next_vobu); */ |
24 | 88 |
89 if(vobu_start <= seekto_block && | |
90 next_vobu > seekto_block) { | |
91 found = 1; | |
92 } else { | |
93 vobu_start = next_vobu; | |
94 } | |
95 address ++; | |
96 } | |
97 if(found) { | |
98 *vobu = vobu_start; | |
193 | 99 return DVDNAV_STATUS_OK; |
24 | 100 } else { |
76 | 101 fprintf(MSG_OUT, "libdvdnav: Could not locate block\n"); |
193 | 102 return DVDNAV_STATUS_ERR; |
24 | 103 } |
104 } | |
76 | 105 fprintf(MSG_OUT, "libdvdnav: admap not located\n"); |
193 | 106 return DVDNAV_STATUS_ERR; |
24 | 107 } |
108 | |
265 | 109 /* FIXME: right now, this function does not use the time tables but interpolates |
110 only the cell times */ | |
111 dvdnav_status_t dvdnav_time_search(dvdnav_t *this, | |
112 uint64_t time) { | |
113 | |
114 uint64_t target = time; | |
115 uint64_t length = 0; | |
116 uint32_t first_cell_nr, last_cell_nr, cell_nr; | |
117 int32_t found; | |
118 cell_playback_t *cell; | |
119 dvd_state_t *state; | |
120 | |
121 if(this->position_current.still != 0) { | |
122 printerr("Cannot seek in a still frame."); | |
123 return DVDNAV_STATUS_ERR; | |
124 } | |
125 | |
126 pthread_mutex_lock(&this->vm_lock); | |
127 state = &(this->vm->state); | |
128 if(!state->pgc) { | |
129 printerr("No current PGC."); | |
130 pthread_mutex_unlock(&this->vm_lock); | |
131 return DVDNAV_STATUS_ERR; | |
132 } | |
133 | |
134 | |
269
77e472cef5f8
implemented dvdnav_get_current_time() with obvious meaning
nicodvb
parents:
265
diff
changeset
|
135 this->cur_cell_time = 0; |
265 | 136 if (this->pgc_based) { |
137 first_cell_nr = 1; | |
138 last_cell_nr = state->pgc->nr_of_cells; | |
139 } else { | |
140 /* Find start cell of program. */ | |
141 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
142 /* Find end cell of program */ | |
143 if(state->pgN < state->pgc->nr_of_programs) | |
144 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
145 else | |
146 last_cell_nr = state->pgc->nr_of_cells; | |
147 } | |
148 | |
149 found = 0; | |
150 for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { | |
151 cell = &(state->pgc->cell_playback[cell_nr-1]); | |
270
5d091ebc4c3b
in dvdnav_time_search() skip secondary angles when searching the cell to hump to
nicodvb
parents:
269
diff
changeset
|
152 if(cell->block_type == BLOCK_TYPE_ANGLE_BLOCK && cell->block_mode != BLOCK_MODE_FIRST_CELL) |
5d091ebc4c3b
in dvdnav_time_search() skip secondary angles when searching the cell to hump to
nicodvb
parents:
269
diff
changeset
|
153 continue; |
265 | 154 length = dvdnav_convert_time(&cell->playback_time); |
155 if (target >= length) { | |
156 target -= length; | |
157 } else { | |
158 /* FIXME: there must be a better way than interpolation */ | |
159 target = target * (cell->last_sector - cell->first_sector + 1) / length; | |
160 target += cell->first_sector; | |
161 | |
162 found = 1; | |
163 break; | |
164 } | |
165 } | |
166 | |
167 if(found) { | |
275
f8ba866996f9
in dvdnav_time_search() vobu and start are uint32_t
nicodvb
parents:
273
diff
changeset
|
168 uint32_t vobu; |
265 | 169 #ifdef LOG_DEBUG |
170 fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n", | |
171 cell_nr, first_cell_nr, last_cell_nr); | |
172 #endif | |
173 if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) { | |
275
f8ba866996f9
in dvdnav_time_search() vobu and start are uint32_t
nicodvb
parents:
273
diff
changeset
|
174 uint32_t start = state->pgc->cell_playback[cell_nr-1].first_sector; |
265 | 175 |
176 if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) { | |
177 #ifdef LOG_DEBUG | |
178 fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , | |
179 state->cellN, state->blockN, target, vobu, start); | |
180 #endif | |
181 this->vm->hop_channel += HOP_SEEK; | |
182 pthread_mutex_unlock(&this->vm_lock); | |
183 return DVDNAV_STATUS_OK; | |
184 } | |
185 } | |
186 } | |
187 | |
188 fprintf(MSG_OUT, "libdvdnav: Error when seeking\n"); | |
189 printerr("Error when seeking."); | |
190 pthread_mutex_unlock(&this->vm_lock); | |
191 return DVDNAV_STATUS_ERR; | |
192 } | |
193 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
194 dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, |
195 | 195 uint64_t offset, int32_t origin) { |
0 | 196 uint32_t target = 0; |
197 uint32_t length = 0; | |
114 | 198 uint32_t first_cell_nr, last_cell_nr, cell_nr; |
195 | 199 int32_t found; |
114 | 200 cell_playback_t *cell; |
0 | 201 dvd_state_t *state; |
202 dvdnav_status_t result; | |
203 | |
114 | 204 if(this->position_current.still != 0) { |
205 printerr("Cannot seek in a still frame."); | |
193 | 206 return DVDNAV_STATUS_ERR; |
114 | 207 } |
0 | 208 |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
209 result = dvdnav_get_position(this, &target, &length); |
0 | 210 if(!result) { |
193 | 211 return DVDNAV_STATUS_ERR; |
0 | 212 } |
213 | |
114 | 214 pthread_mutex_lock(&this->vm_lock); |
215 state = &(this->vm->state); | |
216 if(!state->pgc) { | |
217 printerr("No current PGC."); | |
218 pthread_mutex_unlock(&this->vm_lock); | |
193 | 219 return DVDNAV_STATUS_ERR; |
114 | 220 } |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
221 #ifdef LOG_DEBUG |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
222 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
|
223 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
|
224 #endif |
114 | 225 |
0 | 226 switch(origin) { |
227 case SEEK_SET: | |
228 if(offset > length) { | |
114 | 229 printerr("Request to seek behind end."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
230 pthread_mutex_unlock(&this->vm_lock); |
193 | 231 return DVDNAV_STATUS_ERR; |
0 | 232 } |
233 target = offset; | |
234 break; | |
235 case SEEK_CUR: | |
236 if(target + offset > length) { | |
114 | 237 printerr("Request to seek behind end."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
238 pthread_mutex_unlock(&this->vm_lock); |
193 | 239 return DVDNAV_STATUS_ERR; |
0 | 240 } |
241 target += offset; | |
242 break; | |
243 case SEEK_END: | |
244 if(length - offset < 0) { | |
114 | 245 printerr("Request to seek before start."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
246 pthread_mutex_unlock(&this->vm_lock); |
193 | 247 return DVDNAV_STATUS_ERR; |
0 | 248 } |
249 target = length - offset; | |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
250 break; |
0 | 251 default: |
252 /* Error occured */ | |
114 | 253 printerr("Illegal seek mode."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
254 pthread_mutex_unlock(&this->vm_lock); |
193 | 255 return DVDNAV_STATUS_ERR; |
0 | 256 } |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
257 |
269
77e472cef5f8
implemented dvdnav_get_current_time() with obvious meaning
nicodvb
parents:
265
diff
changeset
|
258 this->cur_cell_time = 0; |
132 | 259 if (this->pgc_based) { |
260 first_cell_nr = 1; | |
261 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 262 } else { |
132 | 263 /* Find start cell of program. */ |
264 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
265 /* Find end cell of program */ | |
266 if(state->pgN < state->pgc->nr_of_programs) | |
267 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
268 else | |
269 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 270 } |
132 | 271 |
114 | 272 found = 0; |
0 | 273 for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { |
274 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
|
275 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
|
276 if (target >= length) { |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
277 target -= length; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
278 } else { |
131 | 279 /* 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
|
280 target += cell->first_sector; |
114 | 281 found = 1; |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
282 break; |
0 | 283 } |
284 } | |
285 | |
114 | 286 if(found) { |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
287 int32_t vobu; |
114 | 288 #ifdef LOG_DEBUG |
76 | 289 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
|
290 cell_nr, first_cell_nr, last_cell_nr); |
114 | 291 #endif |
193 | 292 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
|
293 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
|
294 |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
295 if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) { |
114 | 296 #ifdef LOG_DEBUG |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
297 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
|
298 state->cellN, state->blockN, target, vobu, start); |
114 | 299 #endif |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
300 this->vm->hop_channel += HOP_SEEK; |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
301 pthread_mutex_unlock(&this->vm_lock); |
193 | 302 return DVDNAV_STATUS_OK; |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
303 } |
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
304 } |
0 | 305 } |
114 | 306 |
133
d09a81cf65ce
determine correct PG and PTT numbers when seeking across PG boundaries
mroi
parents:
132
diff
changeset
|
307 fprintf(MSG_OUT, "libdvdnav: Error when seeking\n"); |
76 | 308 fprintf(MSG_OUT, "libdvdnav: FIXME: Implement seeking to location %u\n", target); |
114 | 309 printerr("Error when seeking."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
310 pthread_mutex_unlock(&this->vm_lock); |
193 | 311 return DVDNAV_STATUS_ERR; |
0 | 312 } |
313 | |
195 | 314 dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int32_t part) { |
315 int32_t title, old_part; | |
114 | 316 |
193 | 317 if (dvdnav_current_title_info(this, &title, &old_part) == DVDNAV_STATUS_OK) |
114 | 318 return dvdnav_part_play(this, title, part); |
193 | 319 return DVDNAV_STATUS_ERR; |
0 | 320 } |
321 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
322 dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *this) { |
114 | 323 pthread_mutex_lock(&this->vm_lock); |
324 if(!this->vm->state.pgc) { | |
325 printerr("No current PGC."); | |
326 pthread_mutex_unlock(&this->vm_lock); | |
193 | 327 return DVDNAV_STATUS_ERR; |
114 | 328 } |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
329 |
114 | 330 #ifdef LOG_DEBUG |
113 | 331 fprintf(MSG_OUT, "libdvdnav: previous chapter\n"); |
114 | 332 #endif |
333 if (!vm_jump_prev_pg(this->vm)) { | |
334 fprintf(MSG_OUT, "libdvdnav: previous chapter failed.\n"); | |
335 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
|
336 pthread_mutex_unlock(&this->vm_lock); |
193 | 337 return DVDNAV_STATUS_ERR; |
0 | 338 } |
269
77e472cef5f8
implemented dvdnav_get_current_time() with obvious meaning
nicodvb
parents:
265
diff
changeset
|
339 this->cur_cell_time = 0; |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
340 this->position_current.still = 0; |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
341 this->vm->hop_channel++; |
114 | 342 #ifdef LOG_DEBUG |
76 | 343 fprintf(MSG_OUT, "libdvdnav: previous chapter done\n"); |
114 | 344 #endif |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
345 pthread_mutex_unlock(&this->vm_lock); |
0 | 346 |
193 | 347 return DVDNAV_STATUS_OK; |
0 | 348 } |
349 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
350 dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) { |
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 } |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
357 |
114 | 358 #ifdef LOG_DEBUG |
359 fprintf(MSG_OUT, "libdvdnav: top chapter\n"); | |
360 #endif | |
361 if (!vm_jump_top_pg(this->vm)) { | |
362 fprintf(MSG_OUT, "libdvdnav: top chapter failed.\n"); | |
363 printerr("Skip to top chapter failed."); | |
113 | 364 pthread_mutex_unlock(&this->vm_lock); |
193 | 365 return DVDNAV_STATUS_ERR; |
0 | 366 } |
269
77e472cef5f8
implemented dvdnav_get_current_time() with obvious meaning
nicodvb
parents:
265
diff
changeset
|
367 this->cur_cell_time = 0; |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
368 this->position_current.still = 0; |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
369 this->vm->hop_channel++; |
114 | 370 #ifdef LOG_DEBUG |
371 fprintf(MSG_OUT, "libdvdnav: top chapter done\n"); | |
372 #endif | |
373 pthread_mutex_unlock(&this->vm_lock); | |
374 | |
193 | 375 return DVDNAV_STATUS_OK; |
114 | 376 } |
377 | |
378 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
|
379 vm_t *try_vm; |
114 | 380 |
381 pthread_mutex_lock(&this->vm_lock); | |
382 if(!this->vm->state.pgc) { | |
383 printerr("No current PGC."); | |
384 pthread_mutex_unlock(&this->vm_lock); | |
193 | 385 return DVDNAV_STATUS_ERR; |
114 | 386 } |
387 | |
388 #ifdef LOG_DEBUG | |
389 fprintf(MSG_OUT, "libdvdnav: next chapter\n"); | |
390 #endif | |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
391 /* 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
|
392 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
|
393 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
|
394 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
|
395 /* 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
|
396 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
|
397 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
|
398 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
|
399 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
|
400 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
|
401 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
|
402 pthread_mutex_unlock(&this->vm_lock); |
193 | 403 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
|
404 } |
114 | 405 } |
269
77e472cef5f8
implemented dvdnav_get_current_time() with obvious meaning
nicodvb
parents:
265
diff
changeset
|
406 this->cur_cell_time = 0; |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
407 /* 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
|
408 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
|
409 vm_free_copy(try_vm); |
114 | 410 this->position_current.still = 0; |
411 this->vm->hop_channel++; | |
412 #ifdef LOG_DEBUG | |
76 | 413 fprintf(MSG_OUT, "libdvdnav: next chapter done\n"); |
114 | 414 #endif |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
415 pthread_mutex_unlock(&this->vm_lock); |
0 | 416 |
193 | 417 return DVDNAV_STATUS_OK; |
0 | 418 } |
419 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
420 dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { |
125 | 421 vm_t *try_vm; |
114 | 422 |
423 pthread_mutex_lock(&this->vm_lock); | |
424 if(!this->vm->state.pgc) { | |
425 printerr("No current PGC."); | |
426 pthread_mutex_unlock(&this->vm_lock); | |
193 | 427 return DVDNAV_STATUS_ERR; |
114 | 428 } |
429 | |
269
77e472cef5f8
implemented dvdnav_get_current_time() with obvious meaning
nicodvb
parents:
265
diff
changeset
|
430 this->cur_cell_time = 0; |
125 | 431 /* make a copy of current VM and try to navigate the copy to the menu */ |
432 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
|
433 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
|
434 /* Try resume */ |
167 | 435 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
|
436 /* merge changes on success */ |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
437 vm_merge(this->vm, try_vm); |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
438 vm_free_copy(try_vm); |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
439 this->position_current.still = 0; |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
440 this->vm->hop_channel++; |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
441 pthread_mutex_unlock(&this->vm_lock); |
193 | 442 return DVDNAV_STATUS_OK; |
162
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
443 } |
0fd70a257b44
Implement ESCAPE key jumping from TITLE to MENU and back again.
jcdutton
parents:
136
diff
changeset
|
444 } |
166 | 445 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
|
446 |
125 | 447 if (vm_jump_menu(try_vm, menu) && !try_vm->stopped) { |
448 /* merge changes on success */ | |
449 vm_merge(this->vm, try_vm); | |
450 vm_free_copy(try_vm); | |
129 | 451 this->position_current.still = 0; |
114 | 452 this->vm->hop_channel++; |
453 pthread_mutex_unlock(&this->vm_lock); | |
193 | 454 return DVDNAV_STATUS_OK; |
114 | 455 } else { |
125 | 456 vm_free_copy(try_vm); |
457 printerr("No such menu or menu not reachable."); | |
114 | 458 pthread_mutex_unlock(&this->vm_lock); |
193 | 459 return DVDNAV_STATUS_ERR; |
114 | 460 } |
0 | 461 } |
462 | |
195 | 463 dvdnav_status_t dvdnav_get_position(dvdnav_t *this, uint32_t *pos, |
464 uint32_t *len) { | |
0 | 465 uint32_t cur_sector; |
195 | 466 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
|
467 cell_playback_t *cell; |
0 | 468 dvd_state_t *state; |
114 | 469 |
470 if(!this->started) { | |
471 printerr("Virtual DVD machine not started."); | |
193 | 472 return DVDNAV_STATUS_ERR; |
114 | 473 } |
474 | |
475 pthread_mutex_lock(&this->vm_lock); | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
476 state = &(this->vm->state); |
224
f19fce15577b
fix assertion failure when someone asks for the position between an Exit
mroi
parents:
195
diff
changeset
|
477 if(!state->pgc || this->vm->stopped) { |
114 | 478 printerr("No current PGC."); |
479 pthread_mutex_unlock(&this->vm_lock); | |
193 | 480 return DVDNAV_STATUS_ERR; |
0 | 481 } |
181
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
482 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
|
483 this->position_current.domain != state->domain || |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
484 this->position_current.vts != state->vtsN || |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
485 this->position_current.cell_restart != state->cell_restart) { |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
486 printerr("New position not yet determined."); |
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
487 pthread_mutex_unlock(&this->vm_lock); |
193 | 488 return DVDNAV_STATUS_ERR; |
181
5d9770cb2961
fix some conditions where the following assertion would fail
mroi
parents:
167
diff
changeset
|
489 } |
114 | 490 |
0 | 491 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
492 cur_sector = this->vobu.vobu_start + this->vobu.blockN; |
0 | 493 |
132 | 494 if (this->pgc_based) { |
495 first_cell_nr = 1; | |
496 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 497 } else { |
132 | 498 /* Find start cell of program. */ |
499 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
500 /* Find end cell of program */ | |
501 if(state->pgN < state->pgc->nr_of_programs) | |
502 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
503 else | |
504 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 505 } |
132 | 506 |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
507 *pos = -1; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
508 *len = 0; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
509 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
|
510 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
|
511 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
|
512 /* 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
|
513 * 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
|
514 *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
|
515 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
516 *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
|
517 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
518 |
166 | 519 assert((signed)*pos != -1); |
0 | 520 |
114 | 521 pthread_mutex_unlock(&this->vm_lock); |
0 | 522 |
193 | 523 return DVDNAV_STATUS_OK; |
0 | 524 } |
525 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
526 dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *this, |
195 | 527 uint32_t *pos, |
528 uint32_t *len) { | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
529 uint32_t cur_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
530 uint32_t first_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
531 uint32_t last_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
532 cell_playback_t *first_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
533 cell_playback_t *last_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
534 dvd_state_t *state; |
114 | 535 |
536 state = &(this->vm->state); | |
537 if(!state->pgc) { | |
538 printerr("No current PGC."); | |
193 | 539 return DVDNAV_STATUS_ERR; |
114 | 540 } |
541 | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
542 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
543 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
|
544 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
545 /* 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
|
546 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
|
547 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
|
548 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
|
549 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
|
550 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
551 *pos = cur_sector - first_cell->first_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
552 *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
|
553 |
193 | 554 return DVDNAV_STATUS_OK; |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
555 } |