# HG changeset patch # User jcdutton # Date 1019512888 0 # Node ID 3c1df0cb3aee1d629c4e03f9c07fc5fd046b06fc # Parent d2d73f2ad8d35c8ca2d002745194429b3e9e0e8b Start of rewrite of libdvdnav. Still need to re-implement seeking. diff -r d2d73f2ad8d3 -r 3c1df0cb3aee dvd_types.h --- a/dvd_types.h Mon Apr 22 20:57:15 2002 +0000 +++ b/dvd_types.h Mon Apr 22 22:01:28 2002 +0000 @@ -279,5 +279,13 @@ int more_to_come; } DVDVideoAttributes_t; +typedef struct { + uint32_t palette; /* The CLUT entries for the highlight palette + (4-bits per entry -> 4 entries) */ + uint16_t sx,sy,ex,ey; /* The start/end x,y positions */ + uint32_t pts; /* Highlight PTS to match with SPU */ + uint32_t buttonN; /* Button number for the SPU decoder. */ +} dvdnav_highlight_area_t; + #endif /* DVD_H_INCLUDED */ diff -r d2d73f2ad8d3 -r 3c1df0cb3aee dvdnav.c --- a/dvdnav.c Mon Apr 22 20:57:15 2002 +0000 +++ b/dvdnav.c Mon Apr 22 22:01:28 2002 +0000 @@ -35,7 +35,6 @@ #include #include - /* * NOTE: * All NLCK_*() function are not mutex locked, this made them reusable in @@ -44,13 +43,13 @@ */ /* Current domain (backend to dvdnav_is_domain_() funcs) */ -static int8_t NLCK_dvdnav_is_domain(dvdnav_t *self, domain_t domain) { +static int8_t NLCK_dvdnav_is_domain(dvdnav_t *this, domain_t domain) { dvd_state_t *state; - if((!self) || (!self->started) || (!self->vm)) + if((!this) || (!this->started) || (!this->vm)) return -1; - state = &(self->vm->state); + state = &(this->vm->state); if(!state) return -1; @@ -58,33 +57,33 @@ return (state->domain == domain) ? 1 : 0; } -static int8_t _dvdnav_is_domain(dvdnav_t *self, domain_t domain) { +static int8_t _dvdnav_is_domain(dvdnav_t *this, domain_t domain) { int8_t retval; - pthread_mutex_lock(&self->vm_lock); - retval = NLCK_dvdnav_is_domain(self, domain); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); + retval = NLCK_dvdnav_is_domain(this, domain); + pthread_mutex_unlock(&this->vm_lock); return retval; } -static uint8_t NLCK_dvdnav_get_video_aspect(dvdnav_t *self) { +static uint8_t NLCK_dvdnav_get_video_aspect(dvdnav_t *this) { dvd_state_t *state; ifo_handle_t *vtsi, *vmgi; uint8_t aspect = 0; - if(!self) + if(!this) return aspect; - state = &(self->vm->state); - vtsi = self->vm->vtsi; - vmgi = self->vm->vmgi; + state = &(this->vm->state); + vtsi = this->vm->vtsi; + vmgi = this->vm->vmgi; - if(NLCK_dvdnav_is_domain(self, VTS_DOMAIN)) { + if(NLCK_dvdnav_is_domain(this, VTS_DOMAIN)) { aspect = vtsi->vtsi_mat->vts_video_attr.display_aspect_ratio; - } else if(NLCK_dvdnav_is_domain(self, VTSM_DOMAIN)) { + } else if(NLCK_dvdnav_is_domain(this, VTSM_DOMAIN)) { aspect = vtsi->vtsi_mat->vtsm_video_attr.display_aspect_ratio; - } else if(NLCK_dvdnav_is_domain(self, VMGM_DOMAIN)) { + } else if(NLCK_dvdnav_is_domain(this, VMGM_DOMAIN)) { aspect = vmgi->vmgi_mat->vmgm_video_attr.display_aspect_ratio; } @@ -92,66 +91,66 @@ } #if 0 /* hide it, avoid c compiler warning */ -static video_attr_t *NLCK_dvdnav_get_video_attr(dvdnav_t *self) { +static video_attr_t *NLCK_dvdnav_get_video_attr(dvdnav_t *this) { video_attr_t *attr = NULL; ifo_handle_t *vtsi, *vmgi; - vtsi = self->vm->vtsi; - vmgi = self->vm->vmgi; + vtsi = this->vm->vtsi; + vmgi = this->vm->vmgi; - if(NLCK_dvdnav_is_domain(self, VTS_DOMAIN)) + if(NLCK_dvdnav_is_domain(this, VTS_DOMAIN)) attr = &(vtsi->vtsi_mat->vts_video_attr); - else if(NLCK_dvdnav_is_domain(self, VTSM_DOMAIN)) + else if(NLCK_dvdnav_is_domain(this, VTSM_DOMAIN)) attr = &(vtsi->vtsi_mat->vtsm_video_attr); - else if(NLCK_dvdnav_is_domain(self, VMGM_DOMAIN) || NLCK_dvdnav_is_domain(self, FP_DOMAIN)) + else if(NLCK_dvdnav_is_domain(this, VMGM_DOMAIN) || NLCK_dvdnav_is_domain(this, FP_DOMAIN)) attr = &(vmgi->vmgi_mat->vmgm_video_attr); return attr; } #endif -static audio_attr_t *NLCK_dvdnav_get_audio_attr(dvdnav_t *self, int stream_num) { +static audio_attr_t *NLCK_dvdnav_get_audio_attr(dvdnav_t *this, int stream_num) { audio_attr_t *attr = NULL; ifo_handle_t *vtsi, *vmgi; - vtsi = self->vm->vtsi; - vmgi = self->vm->vmgi; + vtsi = this->vm->vtsi; + vmgi = this->vm->vmgi; - if(NLCK_dvdnav_is_domain(self, VTS_DOMAIN)) + if(NLCK_dvdnav_is_domain(this, VTS_DOMAIN)) attr = &(vtsi->vtsi_mat->vts_audio_attr[stream_num]); - else if(NLCK_dvdnav_is_domain(self, VTSM_DOMAIN)) + else if(NLCK_dvdnav_is_domain(this, VTSM_DOMAIN)) attr = &(vtsi->vtsi_mat->vtsm_audio_attr); - else if(NLCK_dvdnav_is_domain(self, VMGM_DOMAIN) || NLCK_dvdnav_is_domain(self, FP_DOMAIN)) + else if(NLCK_dvdnav_is_domain(this, VMGM_DOMAIN) || NLCK_dvdnav_is_domain(this, FP_DOMAIN)) attr = &(vmgi->vmgi_mat->vmgm_audio_attr); return attr; } -static subp_attr_t *NLCK_dvdnav_get_subp_attr(dvdnav_t *self, int stream_num) { +static subp_attr_t *NLCK_dvdnav_get_subp_attr(dvdnav_t *this, int stream_num) { subp_attr_t *attr = NULL; ifo_handle_t *vtsi, *vmgi; - vtsi = self->vm->vtsi; - vmgi = self->vm->vmgi; + vtsi = this->vm->vtsi; + vmgi = this->vm->vmgi; - if(NLCK_dvdnav_is_domain(self, VTS_DOMAIN)) + if(NLCK_dvdnav_is_domain(this, VTS_DOMAIN)) attr = &(vtsi->vtsi_mat->vts_subp_attr[stream_num]); - else if(NLCK_dvdnav_is_domain(self, VTSM_DOMAIN)) + else if(NLCK_dvdnav_is_domain(this, VTSM_DOMAIN)) attr = &(vtsi->vtsi_mat->vtsm_subp_attr); - else if(NLCK_dvdnav_is_domain(self, VMGM_DOMAIN) || NLCK_dvdnav_is_domain(self, FP_DOMAIN)) + else if(NLCK_dvdnav_is_domain(this, VMGM_DOMAIN) || NLCK_dvdnav_is_domain(this, FP_DOMAIN)) attr = &(vmgi->vmgi_mat->vmgm_subp_attr); return attr; } -static int8_t NCLK_dvdnav_get_audio_logical_stream(dvdnav_t *self, uint8_t audio_num) { +static int8_t NCLK_dvdnav_get_audio_logical_stream(dvdnav_t *this, uint8_t audio_num) { dvd_state_t *state; int8_t logical = -1; - if(!NLCK_dvdnav_is_domain(self, VTS_DOMAIN)) + if(!NLCK_dvdnav_is_domain(this, VTS_DOMAIN)) audio_num = 0; - state = &(self->vm->state); + state = &(this->vm->state); if(audio_num < 8) { if(state->pgc->audio_control[audio_num] & (1 << 15)) { @@ -162,17 +161,17 @@ return logical; } -static int8_t NCLK_dvdnav_get_spu_logical_stream(dvdnav_t *self, uint8_t subp_num) { +static int8_t NCLK_dvdnav_get_spu_logical_stream(dvdnav_t *this, uint8_t subp_num) { dvd_state_t *state; uint8_t aspect; int8_t logical = -1; - if(!NLCK_dvdnav_is_domain(self, VTS_DOMAIN)) + if(!NLCK_dvdnav_is_domain(this, VTS_DOMAIN)) subp_num = 0; - aspect = NLCK_dvdnav_get_video_aspect(self); + aspect = NLCK_dvdnav_get_video_aspect(this); - state = &(self->vm->state); + state = &(this->vm->state); if(logical < 32) { @@ -191,202 +190,198 @@ return logical; } -static int8_t NLCK_dvdnav_get_active_spu_stream(dvdnav_t *self) { +static int8_t NLCK_dvdnav_get_active_spu_stream(dvdnav_t *this) { dvd_state_t *state; int8_t subp_num; int stream_num; - state = &(self->vm->state); + state = &(this->vm->state); subp_num = state->SPST_REG & ~0x40; - stream_num = NCLK_dvdnav_get_spu_logical_stream(self, subp_num); + stream_num = NCLK_dvdnav_get_spu_logical_stream(this, subp_num); if(stream_num == -1) for(subp_num = 0; subp_num < 32; subp_num++) if(state->pgc->subp_control[subp_num] & (1 << 31)) { - stream_num = NCLK_dvdnav_get_spu_logical_stream(self, subp_num); + stream_num = NCLK_dvdnav_get_spu_logical_stream(this, subp_num); break; } return stream_num; } -uint8_t dvdnav_get_video_aspect(dvdnav_t *self) { +uint8_t dvdnav_get_video_aspect(dvdnav_t *this) { uint8_t retval; - pthread_mutex_lock(&self->vm_lock); - retval = NLCK_dvdnav_get_video_aspect(self); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); + retval = NLCK_dvdnav_get_video_aspect(this); + pthread_mutex_unlock(&this->vm_lock); return retval; } -dvdnav_status_t dvdnav_clear(dvdnav_t * self) { - if (!self) { +dvdnav_status_t dvdnav_clear(dvdnav_t * this) { + if (!this) { printerr("Passed a NULL pointer"); return S_ERR; } /* clear everything except path, file, vm, mutex, readahead */ // path - if (self->file) DVDCloseFile(self->file); - self->file = NULL; - self->open_vtsN = -1; - self->open_domain = -1; - self->vobu_start=0; - self->vobu_length=0; - self->blockN=0; - self->next_vobu=0; - self->cell = NULL; - self->jmp_blockN=0; - self->jmp_vobu_start=0; - self->seekto_block=0; + if (this->file) DVDCloseFile(this->file); + this->file = NULL; + this->open_vtsN = -1; + this->open_domain = -1; + this->cell = NULL; + this->jmp_blockN=0; + this->jmp_vobu_start=0; + this->seekto_block=0; - memset(&self->pci,0,sizeof(self->pci)); - memset(&self->dsi,0,sizeof(self->dsi)); + memset(&this->pci,0,sizeof(this->pci)); + memset(&this->dsi,0,sizeof(this->dsi)); /* Set initial values of flags */ - self->expecting_nav_packet = 1; - self->at_soc = 1; - self->still_frame = -1; - self->jumping = 0; - self->seeking = 0; - self->stop = 0; - self->highlight_changed = 0; - self->spu_clut_changed = 0; - self->spu_stream_changed = 0; - self->audio_stream_changed = 0; - self->started=0; - // self->use_read_ahead + this->expecting_nav_packet = 1; + this->at_soc = 1; + this->position_current.still = 0; + this->jumping = 0; + this->seeking = 0; + this->stop = 0; + this->highlight_changed = 0; + this->spu_clut_changed = 0; + this->spu_stream_changed = 0; + this->audio_stream_changed = 0; + this->started=0; + // this->use_read_ahead - self->hli_state=0; + this->hli_state=0; - self->cache_start_sector = -1; - self->cache_block_count = 0; - self->cache_valid = 0; + this->cache_start_sector = -1; + this->cache_block_count = 0; + this->cache_valid = 0; return S_OK; } dvdnav_status_t dvdnav_open(dvdnav_t** dest, char *path) { - dvdnav_t *self; + dvdnav_t *this; /* Create a new structure */ (*dest) = NULL; - self = (dvdnav_t*)malloc(sizeof(dvdnav_t)); - if(!self) + this = (dvdnav_t*)malloc(sizeof(dvdnav_t)); + if(!this) return S_ERR; - memset(self, 0, (sizeof(dvdnav_t) ) ); /* Make sure self structure is clean */ + memset(this, 0, (sizeof(dvdnav_t) ) ); /* Make sure this structure is clean */ - pthread_mutex_init(&self->vm_lock, NULL); + pthread_mutex_init(&this->vm_lock, NULL); /* Initialise the error string */ printerr(""); /* Initialise the VM */ - self->vm = vm_new_vm(); - if(!self->vm) { + this->vm = vm_new_vm(); + if(!this->vm) { printerr("Error initialising the DVD VM"); return S_ERR; } - if(vm_reset(self->vm, path) == -1) { + if(vm_reset(this->vm, path) == -1) { printerr("Error starting the VM / opening the DVD device"); return S_ERR; } /* Set the path. FIXME: Is a deep copy 'right' */ - strncpy(self->path, path, MAX_PATH_LEN); + strncpy(this->path, path, MAX_PATH_LEN); - dvdnav_clear(self); + dvdnav_clear(this); /* Pre-open and close a file so that the CSS-keys are cached. */ - self->file = DVDOpenFile(vm_get_dvd_reader(self->vm), 0, DVD_READ_MENU_VOBS); - if (self->file) DVDCloseFile(self->file); - self->file = NULL; + this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), 0, DVD_READ_MENU_VOBS); + if (this->file) DVDCloseFile(this->file); + this->file = NULL; - if(!self->started) { + if(!this->started) { /* Start the VM */ - vm_start(self->vm); - self->started = 1; + vm_start(this->vm); + this->started = 1; } - (*dest) = self; + (*dest) = this; return S_OK; } -dvdnav_status_t dvdnav_close(dvdnav_t *self) { - if(!self) { +dvdnav_status_t dvdnav_close(dvdnav_t *this) { + if(!this) { printerr("Passed a NULL pointer"); return S_ERR; } fprintf(stderr,"dvdnav:close:called\n"); - if (self->file) { - DVDCloseFile(self->file); + if (this->file) { + DVDCloseFile(this->file); fprintf(stderr,"dvdnav:close:file closing\n"); - self->file = NULL; + this->file = NULL; } /* Free the VM */ - if(self->vm) { - vm_free_vm(self->vm); + if(this->vm) { + vm_free_vm(this->vm); } - if (self->file) { - DVDCloseFile(self->file); + if (this->file) { + DVDCloseFile(this->file); fprintf(stderr,"dvdnav:close2:file closing\n"); - self->file = NULL; + this->file = NULL; } - pthread_mutex_destroy(&self->vm_lock); + pthread_mutex_destroy(&this->vm_lock); /* Finally free the entire structure */ - free(self); + free(this); return S_OK; } -dvdnav_status_t dvdnav_reset(dvdnav_t *self) { +dvdnav_status_t dvdnav_reset(dvdnav_t *this) { dvdnav_status_t result; printf("dvdnav:reset:called\n"); - if(!self) { + if(!this) { printerr("Passed a NULL pointer"); return S_ERR; } printf("getting lock\n"); - pthread_mutex_lock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); printf("reseting vm\n"); - if(vm_reset(self->vm, NULL) == -1) { + if(vm_reset(this->vm, NULL) == -1) { printerr("Error restarting the VM"); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } printf("clearing dvdnav\n"); - result=dvdnav_clear(self); + result=dvdnav_clear(this); printf("starting vm\n"); - if(!self->started) { + if(!this->started) { /* Start the VM */ - vm_start(self->vm); - self->started = 1; + vm_start(this->vm); + this->started = 1; } printf("unlocking\n"); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return result; } -dvdnav_status_t dvdnav_path(dvdnav_t *self, char** path) { - if(!self || !path || !(*path)) { +dvdnav_status_t dvdnav_path(dvdnav_t *this, char** path) { + if(!this || !path || !(*path)) { return S_ERR; } /* FIXME: Is shallow copy 'right'? */ - (*path) = self->path; + (*path) = this->path; return S_OK; } -char* dvdnav_err_to_string(dvdnav_t *self) { - if(!self) { +char* dvdnav_err_to_string(dvdnav_t *this) { + if(!this) { /* Shold this be "passed a NULL pointer?" */ return "Hey! You gave me a NULL pointer you naughty person!"; } - return self->err_str; + return this->err_str; } /** @@ -396,7 +391,7 @@ * Most of the code in here is copied from xine's MPEG demuxer * so any bugs which are found in that should be corrected here also. */ -int dvdnav_check_packet(dvdnav_t *self, uint8_t *p) { +int dvdnav_decode_packet(dvdnav_t *this, uint8_t *p, dsi_t* nav_dsi, pci_t* nav_pci) { int bMpeg1=0; uint32_t nHeaderLen; uint32_t nPacketLen; @@ -459,9 +454,9 @@ */ if(p[0] == 0x00) { #ifdef HAVE_DVDREAD9 - navRead_PCI(&(self->pci), p+1); + navRead_PCI(nav_pci, p+1); #else - navRead_PCI(&(self->pci), p+1, nPacketLen - 1); + navRead_PCI(nav_pci, p+1, nPacketLen - 1); #endif } @@ -475,185 +470,229 @@ p += 6; /* dprint("NAV DSI packet\n"); */ #ifdef HAVE_DVDREAD9 - navRead_DSI(&(self->dsi), p+1); + navRead_DSI(nav_dsi, p+1); #else - navRead_DSI(&(self->dsi), p+1, sizeof(dsi_t)); + navRead_DSI(nav_dsi, p+1, sizeof(dsi_t)); #endif + } + return 1; + } + return 0; +} +/* Some angle suff */ +// dvdnav_get_angle_info(this, ¤t, &num); +// if(num == 1) { + /* This is to switch back to angle one when we + * finish */ +// dvdnav_angle_change(this, 1); +// } +/* DSI is used for most angle stuff. + * PCI is used for only non-seemless angle stuff + */ +int dvdnav_get_vobu(dsi_t* nav_dsi, pci_t* nav_pci, int angle, dvdnav_vobu_t* vobu) { + int num=0, current=0; - self->vobu_start = self->dsi.dsi_gi.nv_pck_lbn; - self->vobu_length = self->dsi.dsi_gi.vobu_ea; - - /** - * If we're not at the end of this cell, we can determine the next - * VOBU to display using the VOBU_SRI information section of the - * DSI. Using this value correctly follows the current angle, - * avoiding the doubled scenes in The Matrix, and makes our life - * really happy. - * - * Otherwise, we set our next address past the end of this cell to - * force the code above to go to the next cell in the program. - */ - if( self->dsi.vobu_sri.next_vobu != SRI_END_OF_CELL ) { - self->next_vobu = self->dsi.dsi_gi.nv_pck_lbn - + ( self->dsi.vobu_sri.next_vobu & 0x7fffffff ); - } else { - self->next_vobu = self->vobu_start + self->vobu_length; - } + vobu->vobu_start = nav_dsi->dsi_gi.nv_pck_lbn; /* Absolute offset from start of disk */ + vobu->vobu_length = nav_dsi->dsi_gi.vobu_ea; /* Relative offset from vobu_start */ + + /** + * If we're not at the end of this cell, we can determine the next + * VOBU to display using the VOBU_SRI information section of the + * DSI. Using this value correctly follows the current angle, + * avoiding the doubled scenes in The Matrix, and makes our life + * really happy. + * + * vobu_next is an offset value, 0x3fffffff = SRI_END_OF_CELL + * DVDs are about 6 Gigs, which is only up to 0x300000 blocks + * Should really assert if bit 31 != 1 + */ + /* Relative offset from vobu_start */ + vobu->vobu_next = ( nav_dsi->vobu_sri.next_vobu & 0x3fffffff ); - dvdnav_get_angle_info(self, ¤t, &num); - if(num == 1) { - /* This is to switch back to angle one when we - * finish */ - dvdnav_angle_change(self, 1); - } - - if(num != 0) { - uint32_t next = self->pci.nsml_agli.nsml_agl_dsta[current-1]; + if(angle != 0) { + /* FIXME: Angles need checking */ + uint32_t next = nav_pci->nsml_agli.nsml_agl_dsta[angle-1]; - if(next != 0) { - int dir = 0; - if(next & 0x80000000) { - dir = -1; - next = next & 0x3fffffff; - } else { - dir = 1; - } + if(next != 0) { + int dir = 0; + if(next & 0x80000000) { + vobu->vobu_next = - (next & 0x3fffffff); + } else { + vobu->vobu_next = + (next & 0x3fffffff); + } - if(next != 0) { - self->next_vobu = self->vobu_start + dir * next; - } - } else if( self->dsi.sml_agli.data[current-1].address != 0 ) { - next = self->dsi.sml_agli.data[current-1].address; - self->vobu_length = self->dsi.sml_pbi.ilvu_ea; + } else if( nav_dsi->sml_agli.data[angle-1].address != 0 ) { + next = nav_dsi->sml_agli.data[angle-1].address; + vobu->vobu_length = nav_dsi->sml_pbi.ilvu_ea; - if((next & 0x80000000) && (next != 0x7fffffff)) { - self->next_vobu = self->dsi.dsi_gi.nv_pck_lbn - (next & 0x7fffffff); - } else { - self->next_vobu = self->dsi.dsi_gi.nv_pck_lbn + next; - } - } + if((next & 0x80000000) && (next != 0x7fffffff)) { + vobu->vobu_next = - (next & 0x3fffffff); + } else { + vobu->vobu_next = + (next & 0x3fffffff); } } - return 1; } - - return 0; + return 1; } -dvdnav_status_t dvdnav_get_next_block(dvdnav_t *self, unsigned char *buf, +dvdnav_status_t dvdnav_get_next_block(dvdnav_t *this, unsigned char *buf, int *event, int *len) { dvd_state_t *state; int result; - if(!self || !event || !len || !buf) { + if(!this || !event || !len || !buf) { printerr("Passed a NULL pointer"); return S_ERR; } - pthread_mutex_lock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); - if(!self->started) { + if(!this->started) { /* Start the VM */ - vm_start(self->vm); - self->started = 1; + vm_start(this->vm); + this->started = 1; } - state = &(self->vm->state); + state = &(this->vm->state); (*event) = DVDNAV_NOP; (*len) = 0; /* Check the STOP flag */ - if(self->stop) { + if(this->stop) { (*event) = DVDNAV_STOP; - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_OK; } - if(self->spu_clut_changed) { + /* Check the STILLFRAME flag */ + //FIXME: Still cell, not still frame + if(this->position_current.still != 0) { + dvdnav_still_event_t still_event; + + still_event.length = this->position_current.still; + + (*event) = DVDNAV_STILL_FRAME; + (*len) = sizeof(dvdnav_still_event_t); + memcpy(buf, &(still_event), sizeof(dvdnav_still_event_t)); + + pthread_mutex_unlock(&this->vm_lock); + return S_OK; + } + + vm_position_get(this->vm,&this->position_next); + /********** + fprintf(stderr, "POS-NEXT "); + vm_position_print(this->vm, &this->position_next); + fprintf(stderr, "POS-CUR "); + vm_position_print(this->vm, &this->position_current); + **********/ + + if(this->position_current.hop_channel != this->position_next.hop_channel) { + this->position_current.hop_channel = this->position_next.hop_channel; + (*event) = DVDNAV_HOP_CHANNEL; + (*len) = 0; + pthread_mutex_unlock(&this->vm_lock); + return S_OK; + } + + + + if(this->spu_clut_changed) { (*event) = DVDNAV_SPU_CLUT_CHANGE; fprintf(stderr,"libdvdnav:SPU_CLUT_CHANGE\n"); (*len) = sizeof(dvdnav_still_event_t); memcpy(buf, &(state->pgc->palette), 16 * sizeof(uint32_t)); - self->spu_clut_changed = 0; + this->spu_clut_changed = 0; fprintf(stderr,"libdvdnav:SPU_CLUT_CHANGE returning S_OK\n"); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_OK; } - if(self->spu_stream_changed) { + if(this->position_current.spu_channel != this->position_next.spu_channel) { dvdnav_stream_change_event_t stream_change; (*event) = DVDNAV_SPU_STREAM_CHANGE; fprintf(stderr,"libdvdnav:SPU_STREAM_CHANGE\n"); (*len) = sizeof(dvdnav_stream_change_event_t); - stream_change.physical = vm_get_subp_active_stream( self->vm ); + stream_change.physical = vm_get_subp_active_stream( this->vm ); memcpy(buf, &(stream_change), sizeof( dvdnav_stream_change_event_t)); - self->spu_stream_changed = 0; + //this->spu_stream_changed = 0; + this->position_current.spu_channel = this->position_next.spu_channel; fprintf(stderr,"libdvdnav:SPU_STREAM_CHANGE stream_id=%d returning S_OK\n",stream_change.physical); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_OK; } - if(self->audio_stream_changed) { + //if(this->audio_stream_changed) { + if(this->position_current.audio_channel != this->position_next.audio_channel) { dvdnav_stream_change_event_t stream_change; (*event) = DVDNAV_AUDIO_STREAM_CHANGE; fprintf(stderr,"libdvdnav:AUDIO_STREAM_CHANGE\n"); (*len) = sizeof(dvdnav_stream_change_event_t); - stream_change.physical= vm_get_audio_active_stream( self->vm ); + stream_change.physical= vm_get_audio_active_stream( this->vm ); memcpy(buf, &(stream_change), sizeof( dvdnav_stream_change_event_t)); - self->audio_stream_changed = 0; + //this->audio_stream_changed = 0; + this->position_current.audio_channel = this->position_next.audio_channel; fprintf(stderr,"libdvdnav:AUDIO_STREAM_CHANGE stream_id=%d returning S_OK\n",stream_change.physical); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_OK; } /* Check the HIGHLIGHT flag */ - if(self->highlight_changed) { + /* FIXME: Use BUTTON instead of HIGHLIGHT. */ + //if(this->highlight_changed) { + if(this->position_current.button != this->position_next.button) { + // if (0) { dvdnav_highlight_event_t hevent; + dvdnav_highlight_area_t highlight; + /* Fill in highlight struct with appropriate values */ - if(self->hli_state != 0) { + //if(this->hli_state != 0) { + if (1) { hevent.display = 1; - + dvdnav_get_highlight_area(&this->pci , this->position_next.button, 0, + &highlight); /* Copy current button bounding box. */ - hevent.sx = self->hli_bbox[0]; - hevent.sy = self->hli_bbox[1]; - hevent.ex = self->hli_bbox[2]; - hevent.ey = self->hli_bbox[3]; + hevent.sx = highlight.sx; + hevent.sy = highlight.sy; + hevent.ex = highlight.ex; + hevent.ey = highlight.ey; - hevent.palette = self->hli_clut; - hevent.pts = self->hli_pts; - hevent.buttonN = self->hli_buttonN; + hevent.palette = highlight.palette; + hevent.pts = highlight.pts; + hevent.buttonN = this->position_next.button; } else { hevent.display = 0; } - + // FIXME: Change this to DVDNAV_BUTTON (*event) = DVDNAV_HIGHLIGHT; memcpy(buf, &(hevent), sizeof(hevent)); (*len) = sizeof(hevent); - self->highlight_changed = 0; + this->highlight_changed = 0; + this->position_current.button = this->position_next.button; - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_OK; } - /* Check to see if we need to change the curently opened VOB */ - if((self->open_vtsN != state->vtsN) || - (self->open_domain != state->domain)) { + /* Check to see if we need to change the currently opened VOB */ + if((this->position_current.vts != this->position_next.vts) || + (this->position_current.domain != this->position_next.domain)) { dvd_read_domain_t domain; int vtsN; dvdnav_vts_change_event_t vts_event; - if(self->file) { - dvdnav_read_cache_clear(self); - DVDCloseFile(self->file); - self->file = NULL; + if(this->file) { + dvdnav_read_cache_clear(this); + DVDCloseFile(this->file); + this->file = NULL; } - vts_event.old_vtsN = self->open_vtsN; - vts_event.old_domain = self->open_domain; + vts_event.old_vtsN = this->open_vtsN; + vts_event.old_domain = this->open_domain; /* Use the current DOMAIN to find whether to open menu or title VOBs */ - switch(state->domain) { + switch(this->position_next.domain) { case FP_DOMAIN: case VMGM_DOMAIN: domain = DVD_READ_MENU_VOBS; @@ -661,29 +700,29 @@ break; case VTSM_DOMAIN: domain = DVD_READ_MENU_VOBS; - vtsN = state->vtsN; + vtsN = this->position_next.vts; break; case VTS_DOMAIN: domain = DVD_READ_TITLE_VOBS; - vtsN = state->vtsN; + vtsN = this->position_next.vts; break; default: printerr("Unknown domain when changing VTS."); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } - self->open_domain = state->domain; - self->open_vtsN = state->vtsN; - dvdnav_read_cache_clear(self); - self->file = DVDOpenFile(vm_get_dvd_reader(self->vm), vtsN, domain); - vts_event.new_vtsN = self->open_vtsN; - vts_event.new_domain = self->open_domain; + this->position_current.vts = this->position_next.vts; + this->position_current.domain = this->position_next.domain; + dvdnav_read_cache_clear(this); + this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), vtsN, domain); + vts_event.new_vtsN = this->position_next.vts; + vts_event.new_domain = this->position_next.domain; /* If couldn't open the file for some reason, moan */ - if(self->file == NULL) { + if(this->file == NULL) { printerrf("Error opening vtsN=%i, domain=%i.", vtsN, domain); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } @@ -694,214 +733,143 @@ /* On a VTS change, we want to disable any highlights which * may have been shown (FIXME: is this valid?) */ - self->highlight_changed = 1; - self->spu_clut_changed = 1; - self->spu_stream_changed = 1; - self->audio_stream_changed = 1; - self->hli_state = 0; /* Hide */ - self->expecting_nav_packet = 1; + //FIXME: We should be able to remove this + //this->highlight_changed = 1; + this->spu_clut_changed = 1; + this->position_current.cell = -1; /* Force an update */ + this->position_current.spu_channel = -1; /* Force an update */ + this->position_current.audio_channel = -1; /* Force an update */; + //this->hli_state = 0; /* Hide */ - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); + return S_OK; + } + /* FIXME: Don't really need "cell", we only need vobu_start */ + if( (this->position_current.cell != this->position_next.cell) || + (this->position_current.vobu_start != this->position_next.vobu_start) ) { + this->position_current.cell = this->position_next.cell; + /* vobu_start changes when PGC or PG changes. */ + this->position_current.vobu_start = this->position_next.vobu_start; + /* FIXME: Need to set vobu_start, vobu_next */ + this->vobu.vobu_start = this->position_next.vobu_start; + /* vobu_next is use for mid cell resumes */ + this->vobu.vobu_next = this->position_next.vobu_next; + //this->vobu.vobu_next = 0; + this->vobu.vobu_length = 0; + this->vobu.blockN = this->vobu.vobu_length + 1; + /* Make blockN > vobu_lenght to do expected_nav */ + this->expecting_nav_packet = 1; + (*event) = DVDNAV_CELL_CHANGE; + (*len) = 0; + pthread_mutex_unlock(&this->vm_lock); return S_OK; } - /* Check the STILLFRAME flag */ - if(self->still_frame != -1) { - dvdnav_still_event_t still_event; - - still_event.length = self->still_frame; + + if (this->vobu.blockN > this->vobu.vobu_length) { + /* End of VOBU */ + dvdnav_nav_packet_event_t nav_event; + this->expecting_nav_packet = 1; - (*event) = DVDNAV_STILL_FRAME; - (*len) = sizeof(dvdnav_still_event_t); - memcpy(buf, &(still_event), sizeof(dvdnav_still_event_t)); - - pthread_mutex_unlock(&self->vm_lock); - return S_OK; - } + if(this->vobu.vobu_next == SRI_END_OF_CELL) { + /* End of Cell from NAV DSI info */ + fprintf(stderr, "Still set to %x\n", this->position_next.still); + this->position_current.still = this->position_next.still; - if(self->at_soc) { - dvdnav_cell_change_event_t cell_event; - cell_playback_t *cell = &(state->pgc->cell_playback[state->cellN - 1]); - - cell_event.old_cell = self->cell; - self->vobu_start = cell->first_sector; - self->cell = cell; - cell_event.new_cell = self->cell; - - self->at_soc = 0; + if(this->position_current.still == 0) { + vm_get_next_cell(this->vm); + vm_position_get(this->vm,&this->position_next); + /* FIXME: Need to set vobu_start, vobu_next */ + this->position_current.cell = this->position_next.cell; + this->position_current.vobu_start = this->position_next.vobu_start; + this->vobu.vobu_start = this->position_next.vobu_start; + /* vobu_next is use for mid cell resumes */ + this->vobu.vobu_next = this->position_next.vobu_next; + //this->vobu.vobu_next = 0; + this->vobu.vobu_length = 0; + this->vobu.blockN = this->vobu.vobu_length + 1; + /* Make blockN > vobu_next to do expected_nav */ + this->expecting_nav_packet = 1; + (*event) = DVDNAV_CELL_CHANGE; + (*len) = 0; + pthread_mutex_unlock(&this->vm_lock); + return S_OK; + } else { + dvdnav_still_event_t still_event; + still_event.length = this->position_current.still; + (*event) = DVDNAV_STILL_FRAME; + (*len) = sizeof(dvdnav_still_event_t); + memcpy(buf, &(still_event), sizeof(dvdnav_still_event_t)); + pthread_mutex_unlock(&this->vm_lock); + return S_OK; + } - (*event) = DVDNAV_CELL_CHANGE; - (*len) = sizeof(dvdnav_cell_change_event_t); - memcpy(buf, &(cell_event), sizeof(dvdnav_cell_change_event_t)); + /* Only set still after whole VOBU has been output. */ + //if(this->position_next.still != 0) { +// this->position_current.still = this->position_next.still; + //} - pthread_mutex_unlock(&self->vm_lock); - return S_OK; - } - - if(self->expecting_nav_packet ) { -//|| -// (self->jumping) ) { - dvdnav_nav_packet_event_t nav_event; - + } /* Perform the jump if necessary (this is always a * VOBU boundary). */ - if(self->seeking) { - /* FIXME:Need to handle seeking outside current cell. */ - vobu_admap_t *admap = NULL; - - fprintf(stderr,"Seeking to target %u ...\n", - self->seekto_block); - - /* Search through the VOBU_ADMAP for the nearest VOBU - * to the target block */ - switch(state->domain) { - case FP_DOMAIN: - case VMGM_DOMAIN: - //ifo = vm_get_vmgi(); - //ifoRead_VOBU_ADMAP(ifo); - admap = self->vm->vmgi->menu_vobu_admap; - break; - case VTSM_DOMAIN: - //ifo = vm_get_vtsi(); - //ifoRead_VOBU_ADMAP(ifo); - admap = self->vm->vtsi->menu_vobu_admap; - break; - case VTS_DOMAIN: - //ifo = vm_get_vtsi(); - //ifoRead_TITLE_VOBU_ADMAP(ifo); - admap = self->vm->vtsi->vts_vobu_admap; - break; - default: - fprintf(stderr,"Error: Unknown domain for seeking seek.\n"); - } - - if(admap) { - uint32_t address = 0; - uint32_t vobu_start, next_vobu; - int found = 0; - - /* Search through ADMAP for best sector */ - vobu_start = 0x3fffffff; - - while((!found) && ((address<<2) < admap->last_byte)) { - next_vobu = admap->vobu_start_sectors[address]; - - /* printf("Found block %u\n", next_vobu); */ - - if(vobu_start <= self->seekto_block && - next_vobu > self->seekto_block) { - found = 1; - } else { - vobu_start = next_vobu; - } - - address ++; - } - if(found) { - self->vobu_start = vobu_start; - self->blockN = 0; - self->seeking = 0; - //self->at_soc = 1; - (*event) = DVDNAV_SEEK_DONE; - (*len) = 0; - pthread_mutex_unlock(&self->vm_lock); - return S_OK; - } else { - fprintf(stderr,"Could not locate block\n"); - return -1; - } - } - } - if(self->jumping) { - fprintf(stderr,"doing jumping\n"); - self->vobu_start = self->jmp_vobu_start; - self->blockN = self->jmp_blockN; - self->jumping = 0; - self->at_soc = 1; - } - - result = DVDReadBlocks(self->file, self->vobu_start + self->blockN, 1, buf); + result = DVDReadBlocks(this->file, this->vobu.vobu_start + this->vobu.vobu_next, 1, buf); if(result <= 0) { printerr("Error reading NAV packet."); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } - - if(dvdnav_check_packet(self, buf) == 0) { + /* Decode nav into pci and dsi. */ + /* Then get next VOBU info. */ + if(dvdnav_decode_packet(this, buf, &this->dsi, &this->pci) == 0) { printerr("Expected NAV packet but none found."); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } - - self->blockN++; - self->expecting_nav_packet = 0; + dvdnav_get_vobu(&this->dsi,&this->pci, 0, &this->vobu); + this->vobu.blockN=1; + this->expecting_nav_packet = 0; - dvdnav_pre_cache_blocks(self, self->vobu_start, self->vobu_length+1); + dvdnav_pre_cache_blocks(this, this->vobu.vobu_start+1, this->vobu.vobu_length); /* Successfully got a NAV packet */ - nav_event.pci = &(self->pci); - nav_event.dsi = &(self->dsi); - (*event) = DVDNAV_NAV_PACKET; - /* memcpy(buf, &(nav_event), sizeof(dvdnav_nav_packet_event_t)); - (*len) = sizeof(dvdnav_nav_packet_event_t); */ (*len) = 2048; - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_OK; } /* If we've got here, it must just be a normal block. */ - if(!self->file) { + if(!this->file) { printerr("Attempting to read without opening file"); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } - result = dvdnav_read_cache_block(self, self->vobu_start + self->blockN, 1, buf); + result = dvdnav_read_cache_block(this, this->vobu.vobu_start + this->vobu.blockN, 1, buf); if(result <= 0) { printerr("Error reading from DVD."); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } - self->blockN++; + this->vobu.blockN++; (*len) = 2048; (*event) = DVDNAV_BLOCK_OK; - if(self->blockN > self->vobu_length) { - self->vobu_start = self->next_vobu; - self->blockN = 0; - self->expecting_nav_packet = 1; - - if(self->dsi.vobu_sri.next_vobu == SRI_END_OF_CELL) { - cell_playback_t *cell = &(state->pgc->cell_playback[state->cellN - 1]); - - if(cell->still_time != 0xff) { - vm_get_next_cell(self->vm); - } - - if(cell->still_time != 0) { - self->still_frame = cell->still_time; - } - - self->at_soc = 1; - } - } - - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_OK; } -uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream) { +uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *this, uint8_t stream) { audio_attr_t *attr = NULL; - if(!self) + if(!this) return -1; - pthread_mutex_lock(&self->vm_lock); - attr = NLCK_dvdnav_get_audio_attr(self, stream); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); + attr = NLCK_dvdnav_get_audio_attr(this, stream); + pthread_mutex_unlock(&this->vm_lock); if(attr == NULL) return 0xffff; @@ -909,28 +877,28 @@ return attr->lang_code; } -int8_t dvdnav_get_audio_logical_stream(dvdnav_t *self, uint8_t audio_num) { +int8_t dvdnav_get_audio_logical_stream(dvdnav_t *this, uint8_t audio_num) { int8_t retval; - if(!self) + if(!this) return -1; - pthread_mutex_lock(&self->vm_lock); - retval = NCLK_dvdnav_get_audio_logical_stream(self, audio_num); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); + retval = NCLK_dvdnav_get_audio_logical_stream(this, audio_num); + pthread_mutex_unlock(&this->vm_lock); return retval; } -uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *self, uint8_t stream) { +uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) { subp_attr_t *attr = NULL; - if(!self) + if(!this) return -1; - pthread_mutex_lock(&self->vm_lock); - attr = NLCK_dvdnav_get_subp_attr(self, stream); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); + attr = NLCK_dvdnav_get_subp_attr(this, stream); + pthread_mutex_unlock(&this->vm_lock); if(attr == NULL) return 0xffff; @@ -938,66 +906,66 @@ return attr->lang_code; } -int8_t dvdnav_get_spu_logical_stream(dvdnav_t *self, uint8_t subp_num) { +int8_t dvdnav_get_spu_logical_stream(dvdnav_t *this, uint8_t subp_num) { int8_t retval; - if(!self) + if(!this) return -1; - pthread_mutex_lock(&self->vm_lock); - retval = NCLK_dvdnav_get_spu_logical_stream(self, subp_num); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); + retval = NCLK_dvdnav_get_spu_logical_stream(this, subp_num); + pthread_mutex_unlock(&this->vm_lock); return retval; } -int8_t dvdnav_get_active_spu_stream(dvdnav_t *self) { +int8_t dvdnav_get_active_spu_stream(dvdnav_t *this) { int8_t retval; - if(!self) + if(!this) return -1; - pthread_mutex_lock(&self->vm_lock); - retval = NLCK_dvdnav_get_active_spu_stream(self); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); + retval = NLCK_dvdnav_get_active_spu_stream(this); + pthread_mutex_unlock(&this->vm_lock); return retval; } /* First Play domain. (Menu) */ -int8_t dvdnav_is_domain_fp(dvdnav_t *self) { - return _dvdnav_is_domain(self, FP_DOMAIN); +int8_t dvdnav_is_domain_fp(dvdnav_t *this) { + return _dvdnav_is_domain(this, FP_DOMAIN); } /* Video management Menu domain. (Menu) */ -int8_t dvdnav_is_domain_vmgm(dvdnav_t *self) { - return _dvdnav_is_domain(self, VMGM_DOMAIN); +int8_t dvdnav_is_domain_vmgm(dvdnav_t *this) { + return _dvdnav_is_domain(this, VMGM_DOMAIN); } /* Video Title Menu domain (Menu) */ -int8_t dvdnav_is_domain_vtsm(dvdnav_t *self) { - return _dvdnav_is_domain(self, VTSM_DOMAIN); +int8_t dvdnav_is_domain_vtsm(dvdnav_t *this) { + return _dvdnav_is_domain(this, VTSM_DOMAIN); } /* Video Title domain (playing movie). */ -int8_t dvdnav_is_domain_vts(dvdnav_t *self) { - return _dvdnav_is_domain(self, VTS_DOMAIN); +int8_t dvdnav_is_domain_vts(dvdnav_t *this) { + return _dvdnav_is_domain(this, VTS_DOMAIN); } /* Generally delegate angle information handling to * VM */ -dvdnav_status_t dvdnav_angle_change(dvdnav_t *self, int angle) { +dvdnav_status_t dvdnav_angle_change(dvdnav_t *this, int angle) { int num, current; - if(!self) { + if(!this) { return S_ERR; } - if(dvdnav_get_angle_info(self, ¤t, &num) != S_OK) { + if(dvdnav_get_angle_info(this, ¤t, &num) != S_OK) { printerr("Error getting angle info"); return S_ERR; } /* Set angle SPRM if valid */ if((angle > 0) && (angle <= num)) { - self->vm->state.AGL_REG = angle; + this->vm->state.AGL_REG = angle; } else { printerr("Passed an invalid angle number"); return S_ERR; @@ -1005,10 +973,10 @@ return S_OK; } - -dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *self, int* current_angle, +/* FIXME: change order of current_angle, number_of_angles */ +dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *this, int* current_angle, int *number_of_angles) { - if(!self || !self->vm) { + if(!this || !this->vm) { return S_ERR; } @@ -1017,14 +985,25 @@ return S_ERR; } - vm_get_angle_info(self->vm, number_of_angles, current_angle); + vm_get_angle_info(this->vm, number_of_angles, current_angle); return S_OK; } +dvdnav_status_t dvdnav_get_cell_info(dvdnav_t *this, int* current_angle, + int *number_of_angles) { + if(!this || !this->vm) { + return S_ERR; + } + *current_angle=this->position_next.cell; + return S_OK; +} /* * $Log$ + * Revision 1.9 2002/04/22 22:00:48 jcdutton + * Start of rewrite of libdvdnav. Still need to re-implement seeking. + * * Revision 1.8 2002/04/22 20:57:14 f1rmb * Change/fix SPU active stream id. Same for audio. Few new functions, largely * inspired from libogle ;-). diff -r d2d73f2ad8d3 -r 3c1df0cb3aee dvdnav.h --- a/dvdnav.h Mon Apr 22 20:57:15 2002 +0000 +++ b/dvdnav.h Mon Apr 22 22:01:28 2002 +0000 @@ -306,6 +306,9 @@ * button -- Pointer to the value to fill in. */ dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *self, int* button); +pci_t* dvdnav_get_current_nav_pci(dvdnav_t *self); +dvdnav_status_t dvdnav_get_highlight_area(pci_t* nav_pci , int32_t button, int32_t mode, + dvdnav_highlight_area_t* highlight); /** * Move button highlight around (e.g. with arrow keys) @@ -455,6 +458,8 @@ dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *self, int* current_angle, int *number_of_angles); +dvdnav_status_t dvdnav_get_cell_info(dvdnav_t *self, int* current_angle, + int *number_of_angles); /** * Converts a *logical* subpicture stream id into country code * (returns 0xffff if no such stream). diff -r d2d73f2ad8d3 -r 3c1df0cb3aee dvdnav_events.h --- a/dvdnav_events.h Mon Apr 22 20:57:15 2002 +0000 +++ b/dvdnav_events.h Mon Apr 22 22:01:28 2002 +0000 @@ -45,6 +45,8 @@ #define DVDNAV_HIGHLIGHT 9 /* Change highlight region */ #define DVDNAV_SPU_CLUT_CHANGE 10 /* SPU CLUT */ #define DVDNAV_SEEK_DONE 11 /* Seek done, subtitles should be reset */ +#define DVDNAV_HOP_CHANNEL 12 /* Sent when non-seemless stream change has happed */ + /* E.g. Menu button pressed causing change in menu */ /*** EVENT TYPES ***/ diff -r d2d73f2ad8d3 -r 3c1df0cb3aee dvdnav_internal.h --- a/dvdnav_internal.h Mon Apr 22 20:57:15 2002 +0000 +++ b/dvdnav_internal.h Mon Apr 22 22:01:28 2002 +0000 @@ -104,6 +104,13 @@ } ATTRIBUTE_PACKED spu_status_t; #endif +typedef struct dvdnav_vobu_s { + int32_t vobu_start; /* Logical Absolute. MAX needed is 0x300000 */ + int32_t vobu_length; /* Relative offset */ + int32_t blockN; /* Relative offset */ + int32_t vobu_next; /* Relative offset */ +} dvdnav_vobu_t; + /* The main DVDNAV type */ struct dvdnav_s { @@ -114,10 +121,9 @@ int open_domain; /* ..currently opened VOB */ /* Position data */ - uint32_t vobu_start; - uint32_t vobu_length; - uint32_t blockN; - uint32_t next_vobu; + vm_position_t position_next; + vm_position_t position_current; + dvdnav_vobu_t vobu; cell_playback_t *cell; uint32_t jmp_blockN; uint32_t jmp_vobu_start; @@ -168,8 +174,8 @@ /** USEFUL MACROS **/ -#define printerrf(format, args...) snprintf(self->err_str, MAX_ERR_LEN, format, ## args); -#define printerr(str) strncpy(self->err_str, str, MAX_ERR_LEN); +#define printerrf(format, args...) snprintf(this->err_str, MAX_ERR_LEN, format, ## args); +#define printerr(str) strncpy(this->err_str, str, MAX_ERR_LEN); /* Save my typing */ #define S_ERR DVDNAV_STATUS_ERR diff -r d2d73f2ad8d3 -r 3c1df0cb3aee highlight.c --- a/highlight.c Mon Apr 22 20:57:15 2002 +0000 +++ b/highlight.c Mon Apr 22 22:01:28 2002 +0000 @@ -28,6 +28,7 @@ /* #define BUTTON_TESTING */ +#include #include #include "dvdnav_internal.h" @@ -42,142 +43,182 @@ /* Highlighting API calls */ -dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *self, int* button) { - if(!self) +dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *this, int* button) { + if(!this) return S_ERR; /* Simply return the appropriate value based on the SPRM */ - (*button) = (self->vm->state.HL_BTNN_REG) >> 10; + (*button) = (this->vm->state.HL_BTNN_REG) >> 10; return S_OK; } -btni_t *__get_current_button(dvdnav_t *self) { +pci_t* dvdnav_get_current_nav_pci(dvdnav_t *this) { + if (!this ) assert(0); + return &this->pci; +} + +btni_t *__get_current_button(dvdnav_t *this) { int button = 0; - if(dvdnav_get_current_highlight(self, &button) != S_OK) { + if(dvdnav_get_current_highlight(this, &button) != S_OK) { printerrf("Unable to get information on current highlight."); return NULL; } #ifdef BUTTON_TESTING - navPrint_PCI(&(self->pci)); + navPrint_PCI(&(this->pci)); #endif - return &(self->pci.hli.btnit[button-1]); + return &(this->pci.hli.btnit[button-1]); } -dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self) { +dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this) { btni_t *button_ptr; - if(!self) + if(!this) return S_ERR; - if((button_ptr = __get_current_button(self)) == NULL) { + if((button_ptr = __get_current_button(this)) == NULL) { return S_ERR; } - dvdnav_button_select(self, button_ptr->up); + dvdnav_button_select(this, button_ptr->up); return S_OK; } -dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self) { +dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this) { btni_t *button_ptr; - if(!self) + if(!this) return S_ERR; - if((button_ptr = __get_current_button(self)) == NULL) { + if((button_ptr = __get_current_button(this)) == NULL) { return S_ERR; } - dvdnav_button_select(self, button_ptr->down); + dvdnav_button_select(this, button_ptr->down); return S_OK; } -dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self) { +dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this) { btni_t *button_ptr; - if(!self) + if(!this) return S_ERR; - if((button_ptr = __get_current_button(self)) == NULL) { + if((button_ptr = __get_current_button(this)) == NULL) { printerr("Error fetching information on current button."); return S_ERR; } - dvdnav_button_select(self, button_ptr->right); + dvdnav_button_select(this, button_ptr->right); + + return S_OK; +} + +dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this) { + btni_t *button_ptr; + + if(!this) + return S_ERR; + + if((button_ptr = __get_current_button(this)) == NULL) { + return S_ERR; + } + + dvdnav_button_select(this, button_ptr->left); return S_OK; } -dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self) { +dvdnav_status_t dvdnav_get_highlight_area(pci_t* nav_pci , int32_t button, int32_t mode, + dvdnav_highlight_area_t* highlight) { btni_t *button_ptr; - - if(!self) - return S_ERR; + fprintf(stderr,"Button get_highlight_area %i\n", button); - if((button_ptr = __get_current_button(self)) == NULL) { + /* Set the highlight SPRM if the passed button was valid*/ + if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns)) { + fprintf(stderr,"Unable to select button number %i as it doesn't exist", + button); return S_ERR; } + button_ptr = &nav_pci->hli.btnit[button-1]; - dvdnav_button_select(self, button_ptr->left); - + highlight->sx = button_ptr->x_start; + highlight->sy = button_ptr->y_start; + highlight->ex = button_ptr->x_end; + highlight->ey = button_ptr->y_end; + if(button_ptr->btn_coln != 0) { + highlight->palette = nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode]; + } else { + highlight->palette = 0; + } + highlight->pts = nav_pci->hli.hl_gi.hli_s_ptm; + highlight->buttonN = button; +//#ifdef BUTTON_TESTING + fprintf(stderr,"highlight.c:Highlight area is (%u,%u)-(%u,%u), display = %i, button = %u\n", + button_ptr->x_start, button_ptr->y_start, + button_ptr->x_end, button_ptr->y_end, + 1, + button); +//#endif + return S_OK; } -dvdnav_status_t dvdnav_button_activate(dvdnav_t *self) { +dvdnav_status_t dvdnav_button_activate(dvdnav_t *this) { int button; btni_t *button_ptr; - if(!self) + if(!this) return S_ERR; - pthread_mutex_lock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); /* Precisely the same as selecting a button except we want * a different palette */ - if(dvdnav_get_current_highlight(self, &button) != S_OK) { - pthread_mutex_unlock(&self->vm_lock); + if(dvdnav_get_current_highlight(this, &button) != S_OK) { + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } - if(dvdnav_button_select(self, button) != S_OK) { - pthread_mutex_unlock(&self->vm_lock); + if(dvdnav_button_select(this, button) != S_OK) { + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } /* Now get the current button's info */ - if((button_ptr = __get_current_button(self)) == NULL) { + if((button_ptr = __get_current_button(this)) == NULL) { printerr("Error fetching information on current button."); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return S_ERR; } /* And set the palette */ if(button_ptr->btn_coln != 0) { - self->hli_clut = - self->pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][1]; + this->hli_clut = + this->pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][1]; } else { - self->hli_clut = 0; + this->hli_clut = 0; } /* Finally, make the VM execute the appropriate code and * scedule a jump */ fprintf(stderr, "libdvdnav: Evaluating Button Activation commands.\n"); - if(vm_eval_cmd(self->vm, &(button_ptr->cmd)) == 1) { + if(vm_eval_cmd(this->vm, &(button_ptr->cmd)) == 1) { /* Cammand caused a jump */ - dvdnav_do_post_jump(self); + dvdnav_do_post_jump(this); } - - pthread_mutex_unlock(&self->vm_lock); + this->vm->hop_channel++; + pthread_mutex_unlock(&this->vm_lock); return S_OK; } -dvdnav_status_t dvdnav_button_select(dvdnav_t *self, int button) { +dvdnav_status_t dvdnav_button_select(dvdnav_t *this, int button) { btni_t *button_ptr; - if(!self) { - printerrf("Unable to select button number %i as self state bad", + if(!this) { + printerrf("Unable to select button number %i as this state bad", button); return S_ERR; } @@ -185,34 +226,34 @@ fprintf(stderr,"Button select %i\n", button); /* Set the highlight SPRM if the passed button was valid*/ - if((button <= 0) || (button > self->pci.hli.hl_gi.btn_ns)) { + if((button <= 0) || (button > this->pci.hli.hl_gi.btn_ns)) { printerrf("Unable to select button number %i as it doesn't exist", button); return S_ERR; } - self->vm->state.HL_BTNN_REG = (button << 10); + this->vm->state.HL_BTNN_REG = (button << 10); /* Now get the current button's info */ - if((button_ptr = __get_current_button(self)) == NULL) { + if((button_ptr = __get_current_button(this)) == NULL) { printerr("Error fetching information on current button."); return S_ERR; } - self->hli_bbox[0] = button_ptr->x_start; - self->hli_bbox[1] = button_ptr->y_start; - self->hli_bbox[2] = button_ptr->x_end; - self->hli_bbox[3] = button_ptr->y_end; - self->hli_state = 1; /* Selected */ + this->hli_bbox[0] = button_ptr->x_start; + this->hli_bbox[1] = button_ptr->y_start; + this->hli_bbox[2] = button_ptr->x_end; + this->hli_bbox[3] = button_ptr->y_end; + this->hli_state = 1; /* Selected */ if(button_ptr->btn_coln != 0) { - self->hli_clut = - self->pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][0]; + this->hli_clut = + this->pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][0]; } else { - self->hli_clut = 0; + this->hli_clut = 0; } - self->hli_pts = self->pci.hli.hl_gi.hli_s_ptm; - self->hli_buttonN = button; - self->highlight_changed = 1; + this->hli_pts = this->pci.hli.hl_gi.hli_s_ptm; + this->hli_buttonN = button; +// this->position_current.button = -1; /* Force Highligh change */ #ifdef BUTTON_TESTING fprintf(stderr,"highlight.c:Highlight area is (%u,%u)-(%u,%u), display = %i, button = %u\n", button_ptr->x_start, button_ptr->y_start, @@ -224,40 +265,40 @@ return S_OK; } -dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, +dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, int button) { /* A trivial function */ - if(dvdnav_button_select(self, button) != S_ERR) { - return dvdnav_button_activate(self); + if(dvdnav_button_select(this, button) != S_ERR) { + return dvdnav_button_activate(this); } /* Should never get here without an error */ return S_ERR; } -dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, int x, int y) { +dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, int x, int y) { int button, cur_button; /* FIXME: At the moment, the case of no button matchin (x,y) is * silently ignored, is this OK? */ - if(!self) + if(!this) return S_ERR; - if(dvdnav_get_current_highlight(self, &cur_button) != S_OK) { + if(dvdnav_get_current_highlight(this, &cur_button) != S_OK) { return S_ERR; } /* Loop through each button */ - for(button=1; button <= self->pci.hli.hl_gi.btn_ns; button++) { + for(button=1; button <= this->pci.hli.hl_gi.btn_ns; button++) { btni_t *button_ptr = NULL; - button_ptr = &(self->pci.hli.btnit[button-1]); + button_ptr = &(this->pci.hli.btnit[button-1]); if((x >= button_ptr->x_start) && (x <= button_ptr->x_end) && (y >= button_ptr->y_start) && (y <= button_ptr->y_end)) { /* As an efficiency measure, only re-select the button * if it is different to the previously selected one. */ if(button != cur_button) { - dvdnav_button_select(self, button); + dvdnav_button_select(this, button); } } } @@ -265,10 +306,10 @@ return S_OK; } -dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, int x, int y) { +dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, int x, int y) { /* A trivial function */ - if(dvdnav_mouse_select(self, x,y) != S_ERR) { - return dvdnav_button_activate(self); + if(dvdnav_mouse_select(this, x,y) != S_ERR) { + return dvdnav_button_activate(this); } /* Should never get here without an error */ diff -r d2d73f2ad8d3 -r 3c1df0cb3aee navigation.c --- a/navigation.c Mon Apr 22 20:57:15 2002 +0000 +++ b/navigation.c Mon Apr 22 22:01:28 2002 +0000 @@ -33,27 +33,27 @@ /* Navigation API calls */ /* Common things we do everytime we do a jump */ -void dvdnav_do_post_jump(dvdnav_t *self) { - dvd_state_t *state = &(self->vm->state); +void dvdnav_do_post_jump(dvdnav_t *this) { + dvd_state_t *state = &(this->vm->state); cell_playback_t *cell = &(state->pgc->cell_playback[state->cellN - 1]); - self->jmp_blockN = 0; /* FIXME: Should this be different? */ - self->jmp_vobu_start = cell->first_sector; - self->jumping = 1; - self->still_frame = -1; + this->jmp_blockN = 0; /* FIXME: Should this be different? */ + this->jmp_vobu_start = cell->first_sector; + this->jumping = 1; + this->position_current.still = 0; } -dvdnav_status_t dvdnav_still_skip(dvdnav_t *self) { - if(!self) +dvdnav_status_t dvdnav_still_skip(dvdnav_t *this) { + if(!this) return S_ERR; - self->still_frame = -1; + this->position_current.still = 0; return S_OK; } -dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *self, int *titles) { - if(!self) +dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *this, int *titles) { + if(!this) return S_ERR; if(!titles) { @@ -61,13 +61,13 @@ return S_ERR; } - (*titles) = vm_get_vmgi(self->vm)->tt_srpt->nr_of_srpts; + (*titles) = vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts; return S_OK; } -dvdnav_status_t dvdnav_get_number_of_programs(dvdnav_t *self, int *programs) { - if(!self) +dvdnav_status_t dvdnav_get_number_of_programs(dvdnav_t *this, int *programs) { + if(!this) return S_ERR; if(!programs) { @@ -75,107 +75,107 @@ return S_ERR; } - (*programs) = self->vm->state.pgc->nr_of_programs; + (*programs) = this->vm->state.pgc->nr_of_programs; return S_OK; } -dvdnav_status_t dvdnav_title_play(dvdnav_t *self, int title) { +dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int title) { int num_titles; - if(!self) { + if(!this) { return S_ERR; } /* Check number of titles */ - dvdnav_get_number_of_titles(self, &num_titles); + dvdnav_get_number_of_titles(this, &num_titles); if((title > num_titles) || (title <= 0)) { printerrf("Invalid title passed (%i, maximum %i)", title, num_titles); return S_ERR; } - vm_start_title(self->vm, title); + vm_start_title(this->vm, title); - /* self->expecting_nav_packet = 1; */ + /* this->expecting_nav_packet = 1; */ - dvdnav_do_post_jump(self); + dvdnav_do_post_jump(this); return S_OK; } -dvdnav_status_t dvdnav_part_play(dvdnav_t *self, int title, int part) { +dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int title, int part) { int num_titles, num_progs; - if(!self) { + if(!this) { return S_ERR; } /* Check number of titles */ - dvdnav_get_number_of_titles(self, &num_titles); + dvdnav_get_number_of_titles(this, &num_titles); if((title > num_titles) || (title <= 0)) { printerrf("Invalid title passed (%i, maximum %i)", title, num_titles); return S_ERR; } - vm_start_title(self->vm, title); + vm_start_title(this->vm, title); /* Check number of parts */ - num_progs = self->vm->state.pgc->nr_of_programs; + num_progs = this->vm->state.pgc->nr_of_programs; if((part > num_progs) || (part <= 0)) { printerrf("Invalid program passed (%i, maximum %i)", part, num_progs); return S_ERR; } - vm_jump_prog(self->vm, part); + vm_jump_prog(this->vm, part); - /* self->expecting_nav_packet = 1; */ + /* this->expecting_nav_packet = 1; */ - dvdnav_do_post_jump(self); + dvdnav_do_post_jump(this); return S_OK; } -dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *self, int title, +dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *this, int title, int part, int parts_to_play) { /* Perform jump as per usual */ - return dvdnav_part_play(self, title, part); + return dvdnav_part_play(this, title, part); /* FIXME: Impement auto-stop */ /* return S_OK;*/ } -dvdnav_status_t dvdnav_time_play(dvdnav_t *self, int title, +dvdnav_status_t dvdnav_time_play(dvdnav_t *this, int title, unsigned long int time) { /* FIXME: Implement */ return S_OK; } -dvdnav_status_t dvdnav_stop(dvdnav_t *self) { - if(!self) +dvdnav_status_t dvdnav_stop(dvdnav_t *this) { + if(!this) return S_ERR; /* Set the STOP flag */ - self->stop = 1; + this->stop = 1; return S_OK; } -dvdnav_status_t dvdnav_go_up(dvdnav_t *self) { - if(!self) +dvdnav_status_t dvdnav_go_up(dvdnav_t *this) { + if(!this) return S_ERR; /* A nice easy function... delegate to the VM */ - vm_go_up(self->vm); + vm_go_up(this->vm); - dvdnav_do_post_jump(self); + dvdnav_do_post_jump(this); return S_OK; } diff -r d2d73f2ad8d3 -r 3c1df0cb3aee searching.c --- a/searching.c Mon Apr 22 20:57:15 2002 +0000 +++ b/searching.c Mon Apr 22 22:01:28 2002 +0000 @@ -33,13 +33,13 @@ /* Searching API calls */ -dvdnav_status_t dvdnav_time_search(dvdnav_t *self, +dvdnav_status_t dvdnav_time_search(dvdnav_t *this, unsigned long int time) { /* Time search the current PGC based on the xxx table */ return S_OK; } -dvdnav_status_t dvdnav_sector_search(dvdnav_t *self, +dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, unsigned long int offset, int origin) { /* FIXME: Implement */ @@ -51,55 +51,55 @@ dvd_state_t *state; dvdnav_status_t result; - if((!self) || (!self->vm) ) + if((!this) || (!this->vm) ) return -1; - state = &(self->vm->state); + state = &(this->vm->state); if((!state) || (!state->pgc) ) return -1; if(offset == 0) return -1; - if(self->still_frame != -1) + if(this->position_current.still != 0) /* Cannot do seeking in a still frame. */ return -1; - pthread_mutex_lock(&self->vm_lock); - result = dvdnav_get_position(self, &target, &length); + pthread_mutex_lock(&this->vm_lock); + result = dvdnav_get_position(this, &target, &length); fprintf(stderr,"FIXME: seeking to offset=%lu pos=%u length=%u\n", offset, target, length); fprintf(stderr,"FIXME: Before cellN=%u blockN=%u\n" , state->cellN, state->blockN); if(!result) { - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return -1; } switch(origin) { case SEEK_SET: if(offset > length) { - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return -1; } target = offset; break; case SEEK_CUR: if(target + offset > length) { - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return -1; } target += offset; break; case SEEK_END: if(length - offset < 0) { - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return -1; } target = length - offset; default: /* Error occured */ - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return -1; } @@ -127,20 +127,20 @@ if(fnd_cell_nr <= last_cell_nr) { fprintf(stderr,"Seeking to cell %i from choice of %i to %i\n", fnd_cell_nr, first_cell_nr, last_cell_nr); - self->seekto_block = target; - self->seeking = 1; + this->seekto_block = target; + this->seeking = 1; /* * Clut does not actually change, * but as the decoders have been closed then opened, * A new clut has to be sent. */ - self->spu_clut_changed = 1; + this->spu_clut_changed = 1; //ogle_do_post_jump(ogle); fprintf(stderr,"FIXME: After cellN=%u blockN=%u\n" , state->cellN, state->blockN); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return target; } else { fprintf(stderr, "Error when seeking, asked to seek outside program\n"); @@ -150,20 +150,20 @@ fprintf(stderr,"FIXME: Implement seeking to location %u\n", target); -// self->seekto_block=target; -// self->seeking = 1; +// this->seekto_block=target; +// this->seeking = 1; - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_unlock(&this->vm_lock); return -1; } -dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int part) { +dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int part) { return S_OK; } -dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *self) { +dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *this) { dvd_state_t *state; - state = &(self->vm->state); + state = &(this->vm->state); /* Make sure this is not the first chapter */ if(state->pgN <= 1 ) { @@ -171,54 +171,56 @@ return S_ERR; } fprintf(stderr,"dvdnav: previous chapter\n"); - vm_jump_prog(self->vm, state->pgN - 1); - dvdnav_do_post_jump(self); + vm_jump_prog(this->vm, state->pgN - 1); + dvdnav_do_post_jump(this); + this->vm->hop_channel++; fprintf(stderr,"dvdnav: previous chapter done\n"); return S_OK; } -dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *self) { +dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) { fprintf(stderr,"dvdnav: top chapter. NOP.\n"); return S_OK; } -dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *self) { +dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) { dvd_state_t *state; - state = &(self->vm->state); + state = &(this->vm->state); /* Make sure this is not the last chapter */ if(state->pgN >= state->pgc->nr_of_programs) { fprintf(stderr,"dvdnav: at last chapter. next chapter failed.\n"); return S_ERR; } fprintf(stderr,"dvdnav: next chapter\n"); - vm_jump_prog(self->vm, state->pgN + 1); - dvdnav_do_post_jump(self); + vm_jump_prog(this->vm, state->pgN + 1); + dvdnav_do_post_jump(this); + this->vm->hop_channel++; fprintf(stderr,"dvdnav: next chapter done\n"); return S_OK; } -dvdnav_status_t dvdnav_menu_call(dvdnav_t *self, DVDMenuID_t menu) { +dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { dvd_state_t *state; - pthread_mutex_lock(&self->vm_lock); - state = &(self->vm->state); - vm_menu_call(self->vm, menu, 0); - dvdnav_do_post_jump(self); - pthread_mutex_unlock(&self->vm_lock); + pthread_mutex_lock(&this->vm_lock); + state = &(this->vm->state); + vm_menu_call(this->vm, menu, 0); + dvdnav_do_post_jump(this); + pthread_mutex_unlock(&this->vm_lock); return S_OK; } -dvdnav_status_t dvdnav_current_title_info(dvdnav_t *self, int *tt, int *pr) { +dvdnav_status_t dvdnav_current_title_info(dvdnav_t *this, int *tt, int *pr) { int vts_ttn = 0; int vts, i; domain_t domain; tt_srpt_t* srpt; - if(!self) + if(!this) return S_ERR; if(!tt || !pr) { @@ -230,26 +232,26 @@ if(*pr) *pr = -1; - domain = self->vm->state.domain; + domain = this->vm->state.domain; if((domain == FP_DOMAIN) || (domain == VMGM_DOMAIN)) { /* Not in a title */ return S_OK; } - vts_ttn = self->vm->state.VTS_TTN_REG; - vts = self->vm->state.vtsN; + vts_ttn = this->vm->state.VTS_TTN_REG; + vts = this->vm->state.vtsN; if(pr) { - *pr = self->vm->state.pgN; + *pr = this->vm->state.pgN; } /* Search TT_SRPT for title */ - if(!(vm_get_vmgi(self->vm))) { + if(!(vm_get_vmgi(this->vm))) { printerr("Oh poo, no SRPT"); return S_ERR; } - srpt = vm_get_vmgi(self->vm)->tt_srpt; + srpt = vm_get_vmgi(this->vm)->tt_srpt; for(i=0; inr_of_srpts; i++) { title_info_t* info = &(srpt->title[i]); if((info->title_set_nr == vts) && (info->vts_ttn == vts_ttn)) { @@ -263,8 +265,8 @@ static char __title_str[] = "DVDNAV"; -dvdnav_status_t dvdnav_get_title_string(dvdnav_t *self, char **title_str) { - if(!self) +dvdnav_status_t dvdnav_get_title_string(dvdnav_t *this, char **title_str) { + if(!this) return S_ERR; if(!title_str) { @@ -277,7 +279,7 @@ return S_OK; } -dvdnav_status_t dvdnav_get_position(dvdnav_t *self, unsigned int* pos, +dvdnav_status_t dvdnav_get_position(dvdnav_t *this, unsigned int* pos, unsigned int *len) { uint32_t cur_sector; uint32_t first_cell_nr; @@ -285,10 +287,10 @@ cell_playback_t *first_cell; cell_playback_t *last_cell; dvd_state_t *state; - if((!self) || (!self->vm) ) + if((!this) || (!this->vm) ) return 0; - state = &(self->vm->state); + state = &(this->vm->state); if((!state) || (!state->pgc) ) return 0; @@ -298,7 +300,7 @@ } /* Get current sector */ - cur_sector = self->vobu_start + self->blockN; + cur_sector = this->vobu.vobu_start + this->vobu.blockN; /* Find start cell of program. */ first_cell_nr = state->pgc->program_map[state->pgN-1]; @@ -318,7 +320,7 @@ return S_OK; } -dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *self, +dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *this, unsigned int *pos, unsigned int *len) { uint32_t cur_sector; @@ -327,10 +329,10 @@ cell_playback_t *first_cell; cell_playback_t *last_cell; dvd_state_t *state; - if((!self) || (!self->vm) ) + if((!this) || (!this->vm) ) return S_ERR; - state = &(self->vm->state); + state = &(this->vm->state); if((!state) || (!state->pgc) ) return S_ERR; @@ -340,7 +342,7 @@ } /* Get current sector */ - cur_sector = self->vobu_start + self->blockN; + cur_sector = this->vobu.vobu_start + this->vobu.blockN; /* Now find first and last cells in title. */ first_cell_nr = state->pgc->program_map[0]; diff -r d2d73f2ad8d3 -r 3c1df0cb3aee settings.c --- a/settings.c Mon Apr 22 20:57:15 2002 +0000 +++ b/settings.c Mon Apr 22 22:01:28 2002 +0000 @@ -32,8 +32,8 @@ /* Characteristics/setting API calls */ -dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *self, int *region) { - if(!self) +dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *this, int *region) { + if(!this) return S_ERR; if(!region) { @@ -41,41 +41,41 @@ return S_ERR; } - if(!self->vm) { + if(!this->vm) { printerr("VM not yet initialised"); return S_ERR; } - (*region) = self->vm->state.registers.SPRM[20]; + (*region) = this->vm->state.registers.SPRM[20]; return S_OK; } -dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *self, int mask) { - if(!self) +dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *this, int mask) { + if(!this) return S_ERR; - if(!self->vm) { + if(!this->vm) { printerr("VM not yet initialised"); return S_ERR; } - self->vm->state.registers.SPRM[20] = (mask & 0xff); + this->vm->state.registers.SPRM[20] = (mask & 0xff); return S_OK; } -dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *self, int use_readahead) { - if(!self) +dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *this, int use_readahead) { + if(!this) return S_ERR; - self->use_read_ahead = use_readahead; + this->use_read_ahead = use_readahead; return S_OK; } -dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *self, int* flag) { - if(!self) +dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *this, int* flag) { + if(!this) return S_ERR; if(!flag) { @@ -83,7 +83,7 @@ return S_ERR; } - (*flag) = self->use_read_ahead; + (*flag) = this->use_read_ahead; return S_OK; } diff -r d2d73f2ad8d3 -r 3c1df0cb3aee vm.c --- a/vm.c Mon Apr 22 20:57:15 2002 +0000 +++ b/vm.c Mon Apr 22 22:01:28 2002 +0000 @@ -40,6 +40,7 @@ #include "decoder.h" #include "vmcmd.h" #include "vm.h" +#include "dvdnav_internal.h" /* Local prototypes */ @@ -266,6 +267,39 @@ return 0; /* ?? */ } +int vm_position_get(vm_t *vm, vm_position_t *position) { + position->button = (vm->state).HL_BTNN_REG >> 10; + position->spu_channel = (vm->state).SPST_REG; + position->audio_channel = (vm->state).AST_REG; + position->angle_channel = (vm->state).AGL_REG; + position->hop_channel = vm->hop_channel; /* Increases by one on each hop */ + position->vts = (vm->state).vtsN; + position->domain = (vm->state).domain; + position->cell = (vm->state).cellN; + position->still = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].still_time; + position->vobu_start = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector; + position->vobu_next = (vm->state).blockN; + position->vobu_next = 0; /* Just for now */ + return 1; +} + +int vm_position_print(vm_t *vm, vm_position_t *position) { + fprintf(stderr, "But=%x Spu=%x Aud=%x Ang=%x Hop=%x vts=%x dom=%x cell=%x still=%x start=%x next=%d\n", + position->button, + position->spu_channel, + position->audio_channel, + position->angle_channel, + position->hop_channel, + position->vts, + position->domain, + position->cell, + position->still, + position->vobu_start, + position->vobu_next); + return 1; +} + + int vm_start_title(vm_t *vm, int tt) { link_t link_values; @@ -802,7 +836,7 @@ if((vm->state).pgN > (vm->state).pgc->nr_of_programs) { fprintf(stderr, "(vm->state).pgN (%i) == pgc->nr_of_programs + 1 (%i)\n", (vm->state).pgN, (vm->state).pgc->nr_of_programs + 1); - assert((vm->state).pgN == (vm->state).pgc->nr_of_programs + 1); + //assert((vm->state).pgN == (vm->state).pgc->nr_of_programs + 1); return play_PGC_post(vm); } @@ -1574,6 +1608,9 @@ /* * $Log$ + * Revision 1.12 2002/04/22 22:00:48 jcdutton + * Start of rewrite of libdvdnav. Still need to re-implement seeking. + * * Revision 1.11 2002/04/12 20:06:41 jcdutton * Implement General Register Counters or GPRM counters. * Navigation timers are not supported yet. SPRM[9] and SPRM[10]. diff -r d2d73f2ad8d3 -r 3c1df0cb3aee vm.h --- a/vm.h Mon Apr 22 20:57:15 2002 +0000 +++ b/vm.h Mon Apr 22 22:01:28 2002 +0000 @@ -61,12 +61,30 @@ int rsm_cellN; } dvd_state_t; +typedef struct vm_position_s { + int16_t button; /* Button highlighted */ + uint32_t clut; /* CLUT to use, not needed in this struct */ + int32_t vts; /* vts number to use */ + int32_t domain; /* domain to use */ + int32_t spu_channel; /* spu channel to use */ + int32_t angle_channel; /* angle channel to use */ + int32_t audio_channel; /* audio channel to use */ + int32_t hop_channel; /* channel hopping. E.g menu button pressed */ + int32_t title; /* title number */ + int32_t chapter; /* chapter number */ + int32_t cell; /* cell number */ + int32_t still; /* is cell still */ + int32_t vobu_start; /* block number of start of current VOBU in use */ + int32_t vobu_next; /* block number within VOBU in use */ +} vm_position_t; + typedef struct { dvd_reader_t *dvd; ifo_handle_t *vmgi; ifo_handle_t *vtsi; dvd_state_t state; int badness_counter; + int32_t hop_channel; } vm_t; @@ -107,6 +125,8 @@ /* Other calls */ int vm_reset(vm_t *vm, char *dvdroot); /* , register_t regs); */ int vm_start(vm_t *vm); +int vm_position_get(vm_t *vm, vm_position_t *position); +int vm_position_print(vm_t *vm, vm_position_t *position); int vm_eval_cmd(vm_t *vm, vm_cmd_t *cmd); int vm_get_next_cell(vm_t *vm); int vm_menu_call(vm_t *vm, DVDMenuID_t menuid, int block);