Mercurial > libdvdnav.hg
changeset 265:99d33725395d src
commit Miguel's approach on the time search function
(it needs fixing, because it does not use the time table, but interpolates
only cell times; but better than not having the function at all)
author | mroi |
---|---|
date | Mon, 03 Oct 2005 21:07:14 +0000 |
parents | 8c86b61eb06f |
children | 21ba13a7b77a |
files | dvdnav.c dvdnav_internal.h searching.c |
diffstat | 3 files changed, 89 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/dvdnav.c Wed Apr 20 16:16:20 2005 +0000 +++ b/dvdnav.c Mon Oct 03 21:07:14 2005 +0000 @@ -203,7 +203,7 @@ } /* converts a dvd_time_t to PTS ticks */ -static int64_t dvdnav_convert_time(dvd_time_t *time) { +int64_t dvdnav_convert_time(dvd_time_t *time) { int64_t result; int64_t frames;
--- a/dvdnav_internal.h Wed Apr 20 16:16:20 2005 +0000 +++ b/dvdnav_internal.h Mon Oct 03 21:07:14 2005 +0000 @@ -183,6 +183,11 @@ char err_str[MAX_ERR_LEN]; }; +/** HELPER FUNCTIONS **/ + +/* converts a dvd_time_t to PTS ticks */ +int64_t dvdnav_convert_time(dvd_time_t *time); + /** USEFUL MACROS **/ #ifdef __GNUC__
--- a/searching.c Wed Apr 20 16:16:20 2005 +0000 +++ b/searching.c Mon Oct 03 21:07:14 2005 +0000 @@ -34,12 +34,6 @@ /* Searching API calls */ -dvdnav_status_t dvdnav_time_search(dvdnav_t *this, - uint64_t time) { - /* FIXME: Time search the current PGC based on the xxx table */ - return DVDNAV_STATUS_OK; -} - /* Scan the ADMAP for a particular block number. */ /* Return placed in vobu. */ /* Returns error status */ @@ -101,6 +95,89 @@ return DVDNAV_STATUS_ERR; } +/* FIXME: right now, this function does not use the time tables but interpolates + only the cell times */ +dvdnav_status_t dvdnav_time_search(dvdnav_t *this, + uint64_t time) { + + uint64_t target = time; + uint64_t length = 0; + uint32_t first_cell_nr, last_cell_nr, cell_nr; + int32_t found; + cell_playback_t *cell; + dvd_state_t *state; + dvdnav_status_t result; + + if(this->position_current.still != 0) { + printerr("Cannot seek in a still frame."); + return DVDNAV_STATUS_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 DVDNAV_STATUS_ERR; + } + + + if (this->pgc_based) { + first_cell_nr = 1; + last_cell_nr = state->pgc->nr_of_cells; + } else { + /* Find start cell of program. */ + first_cell_nr = state->pgc->program_map[state->pgN-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 + last_cell_nr = state->pgc->nr_of_cells; + } + + found = 0; + for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { + cell = &(state->pgc->cell_playback[cell_nr-1]); + length = dvdnav_convert_time(&cell->playback_time); + if (target >= length) { + target -= length; + } else { + /* FIXME: there must be a better way than interpolation */ + target = target * (cell->last_sector - cell->first_sector + 1) / length; + target += cell->first_sector; + + found = 1; + break; + } + } + + if(found) { + int32_t vobu; +#ifdef LOG_DEBUG + fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n", + cell_nr, first_cell_nr, last_cell_nr); +#endif + if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) { + int32_t start = state->pgc->cell_playback[cell_nr-1].first_sector; + + if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) { +#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); +#endif + this->vm->hop_channel += HOP_SEEK; + pthread_mutex_unlock(&this->vm_lock); + return DVDNAV_STATUS_OK; + } + } + } + + fprintf(MSG_OUT, "libdvdnav: Error when seeking\n"); + printerr("Error when seeking."); + pthread_mutex_unlock(&this->vm_lock); + return DVDNAV_STATUS_ERR; +} + dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, uint64_t offset, int32_t origin) { uint32_t target = 0;