/* Sets start origin for subsequent seeks/reads */ void VCDSetOrigin( access_t *p_access, lsn_t i_lsn, track_t i_track, const vcdinfo_itemid_t *p_itemid ) { vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN), "i_lsn: %lu, track: %d", (long unsigned int) i_lsn, i_track ); vcdplayer_set_origin(p_access, i_lsn, i_track, p_itemid); switch (p_vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_ENTRY: VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, "chapter", _("Entry"), "Setting entry/segment"); p_vcdplayer->i_cur_title = i_track - 1; p_vcdplayer->i_cur_chapter = p_itemid->num; break; case VCDINFO_ITEM_TYPE_SEGMENT: VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, "chapter", _("Segment"), "Setting entry/segment"); /* The last title entry is the for segments (when segments exist and they must here. The segment seekpoints are stored after the entry seekpoints and (zeroed) lid seekpoints. */ p_vcdplayer->i_cur_title = p_vcdplayer->i_titles - 1; p_vcdplayer->i_cur_chapter = p_vcdplayer->i_entries + p_vcdplayer->i_lids + p_itemid->num; break; case VCDINFO_ITEM_TYPE_TRACK: p_vcdplayer->i_cur_title = i_track - 1; p_vcdplayer->i_cur_chapter = vcdinfo_track_get_entry(p_vcdplayer->vcd, i_track); break; default: msg_Warn( p_access, "can't set origin for play type %d", p_vcdplayer->play_item.type ); } VCDUpdateTitle( p_access ); }
/* Sets start origin for subsequent seeks/reads */ void VCDSetOrigin( access_t *p_access, lsn_t i_lsn, track_t i_track, const vcdinfo_itemid_t *p_itemid ) { vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN), "i_lsn: %lu, track: %d", (long unsigned int) i_lsn, i_track ); vcdplayer_set_origin(p_access, i_lsn, i_track, p_itemid); switch (p_vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_ENTRY: VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, "chapter", _("Entry"), "Setting entry/segment"); p_access->info.i_title = i_track-1; if (p_vcdplayer->b_track_length) { p_vcdplayer->size = p_vcdplayer->p_title[i_track-1]->i_size; p_access->info.i_pos = (uint64_t) M2F2_SECTOR_SIZE * (vcdinfo_get_track_lsn(p_vcdplayer->vcd, i_track)-i_lsn); } else { p_vcdplayer->size = M2F2_SECTOR_SIZE * (int64_t) vcdinfo_get_entry_sect_count(p_vcdplayer->vcd,p_itemid->num); p_access->info.i_pos = 0; } dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), "size: %"PRIu64", pos: %"PRIu64, p_vcdplayer->size, p_access->info.i_pos ); p_access->info.i_seekpoint = p_itemid->num; break; case VCDINFO_ITEM_TYPE_SEGMENT: VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, "chapter", _("Segment"), "Setting entry/segment"); /* The last title entry is the for segments (when segments exist and they must here. The segment seekpoints are stored after the entry seekpoints and (zeroed) lid seekpoints. */ p_access->info.i_title = p_vcdplayer->i_titles - 1; p_vcdplayer->size = 0; /* No seeking on stills, please. */ p_access->info.i_pos = 0; p_access->info.i_seekpoint = p_vcdplayer->i_entries + p_vcdplayer->i_lids + p_itemid->num; break; case VCDINFO_ITEM_TYPE_TRACK: p_access->info.i_title = i_track-1; p_vcdplayer->size = p_vcdplayer->p_title[i_track-1]->i_size; p_access->info.i_pos = 0; p_access->info.i_seekpoint = vcdinfo_track_get_entry(p_vcdplayer->vcd, i_track); break; default: msg_Warn( p_access, "can't set origin for play type %d", p_vcdplayer->play_item.type ); } p_access->info.i_update = INPUT_UPDATE_TITLE|INPUT_UPDATE_SEEKPOINT; VCDUpdateTitle( p_access ); }
/**************************************************************************** * VCDSeek ****************************************************************************/ int VCDSeek( access_t * p_access, uint64_t i_pos ) { if (!p_access || !p_access->p_sys) return VLC_EGENERIC; { vcdplayer_t *p_vcdplayer = (vcdplayer_t *)p_vcd_access->p_sys; const input_title_t *t = p_vcdplayer->p_title[p_access->info.i_title]; unsigned int i_entry = VCDINFO_INVALID_ENTRY; int i_seekpoint; /* Next sector to read */ p_access->info.i_pos = i_pos; p_vcdplayer->i_lsn = (i_pos / (uint64_t) M2F2_SECTOR_SIZE) + p_vcdplayer->origin_lsn; switch (p_vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_TRACK: case VCDINFO_ITEM_TYPE_ENTRY: break; default: p_vcdplayer->b_valid_ep = false; break; } /* Find entry */ if( p_vcdplayer->b_valid_ep ) { for( i_entry = 0 ; i_entry < p_vcdplayer->i_entries ; i_entry ++ ) { if( p_vcdplayer->i_lsn < p_vcdplayer->p_entries[i_entry] ) { VCDUpdateVar( p_access, i_entry, VLC_VAR_SETVALUE, "chapter", _("Entry"), "Setting entry" ); break; } } { vcdinfo_itemid_t itemid; itemid.num = i_entry; itemid.type = VCDINFO_ITEM_TYPE_ENTRY; VCDSetOrigin(p_access, p_vcdplayer->i_lsn, p_vcdplayer->i_track, &itemid); } } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK), "orig %lu, cur: %lu, offset: %"PRIi64", entry %d", (long unsigned int) p_vcdplayer->origin_lsn, (long unsigned int) p_vcdplayer->i_lsn, i_pos, i_entry ); /* Find seekpoint */ for( i_seekpoint = 0; i_seekpoint < t->i_seekpoint; i_seekpoint++ ) { if( i_seekpoint + 1 >= t->i_seekpoint ) break; if( i_pos < t->seekpoint[i_seekpoint + 1]->i_byte_offset ) break; } /* Update current seekpoint */ if( i_seekpoint != p_access->info.i_seekpoint ) { dbg_print( (INPUT_DBG_SEEK), "seekpoint change %lu", (long unsigned int) i_seekpoint ); p_access->info.i_update |= INPUT_UPDATE_SEEKPOINT; p_access->info.i_seekpoint = i_seekpoint; } } p_access->info.b_eof = false; return VLC_SUCCESS; }