Mercurial > libdvdnav.hg
diff searching.c @ 114:b6834e6359cf src
big libdvdnav cleanup, quoting the ChangeLog:
* some bugfixes
* code cleanup
* build process polishing
* more sensible event order in get_next_block to ensure useful event delivery
* VOBU level resume
* fixed: seeking in a multiangle feature briefly showed the wrong angle
author | mroi |
---|---|
date | Thu, 20 Feb 2003 15:32:21 +0000 |
parents | ec2df154be56 |
children | 48ba92648842 |
line wrap: on
line diff
--- a/searching.c Mon Jan 13 13:33:45 2003 +0000 +++ b/searching.c Thu Feb 20 15:32:21 2003 +0000 @@ -25,46 +25,52 @@ #include "config.h" #endif -#include <dvdnav.h> +#include <assert.h> + #include "dvdnav_internal.h" #include "vm.h" #include <dvdread/nav_types.h> +/* +#define LOG_DEBUG +*/ + /* Searching API calls */ dvdnav_status_t dvdnav_time_search(dvdnav_t *this, unsigned long int time) { -/* Time search the current PGC based on the xxx table */ + /* FIXME: Time search the current PGC based on the xxx table */ return S_OK; } /* Scan the ADMAP for a particular block number. */ /* Return placed in vobu. */ /* Returns error status */ - -dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, int32_t seekto_block, int32_t *vobu) { - /* FIXME:Need to handle seeking outside current cell. */ +/* FIXME: Maybe need to handle seeking outside current cell. */ +static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, int32_t seekto_block, int32_t *vobu) { vobu_admap_t *admap = NULL; + +#ifdef LOG_DEBUG + fprintf(MSG_OUT, "libdvdnav: Seeking to target %u ...\n", seekto_block); +#endif *vobu = -1; - fprintf(MSG_OUT, "libdvdnav: Seeking to target %u ...\n", - seekto_block); /* Search through the VOBU_ADMAP for the nearest VOBU * to the target block */ switch(domain) { - case FP_DOMAIN: - case VMGM_DOMAIN: - admap = this->vm->vmgi->menu_vobu_admap; - break; - case VTSM_DOMAIN: - admap = this->vm->vtsi->menu_vobu_admap; - break; - case VTS_DOMAIN: - admap = this->vm->vtsi->vts_vobu_admap; - break; - default: - fprintf(MSG_OUT, "libdvdnav: Error: Unknown domain for seeking seek.\n"); + case FP_DOMAIN: + case VMGM_DOMAIN: + admap = this->vm->vmgi->menu_vobu_admap; + break; + case VTSM_DOMAIN: + admap = this->vm->vtsi->menu_vobu_admap; + break; + case VTS_DOMAIN: + admap = this->vm->vtsi->vts_vobu_admap; + break; + default: + fprintf(MSG_OUT, "libdvdnav: Error: Unknown domain for seeking.\n"); } if(admap) { int32_t address = 0; @@ -85,7 +91,6 @@ } else { vobu_start = next_vobu; } - address ++; } if(found) { @@ -101,65 +106,67 @@ } dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, - unsigned long int offset, int origin) { -/* FIXME: Implement */ - + unsigned long int offset, int origin) { uint32_t target = 0; uint32_t length = 0; - uint32_t first_cell_nr, last_cell_nr, cell_nr, fnd_cell_nr; + uint32_t first_cell_nr, last_cell_nr, cell_nr; int found; - cell_playback_t *cell, *fnd_cell; + cell_playback_t *cell; dvd_state_t *state; dvdnav_status_t result; - if((!this) || (!this->vm) || (!this->started)) - return -1; + if(this->position_current.still != 0) { + printerr("Cannot seek in a still frame."); + return S_ERR; + } - state = &(this->vm->state); - if((!state) || (!state->pgc) ) - return -1; - - if(this->position_current.still != 0) - /* Cannot do seeking in a still frame. */ - return -1; - - pthread_mutex_lock(&this->vm_lock); result = dvdnav_get_position(this, &target, &length); - fprintf(MSG_OUT, "libdvdnav: FIXME: seeking to offset=%lu pos=%u length=%u\n", offset, target, length); - fprintf(MSG_OUT, "libdvdnav: FIXME: Before cellN=%u blockN=%u\n" , - state->cellN, - state->blockN); +#ifdef LOG_DEBUG + fprintf(MSG_OUT, "libdvdnav: seeking to offset=%lu pos=%u length=%u\n", offset, target, length); + fprintf(MSG_OUT, "libdvdnav: Before cellN=%u blockN=%u\n", state->cellN, state->blockN); +#endif if(!result) { - pthread_mutex_unlock(&this->vm_lock); - return -1; + return S_ERR; } + pthread_mutex_lock(&this->vm_lock); + state = &(this->vm->state); + if(!state->pgc) { + printerr("No current PGC."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } + switch(origin) { case SEEK_SET: if(offset > length) { + printerr("Request to seek behind end."); pthread_mutex_unlock(&this->vm_lock); - return -1; + return S_ERR; } target = offset; break; case SEEK_CUR: if(target + offset > length) { + printerr("Request to seek behind end."); pthread_mutex_unlock(&this->vm_lock); - return -1; + return S_ERR; } target += offset; break; case SEEK_END: if(length - offset < 0) { + printerr("Request to seek before start."); pthread_mutex_unlock(&this->vm_lock); - return -1; + return S_ERR; } target = length - offset; break; default: /* Error occured */ + printerr("Illegal seek mode."); pthread_mutex_unlock(&this->vm_lock); - return -1; + return S_ERR; } /* First find closest cell number in program */ @@ -170,83 +177,89 @@ last_cell_nr = state->pgc->nr_of_cells; } - found = 0; target += state->pgc->cell_playback[first_cell_nr-1].first_sector; - fnd_cell_nr = last_cell_nr + 1; + found = 0; + target += state->pgc->cell_playback[first_cell_nr-1].first_sector; for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { cell = &(state->pgc->cell_playback[cell_nr-1]); if((cell->first_sector <= target) && (cell->last_sector >= target)) { + found = 1; state->cellN = cell_nr; state->blockN = 0; - state->cell_restart++; - found = 1; - fnd_cell_nr = cell_nr; - fnd_cell = cell; + state->cell_restart++; } } - if(fnd_cell_nr <= last_cell_nr) { + if(found) { int32_t vobu, start; - dvdnav_status_t status; +#ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n", - fnd_cell_nr, first_cell_nr, last_cell_nr); - status = dvdnav_scan_admap(this, state->domain, target, &vobu); - /* - * Clut does not actually change, - * but as the decoders have been closed then opened, - * A new clut has to be sent. - */ - start =(state->pgc->cell_playback[state->cellN - 1].first_sector); - fprintf(MSG_OUT, "libdvdnav: FIXME: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , + state->cellN, first_cell_nr, last_cell_nr); +#endif + dvdnav_scan_admap(this, state->domain, target, &vobu); + start = state->pgc->cell_playback[state->cellN - 1].first_sector; +#ifdef LOG_DEBUG + fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , state->cellN, state->blockN, target, vobu, start); - state->blockN = vobu - start; - fprintf(MSG_OUT, "libdvdnav: FIXME: After vobu=%x start=%x blockN=%x\n" , +#endif + state->blockN = vobu - start; +#ifdef LOG_DEBUG + fprintf(MSG_OUT, "libdvdnav: After vobu=%x start=%x blockN=%x\n" , vobu, start, state->blockN); +#endif + this->vm->hop_channel += HOP_SEEK; pthread_mutex_unlock(&this->vm_lock); - return target; - } else { - fprintf(MSG_OUT, "libdvdnav: Error when seeking, asked to seek outside program\n"); + return S_OK; } - + + fprintf(MSG_OUT, "libdvdnav: Error when seeking, asked to seek outside program\n"); fprintf(MSG_OUT, "libdvdnav: FIXME: Implement seeking to location %u\n", target); - + printerr("Error when seeking."); pthread_mutex_unlock(&this->vm_lock); - return -1; + return S_ERR; } dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int part) { - - if((!this) || (!this->vm) ) - return S_ERR; - - return S_OK; + int title, old_part; + + if (dvdnav_current_title_info(this, &title, &old_part) == S_OK) + return dvdnav_part_play(this, title, part); + return S_ERR; } dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *this) { - dvd_state_t *state; - - if((!this) || (!this->vm) ) - return S_ERR; - state = &(this->vm->state); - if((!state) || (!state->pgc) ) + if(!this) { + printerr("Passed a NULL pointer."); return S_ERR; + } + + pthread_mutex_lock(&this->vm_lock); + if(!this->vm->state.pgc) { + printerr("No current PGC."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } - pthread_mutex_lock(&this->vm_lock); +#ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: previous chapter\n"); - if (!vm_prev_pg(this->vm)) { - fprintf(MSG_OUT, "libdvdnav: prev chapter failed.\n"); +#endif + if (!vm_jump_prev_pg(this->vm)) { + fprintf(MSG_OUT, "libdvdnav: previous chapter failed.\n"); + printerr("Skip to previous chapter failed."); pthread_mutex_unlock(&this->vm_lock); return S_ERR; } this->position_current.still = 0; this->vm->hop_channel++; +#ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: previous chapter done\n"); +#endif pthread_mutex_unlock(&this->vm_lock); return S_OK; @@ -254,70 +267,96 @@ dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) { - if((!this) || (!this->vm) ) + if(!this) { + printerr("Passed a NULL pointer."); return S_ERR; + } - fprintf(MSG_OUT, "libdvdnav: top chapter. NOP.\n"); - - return S_OK; -} - -dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) { - dvd_state_t *state; + pthread_mutex_lock(&this->vm_lock); + if(!this->vm->state.pgc) { + printerr("No current PGC."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } - if((!this) || (!this->vm) ) - return S_ERR; - - state = &(this->vm->state); - if((!state) || (!state->pgc) ) - return S_ERR; - - pthread_mutex_lock(&this->vm_lock); - fprintf(MSG_OUT, "libdvdnav: next chapter\n"); - if (!vm_next_pg(this->vm)) { - fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n"); +#ifdef LOG_DEBUG + fprintf(MSG_OUT, "libdvdnav: top chapter\n"); +#endif + if (!vm_jump_top_pg(this->vm)) { + fprintf(MSG_OUT, "libdvdnav: top chapter failed.\n"); + printerr("Skip to top chapter failed."); pthread_mutex_unlock(&this->vm_lock); return S_ERR; } this->position_current.still = 0; this->vm->hop_channel++; +#ifdef LOG_DEBUG + fprintf(MSG_OUT, "libdvdnav: top chapter done\n"); +#endif + pthread_mutex_unlock(&this->vm_lock); + + return S_OK; +} + +dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) { + + if(!this) { + printerr("Passed a NULL pointer."); + return S_ERR; + } + + pthread_mutex_lock(&this->vm_lock); + if(!this->vm->state.pgc) { + printerr("No current PGC."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } + +#ifdef LOG_DEBUG + fprintf(MSG_OUT, "libdvdnav: next chapter\n"); +#endif + if (!vm_jump_next_pg(this->vm)) { + fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n"); + printerr("Skip to next chapter failed."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } + this->position_current.still = 0; + this->vm->hop_channel++; +#ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: next chapter done\n"); +#endif pthread_mutex_unlock(&this->vm_lock); return S_OK; } dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { - dvd_state_t *state; - - if((!this) || (!this->vm) ) - return S_ERR; - - pthread_mutex_lock(&this->vm_lock); - state = &(this->vm->state); - if (vm_menu_call(this->vm, menu, 0)) - this->vm->hop_channel++; - pthread_mutex_unlock(&this->vm_lock); - return S_OK; -} - -static char __title_str[] = "DVDNAV"; - -dvdnav_status_t dvdnav_get_title_string(dvdnav_t *this, char **title_str) { - if(!this) - return S_ERR; - - if(!title_str) { - printerr("Passed a NULL pointer"); + + if(!this) { + printerr("Passed a NULL pointer."); return S_ERR; } - (*title_str) = __title_str; - - return S_OK; + pthread_mutex_lock(&this->vm_lock); + if(!this->vm->state.pgc) { + printerr("No current PGC."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } + + if (vm_jump_menu(this->vm, menu)) { + this->vm->hop_channel++; + pthread_mutex_unlock(&this->vm_lock); + return S_OK; + } else { + printerr("No such menu."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; + } } -dvdnav_status_t dvdnav_get_position(dvdnav_t *this, 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; @@ -325,24 +364,32 @@ cell_playback_t *first_cell; cell_playback_t *last_cell; dvd_state_t *state; - if((!this) || (!this->vm) ) - return 0; - + + if(!this || !pos || !len) { + printerr("Passed a NULL pointer."); + return S_ERR; + } + if(!this->started) { + printerr("Virtual DVD machine not started."); + return S_ERR; + } + + pthread_mutex_lock(&this->vm_lock); state = &(this->vm->state); - if((!state) || (!state->pgc) ) - return 0; - - /* Sanity check */ - if(state->pgN > state->pgc->nr_of_programs) { - return 0; + if(!state->pgc) { + printerr("No current PGC."); + pthread_mutex_unlock(&this->vm_lock); + return S_ERR; } - + /* Get current sector */ cur_sector = this->vobu.vobu_start + this->vobu.blockN; /* Find start cell of program. */ first_cell_nr = state->pgc->program_map[state->pgN-1]; first_cell = &(state->pgc->cell_playback[first_cell_nr-1]); + + /* Find end cell of program */ if(state->pgN < state->pgc->nr_of_programs) { last_cell_nr = state->pgc->program_map[state->pgN] - 1; } else { @@ -352,8 +399,7 @@ *pos= cur_sector - first_cell->first_sector; *len= last_cell->last_sector - first_cell->first_sector; - /* fprintf(MSG_OUT, "libdvdnav: searching:current pos=%u length=%u\n",*pos,*len); */ - + pthread_mutex_unlock(&this->vm_lock); return S_OK; } @@ -367,18 +413,18 @@ cell_playback_t *first_cell; cell_playback_t *last_cell; dvd_state_t *state; - if((!this) || (!this->vm) ) - return S_ERR; - - state = &(this->vm->state); - if((!state) || (!state->pgc) ) - return S_ERR; - - /* Sanity check */ - if(state->pgN > state->pgc->nr_of_programs) { + + if(!this || !pos || !len) { + printerr("Passed a NULL pointer."); return S_ERR; } - + + state = &(this->vm->state); + if(!state->pgc) { + printerr("No current PGC."); + return S_ERR; + } + /* Get current sector */ cur_sector = this->vobu.vobu_start + this->vobu.blockN; @@ -393,5 +439,3 @@ return S_OK; } - -