diff options
author | Michael Roitzsch <mroi@users.sourceforge.net> | 2002-09-20 12:53:53 +0000 |
---|---|---|
committer | Michael Roitzsch <mroi@users.sourceforge.net> | 2002-09-20 12:53:53 +0000 |
commit | 0c7d2678ef70026fa05b3b0921a149d1c0e5ebfb (patch) | |
tree | 534a685276a6f33fe77692a721530a927b95185c /src | |
parent | 44a2823e79fcf9b1002f7bf537fc9c7a9b7913b3 (diff) | |
download | xine-lib-0c7d2678ef70026fa05b3b0921a149d1c0e5ebfb.tar.gz xine-lib-0c7d2678ef70026fa05b3b0921a149d1c0e5ebfb.tar.bz2 |
sync to latest libdvdnav cvs version
CVS patchset: 2718
CVS date: 2002/09/20 12:53:53
Diffstat (limited to 'src')
-rw-r--r-- | src/input/libdvdnav/Makefile.am | 2 | ||||
-rw-r--r-- | src/input/libdvdnav/diff_against_cvs.patch | 20 | ||||
-rw-r--r-- | src/input/libdvdnav/dvd_types.h | 3 | ||||
-rw-r--r-- | src/input/libdvdnav/dvdnav.c | 27 | ||||
-rw-r--r-- | src/input/libdvdnav/dvdnav.h | 34 | ||||
-rw-r--r-- | src/input/libdvdnav/highlight.c | 103 | ||||
-rw-r--r-- | src/input/libdvdnav/navigation.c | 25 | ||||
-rw-r--r-- | src/input/libdvdnav/remap.c | 225 | ||||
-rw-r--r-- | src/input/libdvdnav/remap.h | 13 | ||||
-rw-r--r-- | src/input/libdvdnav/settings.c | 27 | ||||
-rw-r--r-- | src/input/libdvdnav/vm.c | 67 | ||||
-rw-r--r-- | src/input/libdvdnav/vm.h | 6 |
12 files changed, 467 insertions, 85 deletions
diff --git a/src/input/libdvdnav/Makefile.am b/src/input/libdvdnav/Makefile.am index e15771a77..559563aa6 100644 --- a/src/input/libdvdnav/Makefile.am +++ b/src/input/libdvdnav/Makefile.am @@ -11,6 +11,7 @@ libdvdnav_la_SOURCES = \ highlight.c \ navigation.c \ read_cache.c \ + remap.c \ searching.c \ settings.c \ vm.c \ @@ -23,6 +24,7 @@ noinst_HEADERS = \ dvdnav.h \ dvdnav_events.h \ dvdnav_internal.h \ + remap.h \ vm.h \ vmcmd.h \ read_cache.h \ diff --git a/src/input/libdvdnav/diff_against_cvs.patch b/src/input/libdvdnav/diff_against_cvs.patch index 331435d00..df4658ee3 100644 --- a/src/input/libdvdnav/diff_against_cvs.patch +++ b/src/input/libdvdnav/diff_against_cvs.patch @@ -36,23 +36,25 @@ #include <stdlib.h> #include <stdio.h> -@@ -179,7 +179,7 @@ +@@ -181,7 +181,7 @@ struct timeval time; /* Create a new structure */ -- fprintf(MSG_OUT, "libdvdnav: Using dvdnav version (devel-ref:jcd1) from http://dvd.sf.net\n"); -+ fprintf(MSG_OUT, "libdvdnav: Using dvdnav version (devel-ref:jcd1) from http://xine.sf.net\n"); +- fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://dvd.sf.net\n", VERSION); ++ fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://xine.sf.net\n", VERSION); - /* FIXME: We malloc() here, but if an error occurs inside dvdnav_open(), - * we return but never free() it. + (*dest) = NULL; + this = (dvdnav_t*)malloc(sizeof(dvdnav_t)); --- src/input/libdvdnav/dvdnav.h Thu Jul 25 17:26:00 2002 +++ src/input/libdvdnav/dvdnav.h Fri Aug 9 22:01:19 2002 -@@ -40,7 +40,7 @@ +@@ -40,8 +40,8 @@ /* Various useful types */ #include "dvd_types.h" -#include <dvdread/dvd_reader.h> +-#include <dvdread/ifo_types.h> /* For vm_cmd_t */ +#include "dvd_reader.h" ++#include "ifo_types.h" /* For vm_cmd_t */ /** * Opaque data-type can be viewed as a 'DVD handle'. You should get @@ -124,9 +126,9 @@ --- src/input/libdvdnav/vm.c Sat Jul 6 18:12:09 2002 +++ src/input/libdvdnav/vm.c Fri Aug 9 22:03:48 2002 -@@ -34,8 +34,8 @@ - #include <inttypes.h> - #include <assert.h> +@@ -37,8 +37,8 @@ + #include <sys/stat.h> + #include <fcntl.h> -#include <dvdread/ifo_types.h> -#include <dvdread/ifo_read.h> diff --git a/src/input/libdvdnav/dvd_types.h b/src/input/libdvdnav/dvd_types.h index d19bce84a..2c6967b8e 100644 --- a/src/input/libdvdnav/dvd_types.h +++ b/src/input/libdvdnav/dvd_types.h @@ -18,7 +18,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: dvd_types.h,v 1.1 2002/08/08 17:49:21 richwareham Exp $ + * $Id: dvd_types.h,v 1.2 2002/09/20 12:53:53 mroi Exp $ * */ @@ -296,5 +296,4 @@ typedef struct { uint32_t buttonN; /*!< Button number for the SPU decoder. */ } dvdnav_highlight_area_t; - #endif /* DVD_H_INCLUDED */ diff --git a/src/input/libdvdnav/dvdnav.c b/src/input/libdvdnav/dvdnav.c index d1a4e7318..7e209d3a8 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.7 2002/09/04 11:07:47 mroi Exp $ + * $Id: dvdnav.c,v 1.8 2002/09/20 12:53:53 mroi Exp $ * */ @@ -40,6 +40,8 @@ #include <stdio.h> #include <sys/time.h> +#include "remap.h" + /* * NOTE: * All NLCK_*() function are not mutex locked, this made them reusable in @@ -179,11 +181,8 @@ dvdnav_status_t dvdnav_open(dvdnav_t** dest, char *path) { struct timeval time; /* Create a new structure */ - fprintf(MSG_OUT, "libdvdnav: Using dvdnav version (devel-ref:jcd1) from http://xine.sf.net\n"); + fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://xine.sf.net\n", VERSION); - /* FIXME: We malloc() here, but if an error occurs inside dvdnav_open(), - * we return but never free() it. - */ (*dest) = NULL; this = (dvdnav_t*)malloc(sizeof(dvdnav_t)); if(!this) @@ -199,10 +198,15 @@ dvdnav_status_t dvdnav_open(dvdnav_t** dest, char *path) { this->vm = vm_new_vm(); if(!this->vm) { printerr("Error initialising the DVD VM"); + pthread_mutex_destroy(&this->vm_lock); + free(this); return S_ERR; } if(vm_reset(this->vm, path) == -1) { printerr("Error starting the VM / opening the DVD device"); + pthread_mutex_destroy(&this->vm_lock); + vm_free_vm(this->vm); + free(this); return S_ERR; } @@ -593,13 +597,13 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_letterbox=%d\n",stream_change.physical_letterbox); fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_pan_scan=%d\n",stream_change.physical_pan_scan); #endif - pthread_mutex_unlock(&this->vm_lock); if (stream_change.physical_wide != -1 && stream_change.physical_letterbox != -1 && stream_change.physical_pan_scan != -1) { #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE returning S_OK\n"); #endif + pthread_mutex_unlock(&this->vm_lock); return S_OK; } } @@ -782,6 +786,14 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, unsigned char **buf, /* Perform the jump if necessary (this is always a * VOBU boundary). */ + if (this->vm->map) { + this->vobu.vobu_next = remap_block( this->vm->map, + this->vm->state.domain, this->vm->state.TTN_REG, + this->vm->state.pgN, + this->vobu.vobu_start, this->vobu.vobu_next); + } + + //result = DVDReadBlocks(this->file, this->vobu.vobu_start + this->vobu.vobu_next, 1, buf); result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.vobu_next, 1, buf); @@ -998,6 +1010,9 @@ uint32_t dvdnav_get_next_still_flag(dvdnav_t *this) { /* * $Log: dvdnav.c,v $ + * Revision 1.8 2002/09/20 12:53:53 mroi + * sync to latest libdvdnav cvs version + * * Revision 1.7 2002/09/04 11:07:47 mroi * sync to libdvdnav cvs * diff --git a/src/input/libdvdnav/dvdnav.h b/src/input/libdvdnav/dvdnav.h index 0160cc05e..2af610b26 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.3 2002/08/09 22:52:14 mroi Exp $ + * $Id: dvdnav.h,v 1.4 2002/09/20 12:53:53 mroi Exp $ * */ @@ -41,6 +41,7 @@ extern "C" { #include "dvd_types.h" #include "dvd_reader.h" +#include "ifo_types.h" /* For vm_cmd_t */ /** * Opaque data-type can be viewed as a 'DVD handle'. You should get @@ -274,9 +275,10 @@ dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *self, int *titles); * Returns the number of programs within the current title. * * \param self Pointer to dvdnav_t associated with this operation. - * \param programs Pointer to int to receive number of programs. + * \param titles int to select title. + * \param parts Pointer to int to receive number of parts. */ -dvdnav_status_t dvdnav_get_number_of_programs(dvdnav_t *self, int *programs); +dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *self, int title, int *parts); /** * If we are currently in a still-frame this function skips it (or attempts to). @@ -532,31 +534,31 @@ dvdnav_status_t dvdnav_get_highlight_area(pci_t* nav_pci , int32_t button, int32 * * \param self Pointer to dvdnav_t associated with this operation. */ -dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self); +dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self, pci_t *pci); /** * Move button highlight around as suggested by function name (e.g. with arrow keys). * * \param self Pointer to dvdnav_t associated with this operation. */ -dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self); +dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self, pci_t *pci); /** * Move button highlight around as suggested by function name (e.g. with arrow keys). * * \param self Pointer to dvdnav_t associated with this operation. */ -dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self); +dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self, pci_t *pci); /** * Move button highlight around as suggested by function name (e.g. with arrow keys). * * \param self Pointer to dvdnav_t associated with this operation. */ -dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self); +dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self, pci_t *pci); /** * Activate (press) the currently highlighted button. * \param self Pointer to dvdnav_t associated with this operation. */ -dvdnav_status_t dvdnav_button_activate(dvdnav_t *self); +dvdnav_status_t dvdnav_button_activate(dvdnav_t *self, pci_t *pci); /** * Highlight a specific button. @@ -564,7 +566,7 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *self); * \param self Pointer to dvdnav_t associated with this operation. * \param button 1..39 -- Button number to activate. */ -dvdnav_status_t dvdnav_button_select(dvdnav_t *self, int button); +dvdnav_status_t dvdnav_button_select(dvdnav_t *self, pci_t *pci, int button); /** * Activate (press) specified button. @@ -572,7 +574,15 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *self, int button); * \param self Pointer to dvdnav_t associated with this operation. * \param button 1..39 -- Button number to activate. */ -dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, int button); +dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, pci_t *pci, int button); + +/** + * Activate (press) a button and execute specified command. + * + * \param self Pointer to dvdnav_t associated with this operation. + * \param cmd DVD Command to execute. + */ +dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *self, int32_t button, vm_cmd_t *cmd); /** * Select button at specified (image) co-ordinates. @@ -581,7 +591,7 @@ dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, int button); * \param x X co-ordinate in image. * \param y Y xo-ordinate in image. */ -dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, int x, int y); +dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, pci_t *pci, int x, int y); /** * Activate (press) button at specified co-ordinates. @@ -590,7 +600,7 @@ dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, int x, int y); * \param x X co-ordinate in image. * \param y Y xo-ordinate in image. */ -dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, int x, int y); +dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, pci_t *pci, int x, int y); /** * @} diff --git a/src/input/libdvdnav/highlight.c b/src/input/libdvdnav/highlight.c index 8beacd2ca..d0cfac713 100644 --- a/src/input/libdvdnav/highlight.c +++ b/src/input/libdvdnav/highlight.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: highlight.c,v 1.5 2002/09/04 11:07:47 mroi Exp $ + * $Id: highlight.c,v 1.6 2002/09/20 12:53:53 mroi Exp $ * */ @@ -217,7 +217,7 @@ dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *this, int* button) { return S_OK; } -btni_t *__get_current_button(dvdnav_t *this) { +btni_t *__get_current_button(dvdnav_t *this, pci_t *pci) { int button = 0; if(dvdnav_get_current_highlight(this, &button) != S_OK) { @@ -228,16 +228,16 @@ btni_t *__get_current_button(dvdnav_t *this) { nav_print_PCI(&(this->pci)); #endif - return &(this->pci.hli.btnit[button-1]); + return &(pci->hli.btnit[button-1]); } -dvdnav_status_t dvdnav_button_auto_action(dvdnav_t *this) { +dvdnav_status_t dvdnav_button_auto_action(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!this) return S_ERR; - if((button_ptr = __get_current_button(this)) == NULL) { + if((button_ptr = __get_current_button(this, pci)) == NULL) { return S_ERR; } if (button_ptr->auto_action_mode == 1) { @@ -247,74 +247,74 @@ dvdnav_status_t dvdnav_button_auto_action(dvdnav_t *this) { } -dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this) { +dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!this) return S_ERR; - if((button_ptr = __get_current_button(this)) == NULL) { + if((button_ptr = __get_current_button(this, pci)) == NULL) { return S_ERR; } - dvdnav_button_select(this, button_ptr->up); - if (dvdnav_button_auto_action(this) ) { - dvdnav_button_activate(this); + dvdnav_button_select(this, pci, button_ptr->up); + if (dvdnav_button_auto_action(this, pci) ) { + dvdnav_button_activate(this, pci); } return S_OK; } -dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this) { +dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!this) return S_ERR; - if((button_ptr = __get_current_button(this)) == NULL) { + if((button_ptr = __get_current_button(this, pci)) == NULL) { return S_ERR; } - dvdnav_button_select(this, button_ptr->down); - if (dvdnav_button_auto_action(this) ) { - dvdnav_button_activate(this); + dvdnav_button_select(this, pci, button_ptr->down); + if (dvdnav_button_auto_action(this, pci) ) { + dvdnav_button_activate(this, pci); } return S_OK; } -dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this) { +dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!this) return S_ERR; - if((button_ptr = __get_current_button(this)) == NULL) { + if((button_ptr = __get_current_button(this, pci)) == NULL) { printerr("Error fetching information on current button."); return S_ERR; } - dvdnav_button_select(this, button_ptr->right); - if (dvdnav_button_auto_action(this) ) { - dvdnav_button_activate(this); + dvdnav_button_select(this, pci, button_ptr->right); + if (dvdnav_button_auto_action(this, pci) ) { + dvdnav_button_activate(this, pci); } return S_OK; } -dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this) { +dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!this) return S_ERR; - if((button_ptr = __get_current_button(this)) == NULL) { + if((button_ptr = __get_current_button(this, pci)) == NULL) { return S_ERR; } - dvdnav_button_select(this, button_ptr->left); - if (dvdnav_button_auto_action(this) ) { - dvdnav_button_activate(this); + dvdnav_button_select(this, pci, button_ptr->left); + if (dvdnav_button_auto_action(this, pci) ) { + dvdnav_button_activate(this, pci); } return S_OK; @@ -357,7 +357,7 @@ dvdnav_status_t dvdnav_get_highlight_area(pci_t* nav_pci , int32_t button, int32 return S_OK; } -dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) { +dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) { int button; btni_t *button_ptr = NULL; @@ -374,7 +374,7 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) { /* FIXME: dvdnav_button_select should really return a * special case for explicit NO-BUTTONS. */ - if(dvdnav_button_select(this, button) != S_OK) { + if(dvdnav_button_select(this, pci, button) != S_OK) { /* Special code to handle still menus with no buttons. * the navigation is expected to report to the appicatino that a STILL is * underway. In turn, the application is supposed to report to the user @@ -395,7 +395,7 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) { return S_ERR; } /* FIXME: The button command should really be passed in the API instead. */ - button_ptr = __get_current_button(this); + button_ptr = __get_current_button(this, pci); /* Finally, make the VM execute the appropriate code and * scedule a jump */ #ifdef BUTTON_TESTING @@ -410,7 +410,32 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) { return S_OK; } -dvdnav_status_t dvdnav_button_select(dvdnav_t *this, int button) { +dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *this, int32_t button, vm_cmd_t *cmd) +{ + if(!this || !this->vm) + return S_ERR; + pthread_mutex_lock(&this->vm_lock); + /* make the VM execute the appropriate code and + * schedule a jump */ +#ifdef BUTTON_TESTING + fprintf(MSG_OUT, "libdvdnav:dvdnav_button_activate_cmd: Evaluating Button Activation commands.\n"); +#endif + if(button > 0) { + printerrf("Select button number %i\n ", + button); + this->vm->state.HL_BTNN_REG = (button << 10); + if( (vm_eval_cmd(this->vm, cmd)) == 1) { + /* Command caused a jump */ + this->vm->hop_channel++; + } + } + /* Always remove still, because some still menus have no buttons. */ + this->position_current.still = 0; + pthread_mutex_unlock(&this->vm_lock); + return S_OK; +} + +dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int button) { if(!this) { printerrf("Unable to select button number %i as this state bad", @@ -424,7 +449,7 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *this, int button) { /* Set the highlight SPRM if the passed button was valid*/ /* FIXME: this->pci should be provided by the application. */ - if((button <= 0) || (button > this->pci.hli.hl_gi.btn_ns)) { + if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) { printerrf("Unable to select button number %i as it doesn't exist", button); return S_ERR; @@ -438,18 +463,18 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *this, int button) { return S_OK; } -dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, +dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, pci_t *pci, int button) { /* A trivial function */ - if(dvdnav_button_select(this, button) != S_ERR) { - return dvdnav_button_activate(this); + if(dvdnav_button_select(this, pci, button) != S_ERR) { + return dvdnav_button_activate(this, pci); } /* Should never get here without an error */ return S_ERR; } -dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, int x, int y) { +dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, pci_t *pci, int x, int y) { int button, cur_button; uint32_t best,dist; int mx,my,dx,dy,d; @@ -467,7 +492,7 @@ dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, int x, int y) { dist = 0x08000000; /* >> than (720*720)+(567*567); */ /* Loop through each button */ - for(button=1; button <= this->pci.hli.hl_gi.btn_ns; button++) { + for(button=1; button <= pci->hli.hl_gi.btn_ns; button++) { btni_t *button_ptr = NULL; button_ptr = &(this->pci.hli.btnit[button-1]); if((x >= button_ptr->x_start) && (x <= button_ptr->x_end) && @@ -489,17 +514,17 @@ dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, int x, int y) { /* As an efficiency measure, only re-select the button * if it is different to the previously selected one. */ if(best != cur_button) { - dvdnav_button_select(this, best); + dvdnav_button_select(this, pci, best); } } return S_OK; } -dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, int x, int y) { +dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, pci_t *pci, int x, int y) { /* A trivial function */ - if(dvdnav_mouse_select(this, x,y) != S_ERR) { - return dvdnav_button_activate(this); + if(dvdnav_mouse_select(this, pci, x,y) != S_ERR) { + return dvdnav_button_activate(this, pci); } /* Should never get here without an error */ diff --git a/src/input/libdvdnav/navigation.c b/src/input/libdvdnav/navigation.c index 748cb7f52..a3a26dd7d 100644 --- a/src/input/libdvdnav/navigation.c +++ b/src/input/libdvdnav/navigation.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: navigation.c,v 1.2 2002/09/04 11:07:47 mroi Exp $ + * $Id: navigation.c,v 1.3 2002/09/20 12:53:53 mroi Exp $ * */ @@ -51,23 +51,34 @@ dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *this, int *titles) { return S_ERR; } + if(!this->started) { + /* Start the VM */ + vm_start(this->vm); + this->started = 1; + } + (*titles) = vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts; return S_OK; } -/* This function should not be used. FIXME: Suggest alternative */ -dvdnav_status_t dvdnav_get_number_of_programs(dvdnav_t *this, int *programs) { +dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *this, int title, int *parts) { if(!this) return S_ERR; - if(!programs) { + if(!parts) { printerr("Passed a NULL pointer"); return S_ERR; } - - (*programs) = this->vm->state.pgc->nr_of_programs; - + if(!this->started) { + printerr("Virtual DVD machine not started."); + return S_ERR; + } + if ((title < 1) || (title > vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts) ) { + printerr("Passed a title number out of range"); + return S_ERR; + } + (*parts) = vm_get_vmgi(this->vm)->tt_srpt->title[title-1].nr_of_ptts; return S_OK; } diff --git a/src/input/libdvdnav/remap.c b/src/input/libdvdnav/remap.c new file mode 100644 index 000000000..ca30287c6 --- /dev/null +++ b/src/input/libdvdnav/remap.c @@ -0,0 +1,225 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/param.h> +#include <sys/fcntl.h> +#include <assert.h> +#include "remap.h" + +struct block_s { + int domain; + int title; + int program; + unsigned long start_block; + unsigned long end_block; +}; + +struct remap_s { + char *title; + int maxblocks; + int nblocks; + int debug; + struct block_s *blocks; +}; + +remap_t* remap_new( char *title) { + remap_t *map = malloc( sizeof(remap_t)); + map->title = strdup(title); + map->maxblocks = 0; + map->nblocks = 0; + map->blocks = NULL; + map->debug = 0; + return map; +} + +static int compare_block( block_t *a, block_t *b) { + /* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */ + if (a->domain < b->domain) { + return -1; + } else if (a->domain > b->domain) { + return 1; + } + + if (a->title < b->title) { + return -1; + } else if (a->title > b->title) { + return 1; + } + + if (a->program < b->program) { + return -1; + } else if (a->program > b->program) { + return 1; + } + + if (a->end_block < b->start_block) { + return -1; + } else if (a->start_block > b->end_block) { + /* + * if a->start_block == b->end_block then the two regions + * aren't strictly overlapping, but they should be merged + * anyway since there are zero blocks between them + */ + return 1; + } + + return 0; +} + +static block_t *findblock( remap_t *map, block_t *key) { + int lb = 0; + int ub = map->nblocks - 1; + int mid; + int res; + + while (lb <= ub) { + mid = lb + (ub - lb)/2; + res = compare_block( key, &map->blocks[mid]); + if (res < 0) { + ub = mid-1; + } else if (res > 0) { + lb = mid+1; + } else { + return &map->blocks[mid]; + } + } + return NULL; +} + +static void mergeblock( block_t *b, block_t tmp) { + if (tmp.start_block < b->start_block) b->start_block = tmp.start_block; + if (tmp.end_block > b->end_block) b->end_block = tmp.end_block; +} + +static void remap_add_node( remap_t *map, block_t block) { + block_t *b; + int n; + b = findblock( map, &block); + if (b) { + /* overlaps an existing block */ + mergeblock( b, block); + } else { + /* new block */ + if (map->nblocks >= map->maxblocks) { + map->maxblocks += 20; + map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks); + } + n = map->nblocks++; + while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) { + map->blocks[ n] = map->blocks[ n-1]; + n--; + } + map->blocks[ n] = block; + } +} + +int parseblock( + char *buf, int *dom, int *tt, int *pg, + unsigned long *start, unsigned long *end) +{ + long tmp; + char *tok; + char *epos; + char *marker[]={"domain", "title", "program", "start", "end"}; + int st = 0; + tok = strtok( buf, " "); + while (st < 5) { + if (strcmp(tok, marker[st])) return -st-1000; + tok = strtok( NULL, " "); + if (!tok) return -st-2000; + tmp = strtol( tok, &epos, 0); + if (*epos != 0 && *epos != ',') return -st-3000; + switch (st) { + case 0: + *dom = (int)tmp; + break; + case 1: + *tt = (int)tmp; + break; + case 2: + *pg = (int)tmp; + break; + case 3: + *start = tmp; + break; + case 4: + *end = tmp; + break; + } + st++; + tok = strtok( NULL, " "); + } + return st; +} + +remap_t* remap_loadmap( char *title) { + char buf[160]; + char fname[MAXPATHLEN]; + char *home; + int res; + FILE *fp; + block_t tmp; + remap_t *map; + + /* Build the map filename */ + home = getenv("HOME"); assert(home); + strncpy(fname, home, sizeof(fname)); + strncat(fname, "/.xine/", sizeof(fname)); + strncat(fname, title, sizeof(fname)); + strncat(fname, ".map", sizeof(fname)); + + printf("Loading %s.\n", fname); + /* Open the map file */ + fp = fopen( fname, "r"); + if (!fp) { + printf("Unable to find map file '%s'\n", fname); + return NULL; + } + + /* Load the map file */ + map = remap_new( title); + while (fgets( buf, sizeof(buf), fp) != NULL) { + if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue; + if (strncasecmp( buf, "debug", 5) == 0) { + map->debug = 1; + } else { + res = parseblock( buf, + &tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block); + if (res != 5) { + printf("Ignoring map line (%d): %s\n", res, buf); + continue; + } + remap_add_node( map, tmp); + } + } + + if (map->nblocks == 0 && map->debug == 0) return NULL; + return map; +} + +unsigned long remap_block( + remap_t *map, int domain, int title, int program, + unsigned long cblock, unsigned long offset) +{ + block_t key; + block_t *b; + + if (map->debug) { + printf("%s: domain %d, title %d, program %d, start %lx, next %lx\n", + map->title, domain, title, program, cblock, cblock+offset); + } + + key.domain = domain; + key.title = title; + key.program = program; + key.start_block = key.end_block = cblock + offset; + b = findblock( map, &key); + + if (b) { + if (map->debug) { + printf("Redirected to %lx\n", b->end_block); + } + return b->end_block - cblock; + } + return offset; +} diff --git a/src/input/libdvdnav/remap.h b/src/input/libdvdnav/remap.h new file mode 100644 index 000000000..841a24a51 --- /dev/null +++ b/src/input/libdvdnav/remap.h @@ -0,0 +1,13 @@ +#ifndef __REMAP__H +#define __REMAP__H +typedef struct block_s block_t; + +typedef struct remap_s remap_t; + +remap_t* remap_loadmap( char *title); + +unsigned long remap_block( + remap_t *map, int domain, int title, int program, + unsigned long cblock, unsigned long offset); + +#endif diff --git a/src/input/libdvdnav/settings.c b/src/input/libdvdnav/settings.c index a9a5df45e..c74eda500 100644 --- a/src/input/libdvdnav/settings.c +++ b/src/input/libdvdnav/settings.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: settings.c,v 1.1 2002/08/08 17:49:21 richwareham Exp $ + * $Id: settings.c,v 1.2 2002/09/20 12:53:53 mroi Exp $ * */ @@ -33,11 +33,13 @@ /* Characteristics/setting API calls */ dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *this, int *region) { - if(!this) - return S_ERR; + if(!this) { + printerr("Passed a NULL this pointer"); + return S_ERR; + } if(!region) { - printerr("Passed a NULL pointer"); + printerr("Passed a NULL region pointer"); return S_ERR; } @@ -75,11 +77,13 @@ dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *this, int use_readahead) { } dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *this, int* flag) { - if(!this) - return S_ERR; + if(!this) { + printerr("Passed a NULL this pointer"); + return S_ERR; + } if(!flag) { - printerr("Passed a NULL pointer"); + printerr("Passed a NULL flag pointer"); return S_ERR; } @@ -88,9 +92,16 @@ dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *this, int* flag) { } static dvdnav_status_t set_language_register(dvdnav_t *this, char *code, int reg) { - if(!this) + if(!this ) { + printerr("Passed a NULL this pointer"); return S_ERR; + } + if(!code) { + printerr("Passed a NULL code pointer"); + return S_ERR; + } + if(!code[0] || !code[1]) { printerr("Passed illegal language code"); return S_ERR; diff --git a/src/input/libdvdnav/vm.c b/src/input/libdvdnav/vm.c index 10b9f9f32..2a21a8499 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.5 2002/09/04 11:07:47 mroi Exp $ + * $Id: vm.c,v 1.6 2002/09/20 12:53:53 mroi Exp $ * */ @@ -33,6 +33,9 @@ #include <unistd.h> #include <inttypes.h> #include <assert.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include "ifo_types.h" #include "ifo_read.h" @@ -173,6 +176,63 @@ dvd_reader_t *vm_get_dvd_reader(vm_t *vm) { return vm->dvd; } +void dvd_read_name( vm_t *this, char *devname) { + int fd, i; + off64_t off; + uint8_t data[DVD_VIDEO_LB_LEN]; + + /* Read DVD name */ + fd=open(devname, O_RDONLY); + if (fd > 0) { + off = lseek64( fd, 32 * (int64_t) DVD_VIDEO_LB_LEN, SEEK_SET ); + if( off == ( 32 * (int64_t) DVD_VIDEO_LB_LEN ) ) { + off = read( fd, data, DVD_VIDEO_LB_LEN ); + close(fd); + if (off == ( (int64_t) DVD_VIDEO_LB_LEN )) { + fprintf( stderr, "VM DVD Title: "); + for(i=25; i < 73; i++ ) { + if((data[i] == 0)) break; + if((data[i] > 32) && (data[i] < 127)) { + fprintf(stderr, "%c", data[i]); + } else { + fprintf(stderr, " "); + } + } + strncpy(&this->dvd_name[0], &data[25], 48); + /* fprintf(stderr, "TITLE:%s\n",&this->dvd_name[0]); */ + this->dvd_name[48]=0; + this->dvd_name_length=strlen(&this->dvd_name[0]); + fprintf( stderr, "\nVM DVD Serial Number: "); + for(i=73; i < 89; i++ ) { + if((data[i] == 0)) break; + if((data[i] > 32) && (data[i] < 127)) { + fprintf(stderr, "%c", data[i]); + } else { + fprintf(stderr, " "); + } + } + fprintf( stderr, "\nVM DVD Title (Alternative): "); + for(i=89; i < 128; i++ ) { + if((data[i] == 0)) break; + if((data[i] > 32) && (data[i] < 127)) { + fprintf(stderr, "%c", data[i]); + } else { + fprintf(stderr, " "); + } + } + fprintf( stderr, "\n"); + } else { + fprintf( stderr, "libdvdread: Can't read name block. Probably not a DVD-ROM device.\n"); + } + } else { + fprintf( stderr, "libdvdread: Can't seek to block %u\n", 32 ); + } + close(fd); + } else { + fprintf(stderr,"NAME OPEN FAILED\n"); + } +} + int vm_reset(vm_t *vm, char *dvdroot) /* , register_t regs) */ { /* Setup State */ memset((vm->state).registers.SPRM, 0, sizeof(uint16_t)*24); @@ -222,6 +282,8 @@ int vm_reset(vm_t *vm, char *dvdroot) /* , register_t regs) */ { fprintf(MSG_OUT, "libdvdnav: vm: faild to open/read the DVD\n"); return -1; } + dvd_read_name(vm, dvdroot); + vm->map = remap_loadmap( vm->dvd_name); vm->vmgi = ifoOpenVMGI(vm->dvd); if(!vm->vmgi) { @@ -1926,6 +1988,9 @@ static pgcit_t* get_PGCIT(vm_t *vm) { /* * $Log: vm.c,v $ + * Revision 1.6 2002/09/20 12:53:53 mroi + * sync to latest libdvdnav cvs version + * * Revision 1.5 2002/09/04 11:07:47 mroi * sync to libdvdnav cvs * diff --git a/src/input/libdvdnav/vm.h b/src/input/libdvdnav/vm.h index 99da87a73..e4c6f1863 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.2 2002/09/04 11:07:47 mroi Exp $ + * $Id: vm.h,v 1.3 2002/09/20 12:53:53 mroi Exp $ * */ @@ -27,6 +27,7 @@ #define VM_H_INCLUDED #include "decoder.h" +#include "remap.h" #include <dvd_types.h> /* DOMAIN enum */ @@ -87,6 +88,9 @@ typedef struct { dvd_state_t state; int badness_counter; int32_t hop_channel; + char dvd_name[50]; + int dvd_name_length; + remap_t *map; } vm_t; |