Mercurial > libdvdnav.hg
annotate searching.c @ 132:f22458f928b8 src
PGC based positioning
author | mroi |
---|---|
date | Sun, 23 Mar 2003 15:24:31 +0000 |
parents | ada79e606d8d |
children | d09a81cf65ce |
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> |
29 | |
0 | 30 #include "dvdnav_internal.h" |
31 | |
32 #include "vm.h" | |
33 | |
114 | 34 /* |
35 #define LOG_DEBUG | |
36 */ | |
37 | |
0 | 38 /* Searching API calls */ |
39 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
40 dvdnav_status_t dvdnav_time_search(dvdnav_t *this, |
0 | 41 unsigned long int time) { |
114 | 42 /* FIXME: Time search the current PGC based on the xxx table */ |
0 | 43 return S_OK; |
44 } | |
45 | |
24 | 46 /* Scan the ADMAP for a particular block number. */ |
47 /* Return placed in vobu. */ | |
48 /* Returns error status */ | |
114 | 49 /* FIXME: Maybe need to handle seeking outside current cell. */ |
50 static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, int32_t seekto_block, int32_t *vobu) { | |
24 | 51 vobu_admap_t *admap = NULL; |
114 | 52 |
53 #ifdef LOG_DEBUG | |
54 fprintf(MSG_OUT, "libdvdnav: Seeking to target %u ...\n", seekto_block); | |
55 #endif | |
24 | 56 *vobu = -1; |
57 | |
58 /* Search through the VOBU_ADMAP for the nearest VOBU | |
59 * to the target block */ | |
60 switch(domain) { | |
114 | 61 case FP_DOMAIN: |
62 case VMGM_DOMAIN: | |
63 admap = this->vm->vmgi->menu_vobu_admap; | |
64 break; | |
65 case VTSM_DOMAIN: | |
66 admap = this->vm->vtsi->menu_vobu_admap; | |
67 break; | |
68 case VTS_DOMAIN: | |
69 admap = this->vm->vtsi->vts_vobu_admap; | |
70 break; | |
71 default: | |
72 fprintf(MSG_OUT, "libdvdnav: Error: Unknown domain for seeking.\n"); | |
24 | 73 } |
74 if(admap) { | |
75 int32_t address = 0; | |
76 int32_t vobu_start, next_vobu; | |
77 int found = 0; | |
78 | |
79 /* Search through ADMAP for best sector */ | |
80 vobu_start = 0x3fffffff; | |
81 /* FIXME: Implement a faster search algorithm */ | |
82 while((!found) && ((address<<2) < admap->last_byte)) { | |
83 next_vobu = admap->vobu_start_sectors[address]; | |
84 | |
76 | 85 /* fprintf(MSG_OUT, "libdvdnav: Found block %u\n", next_vobu); */ |
24 | 86 |
87 if(vobu_start <= seekto_block && | |
88 next_vobu > seekto_block) { | |
89 found = 1; | |
90 } else { | |
91 vobu_start = next_vobu; | |
92 } | |
93 address ++; | |
94 } | |
95 if(found) { | |
96 *vobu = vobu_start; | |
97 return S_OK; | |
98 } else { | |
76 | 99 fprintf(MSG_OUT, "libdvdnav: Could not locate block\n"); |
24 | 100 return S_ERR; |
101 } | |
102 } | |
76 | 103 fprintf(MSG_OUT, "libdvdnav: admap not located\n"); |
24 | 104 return S_ERR; |
105 } | |
106 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
107 dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, |
114 | 108 unsigned long int offset, int origin) { |
0 | 109 uint32_t target = 0; |
110 uint32_t length = 0; | |
114 | 111 uint32_t first_cell_nr, last_cell_nr, cell_nr; |
0 | 112 int found; |
114 | 113 cell_playback_t *cell; |
0 | 114 dvd_state_t *state; |
115 dvdnav_status_t result; | |
116 | |
114 | 117 if(this->position_current.still != 0) { |
118 printerr("Cannot seek in a still frame."); | |
119 return S_ERR; | |
120 } | |
0 | 121 |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
122 result = dvdnav_get_position(this, &target, &length); |
114 | 123 #ifdef LOG_DEBUG |
124 fprintf(MSG_OUT, "libdvdnav: seeking to offset=%lu pos=%u length=%u\n", offset, target, length); | |
125 fprintf(MSG_OUT, "libdvdnav: Before cellN=%u blockN=%u\n", state->cellN, state->blockN); | |
126 #endif | |
0 | 127 if(!result) { |
114 | 128 return S_ERR; |
0 | 129 } |
130 | |
114 | 131 pthread_mutex_lock(&this->vm_lock); |
132 state = &(this->vm->state); | |
133 if(!state->pgc) { | |
134 printerr("No current PGC."); | |
135 pthread_mutex_unlock(&this->vm_lock); | |
136 return S_ERR; | |
137 } | |
138 | |
0 | 139 switch(origin) { |
140 case SEEK_SET: | |
141 if(offset > length) { | |
114 | 142 printerr("Request to seek behind end."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
143 pthread_mutex_unlock(&this->vm_lock); |
114 | 144 return S_ERR; |
0 | 145 } |
146 target = offset; | |
147 break; | |
148 case SEEK_CUR: | |
149 if(target + offset > length) { | |
114 | 150 printerr("Request to seek behind end."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
151 pthread_mutex_unlock(&this->vm_lock); |
114 | 152 return S_ERR; |
0 | 153 } |
154 target += offset; | |
155 break; | |
156 case SEEK_END: | |
157 if(length - offset < 0) { | |
114 | 158 printerr("Request to seek before start."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
159 pthread_mutex_unlock(&this->vm_lock); |
114 | 160 return S_ERR; |
0 | 161 } |
162 target = length - offset; | |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
163 break; |
0 | 164 default: |
165 /* Error occured */ | |
114 | 166 printerr("Illegal seek mode."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
167 pthread_mutex_unlock(&this->vm_lock); |
114 | 168 return S_ERR; |
0 | 169 } |
170 | |
132 | 171 if (this->pgc_based) { |
172 first_cell_nr = 1; | |
173 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 174 } else { |
132 | 175 /* Find start cell of program. */ |
176 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
177 /* Find end cell of program */ | |
178 if(state->pgN < state->pgc->nr_of_programs) | |
179 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
180 else | |
181 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 182 } |
132 | 183 |
114 | 184 found = 0; |
0 | 185 for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { |
186 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
|
187 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
|
188 if (target >= length) { |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
189 target -= length; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
190 } else { |
131 | 191 /* 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
|
192 target += cell->first_sector; |
114 | 193 found = 1; |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
194 break; |
0 | 195 } |
196 } | |
197 | |
114 | 198 if(found) { |
26 | 199 int32_t vobu, start; |
114 | 200 #ifdef LOG_DEBUG |
76 | 201 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
|
202 cell_nr, first_cell_nr, last_cell_nr); |
114 | 203 #endif |
204 dvdnav_scan_admap(this, state->domain, target, &vobu); | |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
205 |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
206 start = state->pgc->cell_playback[cell_nr-1].first_sector; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
207 state->blockN = vobu - start; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
208 state->cellN = cell_nr; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
209 state->cell_restart++; |
114 | 210 #ifdef LOG_DEBUG |
211 fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , | |
0 | 212 state->cellN, |
24 | 213 state->blockN, |
214 target, | |
215 vobu, | |
216 start); | |
114 | 217 #endif |
218 this->vm->hop_channel += HOP_SEEK; | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
219 pthread_mutex_unlock(&this->vm_lock); |
114 | 220 return S_OK; |
0 | 221 } |
114 | 222 |
223 fprintf(MSG_OUT, "libdvdnav: Error when seeking, asked to seek outside program\n"); | |
76 | 224 fprintf(MSG_OUT, "libdvdnav: FIXME: Implement seeking to location %u\n", target); |
114 | 225 printerr("Error when seeking."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
226 pthread_mutex_unlock(&this->vm_lock); |
114 | 227 return S_ERR; |
0 | 228 } |
229 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
230 dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int part) { |
114 | 231 int title, old_part; |
232 | |
233 if (dvdnav_current_title_info(this, &title, &old_part) == S_OK) | |
234 return dvdnav_part_play(this, title, part); | |
235 return S_ERR; | |
0 | 236 } |
237 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
238 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
|
239 |
114 | 240 if(!this) { |
241 printerr("Passed a NULL pointer."); | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
242 return S_ERR; |
114 | 243 } |
244 | |
245 pthread_mutex_lock(&this->vm_lock); | |
246 if(!this->vm->state.pgc) { | |
247 printerr("No current PGC."); | |
248 pthread_mutex_unlock(&this->vm_lock); | |
249 return S_ERR; | |
250 } | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
251 |
114 | 252 #ifdef LOG_DEBUG |
113 | 253 fprintf(MSG_OUT, "libdvdnav: previous chapter\n"); |
114 | 254 #endif |
255 if (!vm_jump_prev_pg(this->vm)) { | |
256 fprintf(MSG_OUT, "libdvdnav: previous chapter failed.\n"); | |
257 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
|
258 pthread_mutex_unlock(&this->vm_lock); |
0 | 259 return S_ERR; |
260 } | |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
261 this->position_current.still = 0; |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
262 this->vm->hop_channel++; |
114 | 263 #ifdef LOG_DEBUG |
76 | 264 fprintf(MSG_OUT, "libdvdnav: previous chapter done\n"); |
114 | 265 #endif |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
266 pthread_mutex_unlock(&this->vm_lock); |
0 | 267 |
268 return S_OK; | |
269 } | |
270 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
271 dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) { |
0 | 272 |
114 | 273 if(!this) { |
274 printerr("Passed a NULL pointer."); | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
275 return S_ERR; |
114 | 276 } |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
277 |
114 | 278 pthread_mutex_lock(&this->vm_lock); |
279 if(!this->vm->state.pgc) { | |
280 printerr("No current PGC."); | |
281 pthread_mutex_unlock(&this->vm_lock); | |
282 return S_ERR; | |
283 } | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
284 |
114 | 285 #ifdef LOG_DEBUG |
286 fprintf(MSG_OUT, "libdvdnav: top chapter\n"); | |
287 #endif | |
288 if (!vm_jump_top_pg(this->vm)) { | |
289 fprintf(MSG_OUT, "libdvdnav: top chapter failed.\n"); | |
290 printerr("Skip to top chapter failed."); | |
113 | 291 pthread_mutex_unlock(&this->vm_lock); |
292 return S_ERR; | |
0 | 293 } |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
294 this->position_current.still = 0; |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
295 this->vm->hop_channel++; |
114 | 296 #ifdef LOG_DEBUG |
297 fprintf(MSG_OUT, "libdvdnav: top chapter done\n"); | |
298 #endif | |
299 pthread_mutex_unlock(&this->vm_lock); | |
300 | |
301 return S_OK; | |
302 } | |
303 | |
304 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
|
305 vm_t *try_vm; |
114 | 306 |
307 if(!this) { | |
308 printerr("Passed a NULL pointer."); | |
309 return S_ERR; | |
310 } | |
311 | |
312 pthread_mutex_lock(&this->vm_lock); | |
313 if(!this->vm->state.pgc) { | |
314 printerr("No current PGC."); | |
315 pthread_mutex_unlock(&this->vm_lock); | |
316 return S_ERR; | |
317 } | |
318 | |
319 #ifdef LOG_DEBUG | |
320 fprintf(MSG_OUT, "libdvdnav: next chapter\n"); | |
321 #endif | |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
322 /* 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
|
323 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
|
324 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
|
325 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
|
326 /* 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
|
327 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
|
328 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
|
329 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
|
330 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
|
331 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
|
332 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
|
333 pthread_mutex_unlock(&this->vm_lock); |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
334 return S_ERR; |
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
335 } |
114 | 336 } |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
337 /* 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
|
338 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
|
339 vm_free_copy(try_vm); |
114 | 340 this->position_current.still = 0; |
341 this->vm->hop_channel++; | |
342 #ifdef LOG_DEBUG | |
76 | 343 fprintf(MSG_OUT, "libdvdnav: next chapter done\n"); |
114 | 344 #endif |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
345 pthread_mutex_unlock(&this->vm_lock); |
0 | 346 |
347 return S_OK; | |
348 } | |
349 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
350 dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { |
125 | 351 vm_t *try_vm; |
114 | 352 |
353 if(!this) { | |
354 printerr("Passed a NULL pointer."); | |
0 | 355 return S_ERR; |
356 } | |
357 | |
114 | 358 pthread_mutex_lock(&this->vm_lock); |
359 if(!this->vm->state.pgc) { | |
360 printerr("No current PGC."); | |
361 pthread_mutex_unlock(&this->vm_lock); | |
362 return S_ERR; | |
363 } | |
364 | |
125 | 365 /* make a copy of current VM and try to navigate the copy to the menu */ |
366 try_vm = vm_new_copy(this->vm); | |
367 if (vm_jump_menu(try_vm, menu) && !try_vm->stopped) { | |
368 /* merge changes on success */ | |
369 vm_merge(this->vm, try_vm); | |
370 vm_free_copy(try_vm); | |
129 | 371 this->position_current.still = 0; |
114 | 372 this->vm->hop_channel++; |
373 pthread_mutex_unlock(&this->vm_lock); | |
374 return S_OK; | |
375 } else { | |
125 | 376 vm_free_copy(try_vm); |
377 printerr("No such menu or menu not reachable."); | |
114 | 378 pthread_mutex_unlock(&this->vm_lock); |
379 return S_ERR; | |
380 } | |
0 | 381 } |
382 | |
114 | 383 dvdnav_status_t dvdnav_get_position(dvdnav_t *this, unsigned int *pos, |
0 | 384 unsigned int *len) { |
385 uint32_t cur_sector; | |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
386 uint32_t cell_nr; |
0 | 387 uint32_t first_cell_nr; |
388 uint32_t last_cell_nr; | |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
389 cell_playback_t *cell; |
0 | 390 dvd_state_t *state; |
114 | 391 |
392 if(!this || !pos || !len) { | |
393 printerr("Passed a NULL pointer."); | |
394 return S_ERR; | |
395 } | |
396 if(!this->started) { | |
397 printerr("Virtual DVD machine not started."); | |
398 return S_ERR; | |
399 } | |
400 | |
401 pthread_mutex_lock(&this->vm_lock); | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
402 state = &(this->vm->state); |
114 | 403 if(!state->pgc) { |
404 printerr("No current PGC."); | |
405 pthread_mutex_unlock(&this->vm_lock); | |
406 return S_ERR; | |
0 | 407 } |
114 | 408 |
0 | 409 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
410 cur_sector = this->vobu.vobu_start + this->vobu.blockN; |
0 | 411 |
132 | 412 if (this->pgc_based) { |
413 first_cell_nr = 1; | |
414 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 415 } else { |
132 | 416 /* Find start cell of program. */ |
417 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
418 /* Find end cell of program */ | |
419 if(state->pgN < state->pgc->nr_of_programs) | |
420 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
421 else | |
422 last_cell_nr = state->pgc->nr_of_cells; | |
0 | 423 } |
132 | 424 |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
425 *pos = -1; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
426 *len = 0; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
427 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
|
428 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
|
429 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
|
430 /* 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
|
431 * 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
|
432 *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
|
433 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
434 *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
|
435 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
436 |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
437 assert(*pos != -1); |
0 | 438 |
114 | 439 pthread_mutex_unlock(&this->vm_lock); |
0 | 440 |
441 return S_OK; | |
442 } | |
443 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
444 dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *this, |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
445 unsigned int *pos, |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
446 unsigned int *len) { |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
447 uint32_t cur_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
448 uint32_t first_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
449 uint32_t last_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
450 cell_playback_t *first_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
451 cell_playback_t *last_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
452 dvd_state_t *state; |
114 | 453 |
454 if(!this || !pos || !len) { | |
455 printerr("Passed a NULL pointer."); | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
456 return S_ERR; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
457 } |
114 | 458 |
459 state = &(this->vm->state); | |
460 if(!state->pgc) { | |
461 printerr("No current PGC."); | |
462 return S_ERR; | |
463 } | |
464 | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
465 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
466 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
|
467 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
468 /* 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
|
469 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
|
470 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
|
471 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
|
472 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
|
473 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
474 *pos = cur_sector - first_cell->first_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
475 *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
|
476 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
477 return S_OK; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
478 } |