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