From c7cac1b20abc9d907ed715e1040be49532d280c2 Mon Sep 17 00:00:00 2001 From: Rocky Bernstein Date: Tue, 21 Dec 2004 03:42:04 +0000 Subject: [PATCH] Work on getting slider seeking working better. --- modules/access/vcdx/access.c | 214 +++++++++++++++++--------------- modules/access/vcdx/info.c | 36 +++++- modules/access/vcdx/info.h | 6 +- modules/access/vcdx/intf.h | 10 +- modules/access/vcdx/vcdplayer.c | 181 ++++++++++++++++++++++++--- modules/access/vcdx/vcdplayer.h | 40 +++++- 6 files changed, 349 insertions(+), 138 deletions(-) diff --git a/modules/access/vcdx/access.c b/modules/access/vcdx/access.c index fb2410e264..a8262dd980 100644 --- a/modules/access/vcdx/access.c +++ b/modules/access/vcdx/access.c @@ -45,6 +45,8 @@ #include #include +#define FREE_AND_NULL(ptr) if (NULL != ptr) free(ptr); ptr = NULL; + /* how many blocks VCDRead will read in each loop */ #define VCD_BLOCKS_ONCE 20 @@ -59,10 +61,8 @@ static int VCDControl ( access_t *p_access, int i_query, va_list args ); /* Now those which are strictly internal */ -static void VCDSetOrigin ( access_t *p_access, - lsn_t origin_lsn, - lsn_t i_lsn, lsn_t end_lsn, - track_t track, +static void VCDSetOrigin ( access_t *p_access, lsn_t i_lsn, + track_t track, const vcdinfo_itemid_t * p_itemid ); static int VCDEntryPoints ( access_t * ); static int VCDLIDs ( access_t * ); @@ -96,7 +96,7 @@ static access_t *p_vcd_access = NULL; static void cdio_log_handler (cdio_log_level_t level, const char message[]) { - const access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_vcd_access->p_sys; + const vcdplayer_t *p_vcd = (vcdplayer_t *)p_vcd_access->p_sys; switch (level) { case CDIO_LOG_DEBUG: case CDIO_LOG_INFO: @@ -122,7 +122,7 @@ cdio_log_handler (cdio_log_level_t level, const char message[]) static void vcd_log_handler (vcd_log_level_t level, const char message[]) { - access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_vcd_access->p_sys; + vcdplayer_t *p_vcd = (vcdplayer_t *)p_vcd_access->p_sys; switch (level) { case VCD_LOG_DEBUG: case VCD_LOG_INFO: @@ -151,16 +151,18 @@ vcd_log_handler (vcd_log_level_t level, const char message[]) static block_t * VCDReadBlock( access_t * p_access ) { - access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; - block_t *p_block; - int i_blocks = VCD_BLOCKS_ONCE; - int i_read; - byte_t p_last_sector[ M2F2_SECTOR_SIZE ]; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; + block_t *p_block; + int i_blocks = VCD_BLOCKS_ONCE; + int i_read; + byte_t p_last_sector[ M2F2_SECTOR_SIZE ]; i_read = 0; +#if 0 dbg_print( (INPUT_DBG_CALL), "lsn: %lu", (long unsigned int) p_vcd->i_lsn ); +#endif /* Compute the number of blocks we have to read */ @@ -178,13 +180,14 @@ VCDReadBlock( access_t * p_access ) for ( i_read = 0 ; i_read < i_blocks ; i_read++ ) { - if ( p_vcd->i_lsn == p_vcd->end_lsn ) { + if ( p_vcd->i_lsn >= p_vcd->end_lsn ) { vcdplayer_read_status_t read_status; /* We've run off of the end of this entry. Do we continue or stop? */ dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), - "end reached, cur: %lu", - (long unsigned int) p_vcd->i_lsn ); + "end reached, cur: %lu, end: %u", + (long unsigned int) p_vcd->i_lsn, + p_vcd->end_lsn); read_status = vcdplayer_pbc_is_on( p_vcd ) ? vcdplayer_pbc_nav( p_access ) @@ -246,9 +249,7 @@ VCDReadBlock( access_t * p_access ) p_vcd->play_item.num = i_entry; dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), "entry change" ); VCDSetOrigin( p_access, - vcdinfo_get_track_lba(p_vcd->vcd, i_track), vcdinfo_get_entry_lba(p_vcd->vcd, i_entry), - vcdinfo_get_track_lba(p_vcd->vcd, i_track+1), i_track, &(p_vcd->play_item) ); } } @@ -280,8 +281,7 @@ VCDSeek( access_t * p_access, int64_t i_pos ) if (!p_access || !p_access->p_sys) return VLC_EGENERIC; { - access_vcd_data_t *p_vcd = - (access_vcd_data_t *)p_vcd_access->p_sys; + vcdplayer_t *p_vcd = (vcdplayer_t *)p_vcd_access->p_sys; const input_title_t *t = p_vcd->p_title[p_access->info.i_title]; int i_seekpoint; unsigned int i_entry=VCDINFO_INVALID_ENTRY; @@ -289,7 +289,7 @@ VCDSeek( access_t * p_access, int64_t i_pos ) /* Next sector to read */ p_access->info.i_pos = i_pos; p_vcd->i_lsn = (i_pos / (int64_t)M2F2_SECTOR_SIZE) + - p_vcd->origin_lsn; + p_vcd->track_lsn; /* Find entry */ if( p_vcd->b_valid_ep ) @@ -305,6 +305,8 @@ VCDSeek( access_t * p_access, int64_t i_pos ) } p_vcd->play_item.num = i_entry; p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; + vcdplayer_set_origin(p_access); + VCDUpdateTitle(p_access); } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK), @@ -348,7 +350,7 @@ VCDPlay( access_t *p_access, vcdinfo_itemid_t itemid ) { - access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; #if 0 const vlc_bool_t b_was_still = p_vcd->in_still; #endif @@ -372,9 +374,7 @@ VCDPlay( access_t *p_access, vcdinfo_itemid_t itemid ) } p_vcd->in_still = VLC_FALSE; VCDSetOrigin( p_access, - vcdinfo_get_track_lba(p_vcd->vcd, i_track), vcdinfo_get_entry_lba(p_vcd->vcd, i_entry), - vcdinfo_get_track_lba(p_vcd->vcd, i_track+1), i_track, &itemid ); break; } @@ -406,9 +406,7 @@ VCDPlay( access_t *p_access, vcdinfo_itemid_t itemid ) default: p_vcd->in_still = VLC_FALSE; } - VCDSetOrigin( p_access, p_vcd->p_segments[i_seg], - p_vcd->p_segments[i_seg], - p_vcd->p_segments[i_seg+1], + VCDSetOrigin( p_access, p_vcd->p_segments[i_seg], 0, &itemid ); } @@ -468,9 +466,7 @@ VCDPlay( access_t *p_access, vcdinfo_itemid_t itemid ) track_t i_track = vcdinfo_get_track(p_vcd->vcd, i_entry); p_vcd->in_still = VLC_FALSE; VCDSetOrigin( p_access, - vcdinfo_get_entry_lba(p_vcd->vcd, i_track), vcdinfo_get_entry_lba(p_vcd->vcd, i_entry), - vcdinfo_get_entry_lba(p_vcd->vcd, i_track+1), i_track, &itemid ); } break; @@ -500,7 +496,7 @@ VCDEntryPoints( access_t * p_access ) if (!p_access || !p_access->p_sys) return VLC_EGENERIC; { - access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + vcdplayer_t *p_vcd = (vcdplayer_t *) p_access->p_sys; const unsigned int i_entries = vcdinfo_get_num_entries(p_vcd->vcd); const track_t i_last_track = cdio_get_num_tracks(vcdinfo_get_cd_image(p_vcd->vcd)) @@ -561,12 +557,12 @@ VCDEntryPoints( access_t * p_access ) static int VCDSegments( access_t * p_access ) { - access_vcd_data_t * p_vcd; - unsigned int i; - unsigned int i_segments; + vcdplayer_t *p_vcd; + unsigned int i; + unsigned int i_segments; - p_vcd = (access_vcd_data_t *) p_access->p_sys; + p_vcd = (vcdplayer_t *) p_access->p_sys; i_segments = p_vcd->num_segments = vcdinfo_get_num_segments(p_vcd->vcd); #define area p_access->stream.pp_areas @@ -648,7 +644,7 @@ VCDTitles( access_t * p_access ) if (!p_access || !p_access->p_sys) return VLC_EGENERIC; { - access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + vcdplayer_t *p_vcd = (vcdplayer_t *) p_access->p_sys; track_t i; p_vcd->i_titles = 0; @@ -680,7 +676,7 @@ VCDTitles( access_t * p_access ) static int VCDLIDs( access_t * p_access ) { - access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + vcdplayer_t *p_vcd = (vcdplayer_t *) p_access->p_sys; p_vcd->i_lids = vcdinfo_get_num_LIDs(p_vcd->vcd); p_vcd->i_lid = VCDINFO_INVALID_ENTRY; @@ -714,10 +710,10 @@ static char * VCDParse( access_t * p_access, /*out*/ vcdinfo_itemid_t * p_itemid, /*out*/ vlc_bool_t *play_single_item ) { - access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_access->p_sys; - char * psz_parser; - char * psz_source; - char * psz_next; + vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; + char *psz_parser; + char *psz_source; + char *psz_next; if( config_GetInt( p_access, MODULE_STRING "-PBC" ) ) { p_itemid->type = VCDINFO_ITEM_TYPE_LID; @@ -831,32 +827,32 @@ VCDParse( access_t * p_access, /*out*/ vcdinfo_itemid_t * p_itemid, Set's start origin subsequent seeks/reads */ static void -VCDSetOrigin( access_t *p_access, lsn_t origin_lsn, - lsn_t i_lsn, lsn_t end_lsn, track_t i_track, +VCDSetOrigin( access_t *p_access, lsn_t i_lsn, track_t i_track, const vcdinfo_itemid_t *p_itemid ) { - access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; - + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; + unsigned int i_title = i_track - 1; /* For now */ - p_vcd->origin_lsn = origin_lsn; p_vcd->i_lsn = i_lsn; - p_vcd->end_lsn = end_lsn; p_vcd->i_track = i_track; + p_vcd->track_lsn = vcdinfo_get_track_lsn(p_vcd->vcd, i_track); + p_vcd->play_item.num = p_itemid->num; p_vcd->play_item.type = p_itemid->type; + vcdplayer_set_origin(p_access); + p_access->info.i_title = i_track-1; p_access->info.i_size = p_vcd->p_title[i_title]->i_size; - p_access->info.i_pos = ( i_lsn - origin_lsn ) * M2F2_SECTOR_SIZE; + p_access->info.i_pos = ( i_lsn - p_vcd->track_lsn ) + * M2F2_SECTOR_SIZE; p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE | INPUT_UPDATE_SEEKPOINT; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN), - "origin: %lu, cur_lsn: %lu, end_lsn: %lu, track: %d", - (long unsigned int) origin_lsn, - (long unsigned int) i_lsn, - (long unsigned int) end_lsn, i_track ); + "i_lsn: %lu, track: %d", (long unsigned int) i_lsn, + i_track ); if (p_itemid->type == VCDINFO_ITEM_TYPE_ENTRY) { VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, @@ -867,36 +863,25 @@ VCDSetOrigin( access_t *p_access, lsn_t origin_lsn, "chapter", _("Segment"), "Setting entry/segment"); /* seekpoint is what? ??? */ } - - { - unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) - + strlen(p_vcd->psz_source) + sizeof("@E999")+3; - char *psz_mrl = malloc( psz_mrl_max ); - - if( psz_mrl ) - { - char *psz_name; - snprintf(psz_mrl, psz_mrl_max, "%s%s", - VCD_MRL_PREFIX, p_vcd->psz_source); - psz_name = VCDFormatStr( p_access, p_vcd, - config_GetPsz( p_access, MODULE_STRING - "-title-format" ), - psz_mrl, &(p_vcd->play_item) ); - input_Control( p_vcd->p_input, INPUT_SET_NAME, psz_name ); - free(psz_mrl); - } - } + VCDUpdateTitle( p_access ); + } /***************************************************************************** - * vcd_Open: Opens a VCD device or file and returns an opaque handle + * vcd_Open: Opens a VCD device or file initializes, a list of + tracks, segements and entry lsns and sizes and returns an opaque handle. *****************************************************************************/ static vcdinfo_obj_t * vcd_Open( vlc_object_t *p_this, const char *psz_dev ) { + access_t *p_access = (access_t *)p_this; + vcdplayer_t *p_vcd = (vcdplayer_t *) p_access->p_sys; vcdinfo_obj_t *p_vcdobj; char *actual_dev; + unsigned int i; + + dbg_print(INPUT_DBG_CALL, "called with %s\n", psz_dev); if( !psz_dev ) return NULL; @@ -908,6 +893,47 @@ vcd_Open( vlc_object_t *p_this, const char *psz_dev ) } free(actual_dev); + /* + Save summary info on tracks, segments and entries... + */ + + if ( 0 < (p_vcd->i_tracks = vcdinfo_get_num_tracks(p_vcdobj)) ) { + p_vcd->track = (vcdplayer_play_item_info_t *) + calloc(p_vcd->i_tracks, sizeof(vcdplayer_play_item_info_t)); + + for (i=0; ii_tracks; i++) { + unsigned int track_num=i+1; + p_vcd->track[i].size = + vcdinfo_get_track_sect_count(p_vcdobj, track_num); + p_vcd->track[i].start_LSN = + vcdinfo_get_track_lsn(p_vcdobj, track_num); + } + } else + p_vcd->track = NULL; + + if ( 0 < (p_vcd->i_entries = vcdinfo_get_num_entries(p_vcdobj)) ) { + p_vcd->entry = (vcdplayer_play_item_info_t *) + calloc(p_vcd->i_entries, sizeof(vcdplayer_play_item_info_t)); + + for (i=0; ii_entries; i++) { + p_vcd->entry[i].size = vcdinfo_get_entry_sect_count(p_vcdobj, i); + p_vcd->entry[i].start_LSN = vcdinfo_get_entry_lba(p_vcdobj, i); + } + } else + p_vcd->entry = NULL; + + if ( 0 < (p_vcd->i_segments = vcdinfo_get_num_segments(p_vcdobj)) ) { + p_vcd->segment = (vcdplayer_play_item_info_t *) + calloc(p_vcd->i_segments, sizeof(vcdplayer_play_item_info_t)); + + for (i=0; ii_segments; i++) { + p_vcd->segment[i].size = vcdinfo_get_seg_sector_count(p_vcdobj, i); + p_vcd->segment[i].start_LSN = vcdinfo_get_seg_lba(p_vcdobj, i); + } + } else + p_vcd->segment = NULL; + + return p_vcdobj; } @@ -950,7 +976,7 @@ VCDUpdateVar( access_t *p_access, int i_num, int i_action, vlc_value_t val; val.i_int = i_num; if (p_access) { - const access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_vcd_access->p_sys; + const vcdplayer_t *p_vcd = (vcdplayer_t *)p_vcd_access->p_sys; dbg_print( INPUT_DBG_PBC, "%s %d", p_debug_label, i_num ); } if (p_label) { @@ -969,11 +995,11 @@ int E_(DebugCallback) ( vlc_object_t *p_this, const char *psz_name, vlc_value_t oldval, vlc_value_t val, void *p_data ) { - access_vcd_data_t *p_vcd; + vcdplayer_t *p_vcd; if (NULL == p_vcd_access) return VLC_EGENERIC; - p_vcd = (access_vcd_data_t *)p_vcd_access->p_sys; + p_vcd = (vcdplayer_t *)p_vcd_access->p_sys; if (p_vcd->i_debug & (INPUT_DBG_CALL|INPUT_DBG_EXT)) { msg_Dbg( p_vcd_access, "Old debug (x%0x) %d, new debug (x%0x) %d", @@ -996,12 +1022,12 @@ E_(DebugCallback) ( vlc_object_t *p_this, const char *psz_name, int E_(VCDOpen) ( vlc_object_t *p_this ) { - access_t * p_access = (access_t *)p_this; - access_vcd_data_t * p_vcd; - char * psz_source; - vcdinfo_itemid_t itemid; - vlc_bool_t b_play_ok; - vlc_bool_t play_single_item = VLC_FALSE; + access_t *p_access = (access_t *)p_this; + vcdplayer_t *p_vcd; + char *psz_source; + vcdinfo_itemid_t itemid; + vlc_bool_t b_play_ok; + vlc_bool_t play_single_item = VLC_FALSE; p_access->pf_read = NULL; p_access->pf_block = VCDReadBlock; @@ -1015,7 +1041,7 @@ E_(VCDOpen) ( vlc_object_t *p_this ) p_access->info.i_title = 0; p_access->info.i_seekpoint = 0; - p_vcd = malloc( sizeof(access_vcd_data_t) ); + p_vcd = malloc( sizeof(vcdplayer_t) ); if( p_vcd == NULL ) { @@ -1127,25 +1153,19 @@ E_(VCDOpen) ( vlc_object_t *p_this ) void E_(VCDClose) ( vlc_object_t *p_this ) { - access_t *p_access = (access_t *)p_this; - access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_access->p_sys; + access_t *p_access = (access_t *)p_this; + vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "VCDClose" ); vcdinfo_close( p_vcd->vcd ); - free( p_vcd->p_entries ); - free( p_vcd->p_segments ); - free( p_vcd->psz_source ); - - /* For reasons that are a mystery to me we don't have to deal with - stopping, and destroying the p_vcd->p_intf thread. And if we do - it causes problems upstream. - */ - if( p_vcd->p_intf != NULL ) - { - p_vcd->p_intf = NULL; - } + FREE_AND_NULL( p_vcd->p_entries ); + FREE_AND_NULL( p_vcd->p_segments ); + FREE_AND_NULL( p_vcd->psz_source ); + FREE_AND_NULL( p_vcd->track ); + FREE_AND_NULL( p_vcd->segment ); + FREE_AND_NULL( p_vcd->entry ); free( p_vcd ); p_access->p_sys = NULL; @@ -1159,8 +1179,8 @@ E_(VCDClose) ( vlc_object_t *p_this ) *****************************************************************************/ static int VCDControl( access_t *p_access, int i_query, va_list args ) { - access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; - int *pi_int; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; + int *pi_int; int i; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_EVENT), @@ -1284,9 +1304,7 @@ static int VCDControl( access_t *p_access, int i_query, va_list args ) itemid.type = VCDINFO_ITEM_TYPE_TRACK; VCDSetOrigin(p_access, - vcdinfo_get_track_lba(p_vcd->vcd, i_track), vcdinfo_get_entry_lba(p_vcd->vcd, i_entry), - vcdinfo_get_track_lba(p_vcd->vcd, i_track+1), i_track, &itemid ); } break; @@ -1311,9 +1329,7 @@ static int VCDControl( access_t *p_access, int i_query, va_list args ) p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; VCDSetOrigin( p_access, - vcdinfo_get_track_lba(p_vcd->vcd, i_track), vcdinfo_get_entry_lba(p_vcd->vcd, i), - vcdinfo_get_track_lba(p_vcd->vcd, i_track+1), i_track, &(p_vcd->play_item) ); } return VLC_SUCCESS; diff --git a/modules/access/vcdx/info.c b/modules/access/vcdx/info.c index 8a4ff05ec7..e18281a40b 100644 --- a/modules/access/vcdx/info.c +++ b/modules/access/vcdx/info.c @@ -40,7 +40,7 @@ static inline void MetaInfoAddStr(access_t *p_access, char *p_cat, char *title, const char *str) { - access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + vcdplayer_t *p_vcd = (vcdplayer_t *) p_access->p_sys; if ( str ) { dbg_print( INPUT_DBG_META, "field: %s: %s", title, str); input_Control( p_vcd->p_input, INPUT_ADD_INFO, p_cat, title, "%s", str); @@ -51,7 +51,7 @@ MetaInfoAddStr(access_t *p_access, char *p_cat, static inline void MetaInfoAddNum(access_t *p_access, char *psz_cat, char *title, int num) { - access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + vcdplayer_t *p_vcd = (vcdplayer_t *) p_access->p_sys; dbg_print( INPUT_DBG_META, "field %s: %d", title, num); input_Control( p_vcd->p_input, INPUT_ADD_INFO, psz_cat, title, "%d", num ); } @@ -65,7 +65,7 @@ MetaInfoAddNum(access_t *p_access, char *psz_cat, char *title, int num) void VCDMetaInfo( access_t *p_access, /*const*/ char *psz_mrl ) { - access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + vcdplayer_t *p_vcd = (vcdplayer_t *) p_access->p_sys; unsigned int i_entries = vcdinfo_get_num_entries(p_vcd->vcd); unsigned int last_entry = 0; char *psz_cat; @@ -174,7 +174,7 @@ VCDMetaInfo( access_t *p_access, /*const*/ char *psz_mrl ) %% : a % */ char * -VCDFormatStr(const access_t *p_access, access_vcd_data_t *p_vcd, +VCDFormatStr(const access_t *p_access, vcdplayer_t *p_vcd, const char format_str[], const char *mrl, const vcdinfo_itemid_t *itemid) { @@ -312,7 +312,7 @@ VCDFormatStr(const access_t *p_access, access_vcd_data_t *p_vcd, static void VCDCreatePlayListItem(const access_t *p_access, - access_vcd_data_t *p_vcd, + vcdplayer_t *p_vcd, playlist_t *p_playlist, const vcdinfo_itemid_t *itemid, char *psz_mrl, int psz_mrl_max, @@ -362,7 +362,7 @@ VCDCreatePlayListItem(const access_t *p_access, } int -VCDFixupPlayList( access_t *p_access, access_vcd_data_t *p_vcd, +VCDFixupPlayList( access_t *p_access, vcdplayer_t *p_vcd, const char *psz_source, vcdinfo_itemid_t *itemid, vlc_bool_t b_single_item ) { @@ -414,3 +414,27 @@ VCDFixupPlayList( access_t *p_access, access_vcd_data_t *p_vcd, return 0; } +void +VCDUpdateTitle( access_t *p_access ) +{ + + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; + + unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) + + strlen(p_vcd->psz_source) + sizeof("@E999")+3; + char *psz_mrl = malloc( psz_mrl_max ); + + if( psz_mrl ) + { + char *psz_name; + snprintf(psz_mrl, psz_mrl_max, "%s%s", + VCD_MRL_PREFIX, p_vcd->psz_source); + psz_name = VCDFormatStr( p_access, p_vcd, + config_GetPsz( p_access, MODULE_STRING + "-title-format" ), + psz_mrl, &(p_vcd->play_item) ); + input_Control( p_vcd->p_input, INPUT_SET_NAME, psz_name ); + free(psz_mrl); + } +} + diff --git a/modules/access/vcdx/info.h b/modules/access/vcdx/info.h index 8b1b9279eb..a010158db7 100644 --- a/modules/access/vcdx/info.h +++ b/modules/access/vcdx/info.h @@ -29,7 +29,7 @@ /* Fills out playlist information. */ -int VCDFixupPlayList( access_t *p_access, access_vcd_data_t *p_vcd, +int VCDFixupPlayList( access_t *p_access, vcdplayer_t *p_vcd, const char *psz_source, vcdinfo_itemid_t *itemid, vlc_bool_t b_single_track ); @@ -39,8 +39,10 @@ int VCDFixupPlayList( access_t *p_access, access_vcd_data_t *p_vcd, void VCDMetaInfo( access_t *p_access, /*const*/ char *psz_mrl ); -char * VCDFormatStr(const access_t *p_access, access_vcd_data_t *p_vcd, +char * VCDFormatStr(const access_t *p_access, vcdplayer_t *p_vcd, const char format_str[], const char *mrl, const vcdinfo_itemid_t *itemid); +void VCDUpdateTitle( access_t *p_access ); + #endif /* VCD_INFO_H */ diff --git a/modules/access/vcdx/intf.h b/modules/access/vcdx/intf.h index 52475802eb..b82c994eb3 100644 --- a/modules/access/vcdx/intf.h +++ b/modules/access/vcdx/intf.h @@ -26,12 +26,12 @@ *****************************************************************************/ struct intf_sys_t { - input_thread_t * p_input; - access_vcd_data_t * p_vcd; + input_thread_t *p_input; + vcdplayer_t *p_vcd; - vlc_bool_t b_still; /* True if we are in a still frame */ - vlc_bool_t b_inf_still; /* True if still wait time is infinite */ - mtime_t m_still_time; /* Time in microseconds remaining + vlc_bool_t b_still; /* True if we are in a still frame */ + vlc_bool_t b_inf_still; /* True if still wait time is infinite */ + mtime_t m_still_time; /* Time in microseconds remaining to wait in still frame. */ #if FINISHED diff --git a/modules/access/vcdx/vcdplayer.c b/modules/access/vcdx/vcdplayer.c index 07812958b1..0b1d5ed220 100644 --- a/modules/access/vcdx/vcdplayer.c +++ b/modules/access/vcdx/vcdplayer.c @@ -51,16 +51,45 @@ Return VLC_TRUE if playback control (PBC) is on */ vlc_bool_t -vcdplayer_pbc_is_on( const access_vcd_data_t *p_vcd ) +vcdplayer_pbc_is_on( const vcdplayer_t *p_vcd ) { return VCDINFO_INVALID_ENTRY != p_vcd->i_lid; } +/* Given an itemid, return the size for the object (via information + previously stored when opening the vcd). */ +static size_t +vcdplayer_get_item_size(access_t * p_access, vcdinfo_itemid_t itemid) +{ + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; + + switch (itemid.type) { + case VCDINFO_ITEM_TYPE_ENTRY: + return p_vcd->entry[itemid.num].size; + break; + case VCDINFO_ITEM_TYPE_SEGMENT: + return p_vcd->segment[itemid.num].size; + break; + case VCDINFO_ITEM_TYPE_TRACK: + return p_vcd->track[itemid.num-1].size; + break; + case VCDINFO_ITEM_TYPE_LID: + /* Play list number (LID) */ + return 0; + break; + case VCDINFO_ITEM_TYPE_NOTFOUND: + case VCDINFO_ITEM_TYPE_SPAREID2: + default: + LOG_ERR("%s %d\n", _("bad item type"), itemid.type); + return 0; + } +} + static void vcdplayer_update_entry( access_t * p_access, uint16_t ofs, uint16_t *entry, const char *label) { - access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; if ( ofs == VCDINFO_INVALID_OFFSET ) { *entry = VCDINFO_INVALID_ENTRY; @@ -84,7 +113,7 @@ vcdplayer_update_entry( access_t * p_access, uint16_t ofs, vcdplayer_read_status_t vcdplayer_non_pbc_nav ( access_t * p_access ) { - access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; /* Not in playback control. Do we advance automatically or stop? */ switch (p_vcd->play_item.type) { @@ -125,11 +154,125 @@ vcdplayer_non_pbc_nav ( access_t * p_access ) return READ_BLOCK; } +#if FINISHED +/*! + Set reading to play an entire track. +*/ +static void +_vcdplayer_set_track(access_t * p_access, track_t i_track) +{ + vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; + if (i_track < 1 || i_track > p_vcd->i_tracks) + return; + else { + vcdinfo_obj_t *p_obj = p_vcd->vcd; + vcdinfo_itemid_t itemid; + + itemid.num = i_track; + itemid.type = VCDINFO_ITEM_TYPE_TRACK; + p_vcd->in_still = 0; + p_vcd->i_lsn = vcdinfo_get_track_lsn(p_obj, i_track); + p_vcd->play_item = itemid; + p_vcd->i_track = i_track; + p_vcd->track_lsn = p_vcd->i_lsn; + + vcdplayer_set_origin(p_access); + + dbg_print(INPUT_DBG_LSN, "LSN: %u\n", p_vcd->i_lsn); + } +} + +/*! + Set reading to play an entry +*/ +static void +_vcdplayer_set_entry(access_t * p_access, unsigned int num) +{ + vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; + vcdinfo_obj_t *p_obj = p_vcd->vcd; + unsigned int num_entries = vcdinfo_get_num_entries(p_obj); + + if (num >= num_entries) { + LOG_ERR("%s %d\n", _("bad entry number"), num); + return; + } else { + vcdinfo_itemid_t itemid; + + itemid.num = num; + itemid.type = VCDINFO_ITEM_TYPE_ENTRY; + p_vcd->in_still = 0; + p_vcd->i_lsn = vcdinfo_get_entry_lsn(p_obj, num); + p_vcd->play_item = itemid; + p_vcd->i_track = vcdinfo_get_track(p_obj, num); + p_vcd->track_lsn = vcdinfo_get_track_lsn(p_obj, p_vcd->i_track); + p_vcd->track_end_lsn = p_vcd->track_lsn + + p_vcd->track[p_vcd->i_track-1].size; + + vcdplayer_set_origin(p_access); + + dbg_print(INPUT_DBG_LSN, "LSN: %u, track_end LSN: %u\n", + p_vcd->i_lsn, p_vcd->track_end_lsn); + } +} + +/*! + Set reading to play an segment (e.g. still frame) +*/ +static void +_vcdplayer_set_segment(access_t * p_access, unsigned int num) +{ + vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; + vcdinfo_obj_t *p_obj = p_vcd->vcd; + segnum_t num_segs = vcdinfo_get_num_segments(p_obj); + + if (num >= num_segs) { + LOG_ERR("%s %d\n", _("bad segment number"), num); + return; + } else { + vcdinfo_itemid_t itemid; + + p_vcd->i_lsn = vcdinfo_get_seg_lsn(p_obj, num); + p_vcd->i_track = 0; + + if (VCDINFO_NULL_LSN==p_vcd->i_lsn) { + LOG_ERR("%s %d\n", + _("Error in getting current segment number"), num); + return; + } + + itemid.num = num; + itemid.type = VCDINFO_ITEM_TYPE_SEGMENT; + p_vcd->play_item = itemid; + + vcdplayer_set_origin(p_access); + + dbg_print(INPUT_DBG_LSN, "LSN: %u\n", p_vcd->i_lsn); + } +} +#endif /* FINISHED */ + +/* + Set's start origin and size for subsequent seeks. + input: p_vcd->i_lsn, p_vcd->play_item + changed: p_vcd->origin_lsn, p_vcd->end_lsn +*/ +void +vcdplayer_set_origin(access_t *p_access) +{ + vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; + size_t i_size= vcdplayer_get_item_size(p_access, p_vcd->play_item); + + p_vcd->end_lsn = p_vcd->i_lsn + i_size; + p_vcd->origin_lsn = p_vcd->i_lsn; + + dbg_print((INPUT_DBG_CALL|INPUT_DBG_LSN), "end LSN: %u\n", p_vcd->end_lsn); +} + /* Handles PBC navigation when reaching the end of a play item. */ vcdplayer_read_status_t vcdplayer_pbc_nav ( access_t * p_access ) { - access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; /* We are in playback control. */ vcdinfo_itemid_t itemid; @@ -265,7 +408,7 @@ vcdplayer_pbc_nav ( access_t * p_access ) vlc_bool_t vcdplayer_inc_play_item( access_t *p_access ) { - access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; int noi; @@ -305,7 +448,7 @@ vcdplayer_inc_play_item( access_t *p_access ) vlc_bool_t vcdplayer_play_default( access_t * p_access ) { - access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; vcdinfo_itemid_t itemid; @@ -379,9 +522,9 @@ vcdplayer_play_default( access_t * p_access ) vlc_bool_t vcdplayer_play_next( access_t * p_access ) { - access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; - vcdinfo_obj_t *obj; + vcdinfo_obj_t *p_obj; vcdinfo_itemid_t itemid; if (!p_vcd) return VLC_FALSE; @@ -389,13 +532,13 @@ vcdplayer_play_next( access_t * p_access ) dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), "current: %d" , p_vcd->play_item.num); - obj = p_vcd->vcd; + p_obj = p_vcd->vcd; itemid.type = p_vcd->play_item.type; if (vcdplayer_pbc_is_on(p_vcd)) { - vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->i_lid); + vcdinfo_lid_get_pxd(p_obj, &(p_vcd->pxd), p_vcd->i_lid); switch (p_vcd->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: @@ -477,10 +620,9 @@ vcdplayer_play_next( access_t * p_access ) vlc_bool_t vcdplayer_play_prev( access_t * p_access ) { - access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; - - vcdinfo_obj_t *obj = p_vcd->vcd; - vcdinfo_itemid_t itemid; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; + vcdinfo_obj_t *p_obj = p_vcd->vcd; + vcdinfo_itemid_t itemid; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), "current: %d" , p_vcd->play_item.num); @@ -489,7 +631,7 @@ vcdplayer_play_prev( access_t * p_access ) if (vcdplayer_pbc_is_on(p_vcd)) { - vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->i_lid); + vcdinfo_lid_get_pxd(p_obj, &(p_vcd->pxd), p_vcd->i_lid); switch (p_vcd->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: @@ -543,10 +685,9 @@ vcdplayer_play_prev( access_t * p_access ) vlc_bool_t vcdplayer_play_return( access_t * p_access ) { - access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; - - vcdinfo_obj_t *obj = p_vcd->vcd; - vcdinfo_itemid_t itemid; + vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; + vcdinfo_obj_t *p_obj = p_vcd->vcd; + vcdinfo_itemid_t itemid; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), "current: %d" , p_vcd->play_item.num); @@ -555,7 +696,7 @@ vcdplayer_play_return( access_t * p_access ) if (vcdplayer_pbc_is_on(p_vcd)) { - vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->i_lid); + vcdinfo_lid_get_pxd(p_obj, &(p_vcd->pxd), p_vcd->i_lid); switch (p_vcd->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: diff --git a/modules/access/vcdx/vcdplayer.h b/modules/access/vcdx/vcdplayer.h index 075d28bdff..30ffffbae7 100644 --- a/modules/access/vcdx/vcdplayer.h +++ b/modules/access/vcdx/vcdplayer.h @@ -52,6 +52,17 @@ #define LOG_ERR(args...) msg_Err( p_access, args ) #define LOG_WARN(args...) msg_Warn( p_access, args ) +/*------------------------------------------------------------------ + General definitions and structures. +---------------------------------------------------------------------*/ + +#define VCDPLAYER_IN_STILL 65535 + +typedef struct { + lsn_t start_LSN; /* LSN where play item starts */ + size_t size; /* size in sector units of play item. */ +} vcdplayer_play_item_info_t; + /* vcdplayer_read return status */ typedef enum { READ_BLOCK, @@ -61,7 +72,7 @@ typedef enum { } vcdplayer_read_status_t; /***************************************************************************** - * access_vcd_data_t: VCD information + * vcdplayer_t: VCD information *****************************************************************************/ typedef struct thread_vcd_data_s { @@ -70,8 +81,6 @@ typedef struct thread_vcd_data_s /* Current State: position */ int i_debug; /* Debugging mask */ vlc_bool_t in_still; /* true if in still */ - vcdinfo_itemid_t play_item; /* play-item, VCDPLAYER_BAD_ENTRY - if none */ int i_lid; /* LID that play item is in. Implies PBC is on. VCDPLAYER_BAD_ENTRY if not none or not in PBC */ @@ -79,6 +88,8 @@ typedef struct thread_vcd_data_s PSD/PLD */ int pdi; /* current pld index of pxd. -1 if no index*/ + vcdinfo_itemid_t play_item; /* play-item, VCDPLAYER_BAD_ENTRY + if none */ vcdinfo_itemid_t loop_item; /* Where do we loop back to? Meaningful only in a selection list */ @@ -90,7 +101,10 @@ typedef struct thread_vcd_data_s lsn_t end_lsn; /* LSN of end of current entry/segment/track. */ lsn_t origin_lsn; /* LSN of start of seek/slider */ - + lsn_t track_lsn; /* LSN of start track origin of track + we are in. */ + lsn_t track_end_lsn; /* LSN of end of current track (if + entry). */ lsn_t * p_entries; /* Entry points */ lsn_t * p_segments; /* Segments */ vlc_bool_t b_valid_ep; /* Valid entry points flag */ @@ -109,6 +123,13 @@ typedef struct thread_vcd_data_s unsigned int i_segments; /* # of segments */ unsigned int i_entries; /* # of entries */ unsigned int i_lids; /* # of List IDs */ + + /* Tracks, segment, and entry information. The number of entries for + each is given by the corresponding num_* field above. */ + vcdplayer_play_item_info_t *track; + vcdplayer_play_item_info_t *segment; + vcdplayer_play_item_info_t *entry; + unsigned int i_titles; /* # of navigatable titles. */ input_title_t *p_title[CDIO_CD_MAX_TRACKS]; @@ -120,7 +141,7 @@ typedef struct thread_vcd_data_s vlc_bool_t b_end_of_cell; input_thread_t *p_input; -} access_vcd_data_t; +} vcdplayer_t; /*! Get the next play-item in the list given in the LIDs. Note play-item @@ -133,7 +154,7 @@ vlc_bool_t vcdplayer_inc_play_item( access_t *p_access ); /*! Return true if playback control (PBC) is on */ -vlc_bool_t vcdplayer_pbc_is_on(const access_vcd_data_t *p_this); +vlc_bool_t vcdplayer_pbc_is_on(const vcdplayer_t *p_this); /*! Play item assocated with the "default" selection. @@ -164,6 +185,13 @@ vlc_bool_t vcdplayer_play_prev( access_t * p_access ); vlc_bool_t vcdplayer_play_return( access_t * p_access ); +/* + Set's start origin and size for subsequent seeks. + input: p_vcd->i_lsn, p_vcd->play_item + changed: p_vcd->origin_lsn, p_vcd->end_lsn +*/ +void vcdplayer_set_origin(access_t * p_access); + vcdplayer_read_status_t vcdplayer_pbc_nav ( access_t * p_access ); vcdplayer_read_status_t vcdplayer_non_pbc_nav ( access_t * p_access ); -- 2.39.2