Mercurial > libdvdnav.hg
annotate searching.c @ 130:f47065513ad8 src
do not assume PGs to be physically layed out in sequence on the disc
author | mroi |
---|---|
date | Thu, 20 Mar 2003 12:22:59 +0000 |
parents | b48f53f7cff2 |
children | ada79e606d8d |
rev | line source |
---|---|
0 | 1 /* |
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 | |
171 /* First find closest cell number in program */ | |
172 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
173 if(state->pgN < state->pgc->nr_of_programs) { | |
174 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
175 } else { | |
176 last_cell_nr = state->pgc->nr_of_cells; | |
177 } | |
178 | |
114 | 179 found = 0; |
0 | 180 for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { |
181 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
|
182 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
|
183 if (target >= length) { |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
184 target -= length; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
185 } else { |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
186 /* convert the target sector from PG-relative to absolute physical sector */ |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
187 target += cell->first_sector; |
114 | 188 found = 1; |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
189 break; |
0 | 190 } |
191 } | |
192 | |
114 | 193 if(found) { |
26 | 194 int32_t vobu, start; |
114 | 195 #ifdef LOG_DEBUG |
76 | 196 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
|
197 cell_nr, first_cell_nr, last_cell_nr); |
114 | 198 #endif |
199 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
|
200 |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
201 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
|
202 state->blockN = vobu - start; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
203 state->cellN = cell_nr; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
204 state->cell_restart++; |
114 | 205 #ifdef LOG_DEBUG |
206 fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , | |
0 | 207 state->cellN, |
24 | 208 state->blockN, |
209 target, | |
210 vobu, | |
211 start); | |
114 | 212 #endif |
213 this->vm->hop_channel += HOP_SEEK; | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
214 pthread_mutex_unlock(&this->vm_lock); |
114 | 215 return S_OK; |
0 | 216 } |
114 | 217 |
218 fprintf(MSG_OUT, "libdvdnav: Error when seeking, asked to seek outside program\n"); | |
76 | 219 fprintf(MSG_OUT, "libdvdnav: FIXME: Implement seeking to location %u\n", target); |
114 | 220 printerr("Error when seeking."); |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
221 pthread_mutex_unlock(&this->vm_lock); |
114 | 222 return S_ERR; |
0 | 223 } |
224 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
225 dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int part) { |
114 | 226 int title, old_part; |
227 | |
228 if (dvdnav_current_title_info(this, &title, &old_part) == S_OK) | |
229 return dvdnav_part_play(this, title, part); | |
230 return S_ERR; | |
0 | 231 } |
232 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
233 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
|
234 |
114 | 235 if(!this) { |
236 printerr("Passed a NULL pointer."); | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
237 return S_ERR; |
114 | 238 } |
239 | |
240 pthread_mutex_lock(&this->vm_lock); | |
241 if(!this->vm->state.pgc) { | |
242 printerr("No current PGC."); | |
243 pthread_mutex_unlock(&this->vm_lock); | |
244 return S_ERR; | |
245 } | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
246 |
114 | 247 #ifdef LOG_DEBUG |
113 | 248 fprintf(MSG_OUT, "libdvdnav: previous chapter\n"); |
114 | 249 #endif |
250 if (!vm_jump_prev_pg(this->vm)) { | |
251 fprintf(MSG_OUT, "libdvdnav: previous chapter failed.\n"); | |
252 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
|
253 pthread_mutex_unlock(&this->vm_lock); |
0 | 254 return S_ERR; |
255 } | |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
256 this->position_current.still = 0; |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
257 this->vm->hop_channel++; |
114 | 258 #ifdef LOG_DEBUG |
76 | 259 fprintf(MSG_OUT, "libdvdnav: previous chapter done\n"); |
114 | 260 #endif |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
261 pthread_mutex_unlock(&this->vm_lock); |
0 | 262 |
263 return S_OK; | |
264 } | |
265 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
266 dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) { |
0 | 267 |
114 | 268 if(!this) { |
269 printerr("Passed a NULL pointer."); | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
270 return S_ERR; |
114 | 271 } |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
272 |
114 | 273 pthread_mutex_lock(&this->vm_lock); |
274 if(!this->vm->state.pgc) { | |
275 printerr("No current PGC."); | |
276 pthread_mutex_unlock(&this->vm_lock); | |
277 return S_ERR; | |
278 } | |
68
3b45c78f061e
Some NULL-pointer check from aschultz@cs.uni-magdeburg.de
richwareham
parents:
63
diff
changeset
|
279 |
114 | 280 #ifdef LOG_DEBUG |
281 fprintf(MSG_OUT, "libdvdnav: top chapter\n"); | |
282 #endif | |
283 if (!vm_jump_top_pg(this->vm)) { | |
284 fprintf(MSG_OUT, "libdvdnav: top chapter failed.\n"); | |
285 printerr("Skip to top chapter failed."); | |
113 | 286 pthread_mutex_unlock(&this->vm_lock); |
287 return S_ERR; | |
0 | 288 } |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
289 this->position_current.still = 0; |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
290 this->vm->hop_channel++; |
114 | 291 #ifdef LOG_DEBUG |
292 fprintf(MSG_OUT, "libdvdnav: top chapter done\n"); | |
293 #endif | |
294 pthread_mutex_unlock(&this->vm_lock); | |
295 | |
296 return S_OK; | |
297 } | |
298 | |
299 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
|
300 vm_t *try_vm; |
114 | 301 |
302 if(!this) { | |
303 printerr("Passed a NULL pointer."); | |
304 return S_ERR; | |
305 } | |
306 | |
307 pthread_mutex_lock(&this->vm_lock); | |
308 if(!this->vm->state.pgc) { | |
309 printerr("No current PGC."); | |
310 pthread_mutex_unlock(&this->vm_lock); | |
311 return S_ERR; | |
312 } | |
313 | |
314 #ifdef LOG_DEBUG | |
315 fprintf(MSG_OUT, "libdvdnav: next chapter\n"); | |
316 #endif | |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
317 /* 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
|
318 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
|
319 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
|
320 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
|
321 /* 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
|
322 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
|
323 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
|
324 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
|
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 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
|
327 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
|
328 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
|
329 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
|
330 } |
114 | 331 } |
122
29b046894eac
use the new VM copy mechanism to try-run program skipping and report failure in case
mroi
parents:
119
diff
changeset
|
332 /* 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
|
333 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
|
334 vm_free_copy(try_vm); |
114 | 335 this->position_current.still = 0; |
336 this->vm->hop_channel++; | |
337 #ifdef LOG_DEBUG | |
76 | 338 fprintf(MSG_OUT, "libdvdnav: next chapter done\n"); |
114 | 339 #endif |
102
3e6970dbe8d6
- allow seeking to offset 0 (pressing '0' in xine won't work otherwise)
mroi
parents:
90
diff
changeset
|
340 pthread_mutex_unlock(&this->vm_lock); |
0 | 341 |
342 return S_OK; | |
343 } | |
344 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
345 dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { |
125 | 346 vm_t *try_vm; |
114 | 347 |
348 if(!this) { | |
349 printerr("Passed a NULL pointer."); | |
0 | 350 return S_ERR; |
351 } | |
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); | |
357 return S_ERR; | |
358 } | |
359 | |
125 | 360 /* make a copy of current VM and try to navigate the copy to the menu */ |
361 try_vm = vm_new_copy(this->vm); | |
362 if (vm_jump_menu(try_vm, menu) && !try_vm->stopped) { | |
363 /* merge changes on success */ | |
364 vm_merge(this->vm, try_vm); | |
365 vm_free_copy(try_vm); | |
129 | 366 this->position_current.still = 0; |
114 | 367 this->vm->hop_channel++; |
368 pthread_mutex_unlock(&this->vm_lock); | |
369 return S_OK; | |
370 } else { | |
125 | 371 vm_free_copy(try_vm); |
372 printerr("No such menu or menu not reachable."); | |
114 | 373 pthread_mutex_unlock(&this->vm_lock); |
374 return S_ERR; | |
375 } | |
0 | 376 } |
377 | |
114 | 378 dvdnav_status_t dvdnav_get_position(dvdnav_t *this, unsigned int *pos, |
0 | 379 unsigned int *len) { |
380 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
|
381 uint32_t cell_nr; |
0 | 382 uint32_t first_cell_nr; |
383 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
|
384 cell_playback_t *cell; |
0 | 385 cell_playback_t *first_cell; |
386 cell_playback_t *last_cell; | |
387 dvd_state_t *state; | |
114 | 388 |
389 if(!this || !pos || !len) { | |
390 printerr("Passed a NULL pointer."); | |
391 return S_ERR; | |
392 } | |
393 if(!this->started) { | |
394 printerr("Virtual DVD machine not started."); | |
395 return S_ERR; | |
396 } | |
397 | |
398 pthread_mutex_lock(&this->vm_lock); | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
399 state = &(this->vm->state); |
114 | 400 if(!state->pgc) { |
401 printerr("No current PGC."); | |
402 pthread_mutex_unlock(&this->vm_lock); | |
403 return S_ERR; | |
0 | 404 } |
114 | 405 |
0 | 406 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
407 cur_sector = this->vobu.vobu_start + this->vobu.blockN; |
0 | 408 |
409 /* Find start cell of program. */ | |
410 first_cell_nr = state->pgc->program_map[state->pgN-1]; | |
411 first_cell = &(state->pgc->cell_playback[first_cell_nr-1]); | |
114 | 412 |
413 /* Find end cell of program */ | |
0 | 414 if(state->pgN < state->pgc->nr_of_programs) { |
415 last_cell_nr = state->pgc->program_map[state->pgN] - 1; | |
416 } else { | |
417 last_cell_nr = state->pgc->nr_of_cells; | |
418 } | |
419 last_cell = &(state->pgc->cell_playback[last_cell_nr-1]); | |
130
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
420 |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
421 *pos = -1; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
422 *len = 0; |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
423 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
|
424 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
|
425 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
|
426 /* 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
|
427 * 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
|
428 *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
|
429 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
430 *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
|
431 } |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
432 |
f47065513ad8
do not assume PGs to be physically layed out in sequence on the disc
mroi
parents:
129
diff
changeset
|
433 assert(*pos != -1); |
0 | 434 |
114 | 435 pthread_mutex_unlock(&this->vm_lock); |
0 | 436 |
437 return S_OK; | |
438 } | |
439 | |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
440 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
|
441 unsigned int *pos, |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
442 unsigned int *len) { |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
443 uint32_t cur_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
444 uint32_t first_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
445 uint32_t last_cell_nr; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
446 cell_playback_t *first_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
447 cell_playback_t *last_cell; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
448 dvd_state_t *state; |
114 | 449 |
450 if(!this || !pos || !len) { | |
451 printerr("Passed a NULL pointer."); | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
452 return S_ERR; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
453 } |
114 | 454 |
455 state = &(this->vm->state); | |
456 if(!state->pgc) { | |
457 printerr("No current PGC."); | |
458 return S_ERR; | |
459 } | |
460 | |
8
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
461 /* Get current sector */ |
22
3c1df0cb3aee
Start of rewrite of libdvdnav. Still need to re-implement seeking.
jcdutton
parents:
8
diff
changeset
|
462 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
|
463 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
464 /* 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
|
465 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
|
466 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
|
467 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
|
468 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
|
469 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
470 *pos = cur_sector - first_cell->first_sector; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
471 *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
|
472 |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
473 return S_OK; |
66708b4a1b5e
Stop C++ bitching about some things and extend the menus example
richwareham
parents:
3
diff
changeset
|
474 } |