From e2bc9a538ea717487c2ccf7e7f1d55c95721feda Mon Sep 17 00:00:00 2001 From: Rocky Bernstein Date: Wed, 22 Dec 2004 11:18:11 +0000 Subject: [PATCH] More segment playing improvements, be able to map seekpoints to segments and lids. Fill out vcdplayer a little more for use later. --- modules/access/vcdx/access.c | 31 ++++++-- modules/access/vcdx/info.c | 2 +- modules/access/vcdx/vcdplayer.c | 130 +++++++++++++++++++++++++++++++- 3 files changed, 152 insertions(+), 11 deletions(-) diff --git a/modules/access/vcdx/access.c b/modules/access/vcdx/access.c index a20c745e16..c2770a0577 100644 --- a/modules/access/vcdx/access.c +++ b/modules/access/vcdx/access.c @@ -863,11 +863,12 @@ VCDSetOrigin( access_t *p_access, lsn_t i_lsn, track_t i_track, "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 seepoints. + the entry seekpoints and (zeroed) lid seekpoints. */ p_access->info.i_title = p_vcd->i_titles - 1; p_access->info.i_size = 150 * M2F2_SECTOR_SIZE; - p_access->info.i_seekpoint = p_vcd->i_entries + p_itemid->num; + p_access->info.i_seekpoint = p_vcd->i_entries + + p_vcd->i_lids + p_itemid->num; } @@ -1303,22 +1304,38 @@ static int VCDControl( access_t *p_access, int i_query, va_list args ) case ACCESS_SET_SEEKPOINT: { input_title_t *t = p_vcd->p_title[p_access->info.i_title]; - i = (int)va_arg( args, int ); + unsigned int i = (unsigned int)va_arg( args, unsigned int ); dbg_print( INPUT_DBG_EVENT, "set seekpoint %d", i ); if( t->i_seekpoint > 0 ) { track_t i_track = p_access->info.i_title+1; - + lsn_t lsn; + /* FIXME! For now we are assuming titles are only tracks and that track == title+1 and we the play item is entries (not tracks or lids). We need to generalize all of this. */ - p_vcd->play_item.num = i; - p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; - + if (i < p_vcd->i_entries) + { + p_vcd->play_item.num = i; + p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; + lsn = vcdinfo_get_entry_lba(p_vcd->vcd, i); + } else if ( i < p_vcd->i_entries + p_vcd->i_lids ) + { + p_vcd->play_item.num = i = i - p_vcd->i_entries; + p_vcd->play_item.type = VCDINFO_ITEM_TYPE_LID; + lsn = 0; + } else + { + p_vcd->play_item.num = i = i - p_vcd->i_entries + - p_vcd->i_lids; + p_vcd->play_item.type = VCDINFO_ITEM_TYPE_SEGMENT; + lsn = vcdinfo_get_seg_lsn(p_vcd->vcd, i); + } + VCDSetOrigin( p_access, vcdinfo_get_entry_lba(p_vcd->vcd, i), i_track, &(p_vcd->play_item) ); diff --git a/modules/access/vcdx/info.c b/modules/access/vcdx/info.c index e18281a40b..6213c48ee8 100644 --- a/modules/access/vcdx/info.c +++ b/modules/access/vcdx/info.c @@ -71,7 +71,7 @@ VCDMetaInfo( access_t *p_access, /*const*/ char *psz_mrl ) char *psz_cat; track_t i_track; - psz_cat = _("General"); + psz_cat = _("Disc"); addstr( _("VCD Format"), vcdinfo_get_format_version_str(p_vcd->vcd) ); addstr( _("Album"), vcdinfo_get_album_id(p_vcd->vcd)); diff --git a/modules/access/vcdx/vcdplayer.c b/modules/access/vcdx/vcdplayer.c index 0b1d5ed220..8e25b69618 100644 --- a/modules/access/vcdx/vcdplayer.c +++ b/modules/access/vcdx/vcdplayer.c @@ -111,7 +111,7 @@ vcdplayer_update_entry( access_t * p_access, uint16_t ofs, return VLC_TRUE if the caller should return. */ vcdplayer_read_status_t -vcdplayer_non_pbc_nav ( access_t * p_access ) +vcdplayer_non_pbc_nav ( access_t *p_access ) { vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; @@ -154,7 +154,7 @@ vcdplayer_non_pbc_nav ( access_t * p_access ) return READ_BLOCK; } -#if FINISHED +#if 1 /*! Set reading to play an entire track. */ @@ -249,6 +249,87 @@ _vcdplayer_set_segment(access_t * p_access, unsigned int num) dbg_print(INPUT_DBG_LSN, "LSN: %u\n", p_vcd->i_lsn); } } + +/* Play entry. */ +/* Play a single item. */ +static void +vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid) +{ + vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; + vcdinfo_obj_t *p_obj = p_vcd->vcd; + + dbg_print(INPUT_DBG_CALL, "called itemid.num: %d, itemid.type: %d\n", + itemid.num, itemid.type); + + p_vcd->in_still = 0; + + switch (itemid.type) { + case VCDINFO_ITEM_TYPE_SEGMENT: + { + vcdinfo_video_segment_type_t segtype + = vcdinfo_get_video_type(p_obj, itemid.num); + segnum_t num_segs = vcdinfo_get_num_segments(p_obj); + + dbg_print(INPUT_DBG_PBC, "%s (%d), itemid.num: %d\n", + vcdinfo_video_type2str(p_obj, itemid.num), + (int) segtype, itemid.num); + + if (itemid.num >= num_segs) return; + _vcdplayer_set_segment(p_access, itemid.num); + + switch (segtype) + { + case VCDINFO_FILES_VIDEO_NTSC_STILL: + case VCDINFO_FILES_VIDEO_NTSC_STILL2: + case VCDINFO_FILES_VIDEO_PAL_STILL: + case VCDINFO_FILES_VIDEO_PAL_STILL2: + p_vcd->in_still = -5; + break; + default: + p_vcd->in_still = 0; + } + + break; + } + + case VCDINFO_ITEM_TYPE_TRACK: + dbg_print(INPUT_DBG_PBC, "track %d\n", itemid.num); + if (itemid.num < 1 || itemid.num > p_vcd->i_tracks) return; + _vcdplayer_set_track(p_access, itemid.num); + break; + + case VCDINFO_ITEM_TYPE_ENTRY: + { + unsigned int num_entries = vcdinfo_get_num_entries(p_obj); + dbg_print(INPUT_DBG_PBC, "entry %d\n", itemid.num); + if (itemid.num >= num_entries) return; + _vcdplayer_set_entry(p_access, itemid.num); + break; + } + + case VCDINFO_ITEM_TYPE_LID: + LOG_ERR("%s\n", _("Should have converted p_vcd above")); + break; + + case VCDINFO_ITEM_TYPE_NOTFOUND: + dbg_print(INPUT_DBG_PBC, "play nothing\n"); + p_vcd->i_lsn = p_vcd->end_lsn; + return; + + default: + LOG_ERR("item type %d not implemented.\n", itemid.type); + return; + } + + p_vcd->play_item = itemid; + + /* Some players like xine, have a fifo queue of audio and video buffers + that need to be flushed when playing a new selection. */ + /* if (p_vcd->flush_buffers) + p_vcd->flush_buffers(); */ + +} + #endif /* FINISHED */ /* @@ -256,6 +337,8 @@ _vcdplayer_set_segment(access_t * p_access, unsigned int num) input: p_vcd->i_lsn, p_vcd->play_item changed: p_vcd->origin_lsn, p_vcd->end_lsn */ + +/* FIXME: add parameters lsn, i_track, p_itemid and set accordingly. */ void vcdplayer_set_origin(access_t *p_access) { @@ -268,6 +351,47 @@ vcdplayer_set_origin(access_t *p_access) dbg_print((INPUT_DBG_CALL|INPUT_DBG_LSN), "end LSN: %u\n", p_vcd->end_lsn); } +/* + Get the next play-item in the list given in the LIDs. Note play-item + here refers to list of play-items for a single LID It shouldn't be + confused with a user's list of favorite things to play or the + "next" field of a LID which moves us to a different LID. + */ +static bool +_vcdplayer_inc_play_item(access_t *p_access) +{ + vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; + int noi; + + dbg_print(INPUT_DBG_CALL, "called pli: %d\n", p_vcd->pdi); + + if ( NULL == p_vcd || NULL == p_vcd->pxd.pld ) return false; + + noi = vcdinf_pld_get_noi(p_vcd->pxd.pld); + + if ( noi <= 0 ) return false; + + /* Handle delays like autowait or wait here? */ + + p_vcd->pdi++; + + if ( p_vcd->pdi < 0 || p_vcd->pdi >= noi ) return false; + + else { + uint16_t trans_itemid_num=vcdinf_pld_get_play_item(p_vcd->pxd.pld, + p_vcd->pdi); + vcdinfo_itemid_t trans_itemid; + + if (VCDINFO_INVALID_ITEMID == trans_itemid_num) return false; + + vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid); + dbg_print(INPUT_DBG_PBC, " play-item[%d]: %s\n", + p_vcd->pdi, vcdinfo_pin2str (trans_itemid_num)); + vcdplayer_play_single_item(p_access, trans_itemid); + return true; + } +} + /* Handles PBC navigation when reaching the end of a play item. */ vcdplayer_read_status_t vcdplayer_pbc_nav ( access_t * p_access ) @@ -450,7 +574,7 @@ vcdplayer_play_default( access_t * p_access ) { vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; - vcdinfo_itemid_t itemid; + vcdinfo_itemid_t itemid; if (!p_vcd) { dbg_print( (INPUT_DBG_CALL|INPUT_DBG_PBC), -- 2.39.5