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