diff options
author | Michael Roitzsch <mroi@users.sourceforge.net> | 2003-03-21 22:13:37 +0000 |
---|---|---|
committer | Michael Roitzsch <mroi@users.sourceforge.net> | 2003-03-21 22:13:37 +0000 |
commit | ae83701d4b53dbd4b49ffade77d85f391aee5bed (patch) | |
tree | 55db1c3ee746607f3b134731e6d7ab4fb74dc376 /src | |
parent | cfed69ca942b61ae616b378d6209ca6b93ef7dd4 (diff) | |
download | xine-lib-ae83701d4b53dbd4b49ffade77d85f391aee5bed.tar.gz xine-lib-ae83701d4b53dbd4b49ffade77d85f391aee5bed.tar.bz2 |
sync to libdvdnav cvs
* method to try-run VM operations, now used for safer chapter skipping and menu jumps
* fixed detection of current PTT to not assume a 1:1 mapping between PTTs and PGs
* releasing stills when jumping to menu fixes some state inconsistencies
* do not assume PGs to be physically layed out in sequence on the disc
CVS patchset: 4466
CVS date: 2003/03/21 22:13:37
Diffstat (limited to 'src')
-rw-r--r-- | src/input/libdvdnav/dvdnav.c | 20 | ||||
-rw-r--r-- | src/input/libdvdnav/dvdnav.h | 35 | ||||
-rw-r--r-- | src/input/libdvdnav/searching.c | 84 | ||||
-rw-r--r-- | src/input/libdvdnav/vm.c | 142 | ||||
-rw-r--r-- | src/input/libdvdnav/vm.h | 9 |
5 files changed, 205 insertions, 85 deletions
diff --git a/src/input/libdvdnav/dvdnav.c b/src/input/libdvdnav/dvdnav.c index dc3acb190..a86002169 100644 --- a/src/input/libdvdnav/dvdnav.c +++ b/src/input/libdvdnav/dvdnav.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvdnav.c,v 1.17 2003/02/26 20:44:12 mroi Exp $ + * $Id: dvdnav.c,v 1.18 2003/03/21 22:13:37 mroi Exp $ * */ @@ -393,6 +393,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, /* Check the STOP flag */ if(this->vm->stopped) { + vm_stop(this->vm); (*event) = DVDNAV_STOP; this->started = 0; pthread_mutex_unlock(&this->vm_lock); @@ -401,7 +402,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, vm_position_get(this->vm, &this->position_next); -#ifdef TRACE +#ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: POS-NEXT "); vm_position_print(this->vm, &this->position_next); fprintf(MSG_OUT, "libdvdnav: POS-CUR "); @@ -447,9 +448,9 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, } } this->position_current.hop_channel = this->position_next.hop_channel; - /* Make blockN > vobu_length to do expected_nav */ + /* Make blockN == vobu_length to do expected_nav */ this->vobu.vobu_length = 0; - this->vobu.blockN = 1; + this->vobu.blockN = 0; this->sync_wait = 0; pthread_mutex_unlock(&this->vm_lock); return S_OK; @@ -569,9 +570,9 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, /* vobu info is used for mid cell resumes */ this->vobu.vobu_start = this->position_next.cell_start + this->position_next.block; this->vobu.vobu_next = 0; - /* Make blockN > vobu_length to do expected_nav */ + /* Make blockN == vobu_length to do expected_nav */ this->vobu.vobu_length = 0; - this->vobu.blockN = 1; + this->vobu.blockN = 0; /* update the spu palette at least on PGC changes */ this->spu_clut_changed = 1; @@ -979,6 +980,13 @@ uint32_t dvdnav_get_next_still_flag(dvdnav_t *this) { /* * $Log: dvdnav.c,v $ + * Revision 1.18 2003/03/21 22:13:37 mroi + * sync to libdvdnav cvs + * * method to try-run VM operations, now used for safer chapter skipping and menu jumps + * * fixed detection of current PTT to not assume a 1:1 mapping between PTTs and PGs + * * releasing stills when jumping to menu fixes some state inconsistencies + * * do not assume PGs to be physically layed out in sequence on the disc + * * Revision 1.17 2003/02/26 20:44:12 mroi * sync to current libdvdnav cvs, important change is the new DVDNAV_WAIT event, * which allows us to keep libdvdnav and what is seen on screen in sync in certain diff --git a/src/input/libdvdnav/dvdnav.h b/src/input/libdvdnav/dvdnav.h index 6702f6784..69f2367cc 100644 --- a/src/input/libdvdnav/dvdnav.h +++ b/src/input/libdvdnav/dvdnav.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvdnav.h,v 1.6 2003/02/26 20:44:13 mroi Exp $ + * $Id: dvdnav.h,v 1.7 2003/03/21 22:13:37 mroi Exp $ * */ @@ -376,7 +376,7 @@ dvdnav_status_t dvdnav_stop(dvdnav_t *self); dvdnav_status_t dvdnav_go_up(dvdnav_t *self); /** - * Stop playing the current title and jump to the specified menu. + * Stop playing the current position and jump to the specified menu. * * \param self Pointer to dvdnav_t associated with this operation. * \param menu Which menu to call (see DVDMenuID_t). @@ -407,7 +407,7 @@ dvdnav_status_t dvdnav_current_title_info(dvdnav_t *self, int *title, */ /** - * Stop playing the current title and start playback of the title + * Stop playing the current position and start playback of the title * from the specified timecode. * * \par Note: @@ -420,7 +420,12 @@ dvdnav_status_t dvdnav_time_search(dvdnav_t *self, unsigned long int time); /** - * Stop playing the current title and start playback of the title + * Stop playing the current position and start playback from the last + * VOBU boundary before the given sector. The sector number is not + * meant to be an absolute physical DVD sector, but a relative sector + * in the current program. This function cannot leave the current + * program and will fail, if asked to do so. + * * from the specified sector offset. * * \param self Pointer to dvdnav_t associated with this operation. @@ -431,7 +436,7 @@ dvdnav_status_t dvdnav_sector_search(dvdnav_t *self, unsigned long int offset, int origin); /** - * Stop playing the current title and start playback of the title + * Stop playing the current position and start playback of the current title * from the specified part (chapter). * * \param self Pointer to dvdnav_t associated with this operation. @@ -440,24 +445,24 @@ dvdnav_status_t dvdnav_sector_search(dvdnav_t *self, dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int part); /** - * Stop playing the current title and start playback of the title - * from the previous program (if it exists). + * Stop playing the current position and start playback at the + * previous program (if it exists). * * \param self Pointer to dvdnav_t associated with this operation. */ dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *self); /** - * Stop playing the current title and start playback of the title - * from the first program. + * Stop playing the current position and start playback at the + * first program. * * \param self Pointer to dvdnav_t associated with this operation. */ dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *self); /** - * Stop playing the current title and start playback of the title - * from the next program (if it exists). + * Stop playing the current position and start playback at the + * next program (if it exists). * * \param self Pointer to dvdnav_t associated with this operation. */ @@ -465,11 +470,11 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *self); /** * Return the current position (in blocks) within the current - * part and the length (in blocks) of said part. + * program and the length (in blocks) of current program. * * \param self Pointer to dvdnav_t associated with this operation. * \param pos Pointer to unsigned int to get the current position. - * \param len Pointer to unsinged int to hold the length of the current part. + * \param len Pointer to unsinged int to hold the length of the current program. */ dvdnav_status_t dvdnav_get_position(dvdnav_t *self, unsigned int *pos, unsigned int *len); @@ -478,6 +483,10 @@ dvdnav_status_t dvdnav_get_position(dvdnav_t *self, unsigned int *pos, * Return the current position (in blocks) within the current * title and the length (in blocks) of said title. * + * \par Note: + * Current implementation is wrong and likely to behave unpredictably. + * Use is discouraged. + * * \param self Pointer to dvdnav_t associated with this operation. * \param pos Pointer to unsigned int to get the current position. * \param len Pointer to unsinged int to hold the length of the current title. diff --git a/src/input/libdvdnav/searching.c b/src/input/libdvdnav/searching.c index 526fb94e8..195ee9705 100644 --- a/src/input/libdvdnav/searching.c +++ b/src/input/libdvdnav/searching.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: searching.c,v 1.10 2003/03/08 14:36:13 mroi Exp $ + * $Id: searching.c,v 1.11 2003/03/21 22:13:38 mroi Exp $ * */ @@ -177,14 +177,16 @@ dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, } found = 0; - target += state->pgc->cell_playback[first_cell_nr-1].first_sector; for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { cell = &(state->pgc->cell_playback[cell_nr-1]); - if((cell->first_sector <= target) && (cell->last_sector >= target)) { + length = cell->last_sector - cell->first_sector + 1; + if (target >= length) { + target -= length; + } else { + /* convert the target sector from Cell-relative to absolute physical sector */ + target += cell->first_sector; found = 1; - state->cellN = cell_nr; - state->blockN = 0; - state->cell_restart++; + break; } } @@ -192,10 +194,14 @@ dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, int32_t vobu, start; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n", - state->cellN, first_cell_nr, last_cell_nr); + cell_nr, first_cell_nr, last_cell_nr); #endif dvdnav_scan_admap(this, state->domain, target, &vobu); - start = state->pgc->cell_playback[state->cellN - 1].first_sector; + + start = state->pgc->cell_playback[cell_nr-1].first_sector; + state->blockN = vobu - start; + state->cellN = cell_nr; + state->cell_restart++; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , state->cellN, @@ -204,13 +210,6 @@ dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, vobu, start); #endif - state->blockN = vobu - start; -#ifdef LOG_DEBUG - fprintf(MSG_OUT, "libdvdnav: After vobu=%x start=%x blockN=%x\n" , - vobu, - start, - state->blockN); -#endif this->vm->hop_channel += HOP_SEEK; pthread_mutex_unlock(&this->vm_lock); return S_OK; @@ -298,6 +297,7 @@ dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) { } dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) { + vm_t *try_vm; if(!this) { printerr("Passed a NULL pointer."); @@ -314,12 +314,24 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) { #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: next chapter\n"); #endif - if (!vm_jump_next_pg(this->vm)) { - fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n"); - printerr("Skip to next chapter failed."); - pthread_mutex_unlock(&this->vm_lock); - return S_ERR; + /* make a copy of current VM and try to navigate the copy to the next PG */ + try_vm = vm_new_copy(this->vm); + if (!vm_jump_next_pg(try_vm) || try_vm->stopped) { + vm_free_copy(try_vm); + /* next_pg failed, try to jump at least to the next cell */ + try_vm = vm_new_copy(this->vm); + vm_get_next_cell(try_vm); + if (try_vm->stopped) { + vm_free_copy(try_vm); + fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n"); + printerr("Skip to next chapter failed."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } } + /* merge changes on success */ + vm_merge(this->vm, try_vm); + vm_free_copy(try_vm); this->position_current.still = 0; this->vm->hop_channel++; #ifdef LOG_DEBUG @@ -331,6 +343,7 @@ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) { } dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { + vm_t *try_vm; if(!this) { printerr("Passed a NULL pointer."); @@ -344,12 +357,19 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { return S_ERR; } - if (vm_jump_menu(this->vm, menu)) { + /* make a copy of current VM and try to navigate the copy to the menu */ + try_vm = vm_new_copy(this->vm); + if (vm_jump_menu(try_vm, menu) && !try_vm->stopped) { + /* merge changes on success */ + vm_merge(this->vm, try_vm); + vm_free_copy(try_vm); + this->position_current.still = 0; this->vm->hop_channel++; pthread_mutex_unlock(&this->vm_lock); return S_OK; } else { - printerr("No such menu."); + vm_free_copy(try_vm); + printerr("No such menu or menu not reachable."); pthread_mutex_unlock(&this->vm_lock); return S_ERR; } @@ -358,8 +378,10 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { dvdnav_status_t dvdnav_get_position(dvdnav_t *this, unsigned int *pos, unsigned int *len) { uint32_t cur_sector; + uint32_t cell_nr; uint32_t first_cell_nr; uint32_t last_cell_nr; + cell_playback_t *cell; cell_playback_t *first_cell; cell_playback_t *last_cell; dvd_state_t *state; @@ -395,9 +417,21 @@ dvdnav_status_t dvdnav_get_position(dvdnav_t *this, unsigned int *pos, last_cell_nr = state->pgc->nr_of_cells; } last_cell = &(state->pgc->cell_playback[last_cell_nr-1]); + + *pos = -1; + *len = 0; + for (cell_nr = first_cell_nr; cell_nr <= last_cell_nr; cell_nr++) { + cell = &(state->pgc->cell_playback[cell_nr-1]); + if (cell_nr == state->cellN) { + /* the current sector is in this cell, + * pos is length of PG up to here + sector's offset in this cell */ + *pos = *len + cur_sector - cell->first_sector; + } + *len += cell->last_sector - cell->first_sector + 1; + } + + assert(*pos != -1); - *pos= cur_sector - first_cell->first_sector; - *len= last_cell->last_sector - first_cell->first_sector; pthread_mutex_unlock(&this->vm_lock); return S_OK; diff --git a/src/input/libdvdnav/vm.c b/src/input/libdvdnav/vm.c index 740928be0..0248292b6 100644 --- a/src/input/libdvdnav/vm.c +++ b/src/input/libdvdnav/vm.c @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: vm.c,v 1.13 2003/02/20 16:02:01 mroi Exp $ + * $Id: vm.c,v 1.14 2003/03/21 22:13:38 mroi Exp $ * */ @@ -251,8 +251,7 @@ dvd_reader_t *vm_get_dvd_reader(vm_t *vm) { /* Basic Handling */ -void vm_start(vm_t *vm) -{ +void vm_start(vm_t *vm) { /* Set pgc to FP (First Play) pgc */ set_FP_PGC(vm); process_command(vm, play_PGC(vm)); @@ -265,7 +264,7 @@ void vm_stop(vm_t *vm) { } if(vm->vtsi) { ifoClose(vm->vtsi); - vm->vmgi=NULL; + vm->vtsi=NULL; } if(vm->dvd) { DVDClose(vm->dvd); @@ -364,6 +363,48 @@ int vm_reset(vm_t *vm, const char *dvdroot) { } +/* copying and merging */ + +vm_t *vm_new_copy(vm_t *source) { + vm_t *target = vm_new_vm(); + int vtsN; + int pgcN = get_PGCN(source); + int pgN = (source->state).pgN; + + assert(pgcN); + + memcpy(target, source, sizeof(vm_t)); + + /* open a new vtsi handle, because the copy might switch to another VTS */ + target->vtsi = NULL; + vtsN = (target->state).vtsN; + if (vtsN > 0) { + (target->state).vtsN = 0; + ifoOpenNewVTSI(target, target->dvd, vtsN); + + /* restore pgc pointer into the new vtsi */ + if (!set_PGCN(target, pgcN)) + assert(0); + (target->state).pgN = pgN; + } + + return target; +} + +void vm_merge(vm_t *target, vm_t *source) { + if(target->vtsi) + ifoClose(target->vtsi); + memcpy(target, source, sizeof(vm_t)); + memset(source, 0, sizeof(vm_t)); +} + +void vm_free_copy(vm_t *vm) { + if(vm->vtsi) + ifoClose(vm->vtsi); + free(vm); +} + + /* regular playback */ void vm_position_get(vm_t *vm, vm_position_t *position) { @@ -399,14 +440,19 @@ void vm_position_get(vm_t *vm, vm_position_t *position) { if (((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector == (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_vobu_start_sector) && ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector - - (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector < 250)) { + (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector < 1024)) { int time; + int size = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector - + (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector; time = ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour & 0xf0) * 36000; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour & 0x0f) * 3600; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0xf0) * 600; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0x0f) * 60; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0xf0) * 10; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0x0f) * 1; + if (size / time > 30) + /* datarate is too high, it might be a very short, but regular cell */ + return; if (time > 0xff) time = 0xff; position->still = time; } @@ -458,6 +504,7 @@ int vm_jump_prev_pg(vm_t *vm) { /* first program -> move to last program of previous PGC */ if ((vm->state).pgc->prev_pgc_nr && set_PGCN(vm, (vm->state).pgc->prev_pgc_nr)) { process_command(vm, play_PGC(vm)); + vm_jump_pg(vm, (vm->state).pgc->nr_of_programs); return 1; } return 0; @@ -535,10 +582,17 @@ int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) { found = 0; for (vts_ttn = 0; (vts_ttn < vts_ptt_srpt->nr_of_srpts) && !found; vts_ttn++) { for (part = 0; (part < vts_ptt_srpt->title[vts_ttn].nr_of_ptts) && !found; part++) { - if ((vts_ptt_srpt->title[vts_ttn].ptt[part].pgcn == pgcN) && - (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn == pgN )) { - found = 1; - break; + if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgcn == pgcN) { + if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn == pgN) { + found = 1; + break; + } + if (part > 0 && vts_ptt_srpt->title[vts_ttn].ptt[part].pgn > pgN && + vts_ptt_srpt->title[vts_ttn].ptt[part - 1].pgn < pgN) { + part--; + found = 1; + break; + } } } if (found) break; @@ -546,6 +600,11 @@ int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) { vts_ttn++; part++; + if (!found) { + fprintf(MSG_OUT, "libdvdnav: chapter NOT FOUND!\n"); + return 0; + } + title = get_TT(vm, vm->state.vtsN, vts_ttn); #ifdef TRACE @@ -553,14 +612,10 @@ int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) { fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n"); fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n", title, part, - vts_ptt_srpt->title[ttn-1].ptt[part-1].pgcn , - vts_ptt_srpt->title[ttn-1].ptt[part-1].pgn ); - } else { - fprintf(MSG_OUT, "libdvdnav: ************ this chapter NOT FOUND!\n"); + vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgcn , + vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgn ); } #endif - if (!title) - return 0; *title_result = title; *part_result = part; return 1; @@ -572,10 +627,6 @@ int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) { int vm_get_audio_stream(vm_t *vm, int audioN) { int streamN = -1; -#ifdef TRACE - fprintf(MSG_OUT, "libdvdnav: vm.c:get_audio_stream audioN=%d\n",audioN); -#endif - if((vm->state).domain != VTS_DOMAIN) audioN = 0; @@ -818,7 +869,7 @@ static link_t play_PGC(vm_t *vm) { link_t link_values; #ifdef TRACE - fprintf(MSG_OUT, "libdvdnav: vm: play_PGC:"); + fprintf(MSG_OUT, "libdvdnav: play_PGC:"); if((vm->state).domain != FP_DOMAIN) { fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); } else { @@ -858,7 +909,7 @@ static link_t play_PGC_PG(vm_t *vm, int pgN) { link_t link_values; #ifdef TRACE - fprintf(MSG_OUT, "libdvdnav: vm: play_PGC:"); + fprintf(MSG_OUT, "libdvdnav: play_PGC:"); if((vm->state).domain != FP_DOMAIN) { fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); } else { @@ -909,7 +960,7 @@ static link_t play_PGC_post(vm_t *vm) { - just go to next PGC (This is what happens if you fall of the end of the post_cmds) - or an error (are there more cases?) */ - if((vm->state).pgc->command_tbl && + if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_post && vmEval_CMD((vm->state).pgc->command_tbl->post_cmds, (vm->state).pgc->command_tbl->nr_of_post, &(vm->state).registers, &link_values)) { @@ -919,10 +970,11 @@ static link_t play_PGC_post(vm_t *vm) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n"); #endif - assert((vm->state).pgc->next_pgc_nr != 0); /* Should end up in the STOP_DOMAIN if next_pgc is 0. */ - if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) - assert(0); + if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) { + link_values.command = Exit; + return link_values; + } return play_PGC(vm); } @@ -1229,8 +1281,13 @@ static int process_command(vm_t *vm, link_t link_values) { /* Link to Resume point */ int i; - /* Check and see if there is any rsm info!! */ - assert((vm->state).rsm_vtsN); + /* Check and see if there is any rsm info!! */ + if (!(vm->state).rsm_vtsN) { + fprintf(MSG_OUT, "libdvdnav: trying to resume without any resume info set\n"); + link_values.command = Exit; + break; + } + (vm->state).domain = VTS_DOMAIN; ifoOpenNewVTSI(vm, vm->dvd, (vm->state).rsm_vtsN); set_PGCN(vm, (vm->state).rsm_pgcN); @@ -1299,8 +1356,8 @@ static int process_command(vm_t *vm, link_t link_values) { break; case Exit: - fprintf(MSG_OUT, "libdvdnav: FIXME:in trouble...Link Exit - CRASHING!!!\n"); - assert(0); /* What should we do here?? */ + vm->stopped = 1; + return 0; case JumpTT: /* Jump to VTS Title Domain */ @@ -1479,7 +1536,7 @@ static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) { pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn; (vm->state).TT_PGCN_REG = pgcN; - (vm->state).PTTN_REG = pgN; + (vm->state).PTTN_REG = part; (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn); assert( (vm->state.TTN_REG) != 0 ); (vm->state).VTS_TTN_REG = vts_ttn; @@ -1545,7 +1602,7 @@ static int set_PGN(vm_t *vm) { return 0; /* ?? */ pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty; if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) { - int dummy; + int dummy, part; #if 0 /* TTN_REG can't be trusted to have a correct value here... */ vts_ptt_srpt_t *ptt_srpt = vtsi->vts_ptt_srpt; @@ -1553,8 +1610,8 @@ static int set_PGN(vm_t *vm) { assert(get_PGCN() == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgcn); assert(1 == ptt_srpt->title[(vm->state).VTS_TTN_REG - 1].ptt[0].pgn); #endif - vm_get_current_title_part(vm, &dummy, &(vm->state).pgN); - (vm->state).PTTN_REG = (vm->state).pgN; + vm_get_current_title_part(vm, &dummy, &part); + (vm->state).PTTN_REG = part; } else { /* FIXME: Handle RANDOM or SHUFFLE titles. */ fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n"); @@ -1649,16 +1706,16 @@ static int get_PGCN(vm_t *vm) { int pgcN = 1; pgcit = get_PGCIT(vm); - assert(pgcit != NULL); - while(pgcN <= pgcit->nr_of_pgci_srp) { - if(pgcit->pgci_srp[pgcN - 1].pgc == (vm->state).pgc) - return pgcN; - pgcN++; + if (pgcit) { + while(pgcN <= pgcit->nr_of_pgci_srp) { + if(pgcit->pgci_srp[pgcN - 1].pgc == (vm->state).pgc) + return pgcN; + pgcN++; + } } fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n", (vm->state).domain); - /* assert(0);*/ return 0; /* error */ } @@ -1742,6 +1799,13 @@ void vm_position_print(vm_t *vm, vm_position_t *position) { /* * $Log: vm.c,v $ + * Revision 1.14 2003/03/21 22:13:38 mroi + * sync to libdvdnav cvs + * * method to try-run VM operations, now used for safer chapter skipping and menu jumps + * * fixed detection of current PTT to not assume a 1:1 mapping between PTTs and PGs + * * releasing stills when jumping to menu fixes some state inconsistencies + * * do not assume PGs to be physically layed out in sequence on the disc + * * Revision 1.13 2003/02/20 16:02:01 mroi * syncing to libdvdnav 0.1.5 and modifying input plugin accordingly * quoting the ChangeLog: diff --git a/src/input/libdvdnav/vm.h b/src/input/libdvdnav/vm.h index 9b1f0cfc8..ee5e4d16f 100644 --- a/src/input/libdvdnav/vm.h +++ b/src/input/libdvdnav/vm.h @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: vm.h,v 1.4 2003/02/20 16:02:01 mroi Exp $ + * $Id: vm.h,v 1.5 2003/03/21 22:13:39 mroi Exp $ * */ @@ -113,7 +113,7 @@ typedef struct { #define PTL_REG registers.SPRM[13] /* Initialisation & destruction */ -vm_t* vm_new_vm(); +vm_t *vm_new_vm(); void vm_free_vm(vm_t *vm); /* IFO access */ @@ -128,6 +128,11 @@ void vm_start(vm_t *vm); void vm_stop(vm_t *vm); int vm_reset(vm_t *vm, const char *dvdroot); +/* copying and merging - useful for try-running an operation */ +vm_t *vm_new_copy(vm_t *vm); +void vm_merge(vm_t *target, vm_t *source); +void vm_free_copy(vm_t *vm); + /* regular playback */ void vm_position_get(vm_t *vm, vm_position_t *position); void vm_get_next_cell(vm_t *vm); |