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