Commit d6b04c78 authored by Rocky Bernstein's avatar Rocky Bernstein

Fill out more VCD player-independent parts. Modal (track, segment,

entry) playing is better. 

Still frame and menu selection is still quite a mess. 
parent 89885149
...@@ -47,6 +47,9 @@ ...@@ -47,6 +47,9 @@
#define FREE_AND_NULL(ptr) if (NULL != ptr) free(ptr); ptr = NULL; #define FREE_AND_NULL(ptr) if (NULL != ptr) free(ptr); ptr = NULL;
extern void VCDSetOrigin( access_t *p_access, lsn_t i_lsn, track_t i_track,
const vcdinfo_itemid_t *p_itemid );
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -58,16 +61,10 @@ static int VCDControl ( access_t *p_access, int i_query, ...@@ -58,16 +61,10 @@ static int VCDControl ( access_t *p_access, int i_query,
va_list args ); va_list args );
/* Now those which are strictly internal */ /* Now those which are strictly internal */
static void VCDSetOrigin ( access_t *p_access, lsn_t i_lsn,
track_t track,
const vcdinfo_itemid_t * p_itemid );
static vlc_bool_t VCDEntryPoints ( access_t * ); static vlc_bool_t VCDEntryPoints ( access_t * );
static vlc_bool_t VCDLIDs ( access_t * ); static vlc_bool_t VCDLIDs ( access_t * );
static vlc_bool_t VCDSegments ( access_t * ); static vlc_bool_t VCDSegments ( access_t * );
static int VCDTitles ( access_t * ); static int VCDTitles ( access_t * );
static int VCDReadSector ( vlc_object_t *p_this,
const vcdinfo_obj_t *p_vcd, lsn_t i_lsn,
byte_t * p_buffer );
static char *VCDParse ( access_t *, static char *VCDParse ( access_t *,
/*out*/ vcdinfo_itemid_t * p_itemid , /*out*/ vcdinfo_itemid_t * p_itemid ,
/*out*/ vlc_bool_t *play_single_item ); /*out*/ vlc_bool_t *play_single_item );
...@@ -150,14 +147,11 @@ VCDReadBlock( access_t * p_access ) ...@@ -150,14 +147,11 @@ VCDReadBlock( access_t * p_access )
block_t *p_block; block_t *p_block;
const int i_blocks = p_vcd->i_blocks_per_read; const int i_blocks = p_vcd->i_blocks_per_read;
int i_read; int i_read;
byte_t p_last_sector[ M2F2_SECTOR_SIZE ];
i_read = 0; i_read = 0;
#if 0 dbg_print( (INPUT_DBG_LSN), "lsn: %lu",
dbg_print( (INPUT_DBG_CALL), "lsn: %lu",
(long unsigned int) p_vcd->i_lsn ); (long unsigned int) p_vcd->i_lsn );
#endif
/* Allocate a block for the reading */ /* Allocate a block for the reading */
if( !( p_block = block_New( p_access, i_blocks * M2F2_SECTOR_SIZE ) ) ) if( !( p_block = block_New( p_access, i_blocks * M2F2_SECTOR_SIZE ) ) )
...@@ -170,95 +164,60 @@ VCDReadBlock( access_t * p_access ) ...@@ -170,95 +164,60 @@ VCDReadBlock( access_t * p_access )
for ( i_read = 0 ; i_read < i_blocks ; i_read++ ) for ( i_read = 0 ; i_read < i_blocks ; i_read++ )
{ {
const lsn_t old_lsn = p_vcd->i_lsn;
if ( p_vcd->i_lsn >= p_vcd->end_lsn ) { switch ( vcdplayer_read(p_access, (byte_t *) p_block->p_buffer
vcdplayer_read_status_t read_status; + (i_read*M2F2_SECTOR_SIZE)) ) {
case READ_END:
/* We've run off of the end of this entry. Do we continue or stop? */ /* End reached. Return NULL to indicated this. */
dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), block_Release( p_block );
"end reached, cur: %lu, end: %u", return NULL;
(long unsigned int) p_vcd->i_lsn, case READ_ERROR:
p_vcd->end_lsn); /* Some sort of error. Should we increment lsn? to skip block?
*/
read_status = vcdplayer_pbc_is_on( p_vcd ) block_Release( p_block );
? vcdplayer_pbc_nav( p_access ) return NULL;
: vcdplayer_non_pbc_nav( p_access ); case READ_STILL_FRAME:
{
switch (read_status) { dbg_print(INPUT_DBG_STILL, "Handled still event\n");
case READ_END: /* Reached the end of a still frame. */
/* End reached. Return NULL to indicated this. */ byte_t * p_buf = (byte_t *) p_block->p_buffer;
case READ_ERROR:
/* Some sort of error. */ p_buf += (i_read*M2F2_SECTOR_SIZE);
return NULL; memset(p_buf, 0, M2F2_SECTOR_SIZE);
p_buf += 2;
case READ_STILL_FRAME: *p_buf = 0x01;
{ dbg_print(INPUT_DBG_STILL, "Handled still event");
/* Reached the end of a still frame. */
byte_t * p_buf = (byte_t *) p_block->p_buffer; p_vcd->in_still = VLC_TRUE;
var_SetInteger( p_access, "state", PAUSE_S );
p_buf += (i_read*M2F2_SECTOR_SIZE);
memset(p_buf, 0, M2F2_SECTOR_SIZE); return p_block;
p_buf += 2; }
*p_buf = 0x01;
dbg_print(INPUT_DBG_STILL, "Handled still event"); default:
case READ_BLOCK:
p_vcd->in_still = VLC_TRUE; /* Read buffer */
var_SetInteger( p_access, "state", PAUSE_S ); ;
return p_block;
}
default:
case READ_BLOCK:
break;
}
}
if ( VCDReadSector( VLC_OBJECT(p_access), p_vcd->vcd,
p_vcd->i_lsn,
(byte_t *) p_block->p_buffer
+ (i_read*M2F2_SECTOR_SIZE) ) < 0 )
{
LOG_ERR ("could not read sector %lu",
(long unsigned int) p_vcd->i_lsn );
/* Try to skip one sector (in case of bad sectors) */
p_vcd->i_lsn ++;
p_access->info.i_pos += M2F2_SECTOR_SIZE;
return NULL;
} }
p_vcd->i_lsn ++; p_access->info.i_pos += (p_vcd->i_lsn - old_lsn) * M2F2_SECTOR_SIZE;
p_access->info.i_pos += M2F2_SECTOR_SIZE;
/* Update seekpoint */ /* Update seekpoint */
if ( VCDINFO_ITEM_TYPE_ENTRY == p_vcd->play_item.type ) if ( VCDINFO_ITEM_TYPE_ENTRY == p_vcd->play_item.type )
{ {
unsigned int i_entry = p_vcd->play_item.num+1; unsigned int i_entry = p_vcd->play_item.num+1;
lsn_t i_lsn = vcdinfo_get_entry_lba(p_vcd->vcd, i_entry);
if (p_vcd->i_lsn >= vcdinfo_get_entry_lba(p_vcd->vcd, i_entry)) if (p_vcd->i_lsn >= i_lsn )
{ {
const track_t i_track = p_vcd->i_track; const track_t i_track = p_vcd->i_track;
p_vcd->play_item.num = i_entry; p_vcd->play_item.num = i_entry;
dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), "entry change" ); dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), "entry change" );
VCDSetOrigin( p_access, VCDSetOrigin( p_access, i_lsn, i_track, &(p_vcd->play_item) );
vcdinfo_get_entry_lba(p_vcd->vcd, i_entry),
i_track, &(p_vcd->play_item) );
} }
} }
} }
if ( i_read != i_blocks ) /* this should not happen */
{
if ( VCDReadSector( VLC_OBJECT(p_access), p_vcd->vcd,
p_vcd->i_lsn, p_last_sector ) < 0 )
{
LOG_ERR ("could not read sector %lu",
(long unsigned int) p_vcd->i_lsn );
}
p_vcd->i_lsn ++;
return NULL;
}
return p_block; return p_block;
} }
...@@ -294,10 +253,14 @@ VCDSeek( access_t * p_access, int64_t i_pos ) ...@@ -294,10 +253,14 @@ VCDSeek( access_t * p_access, int64_t i_pos )
break; break;
} }
} }
p_vcd->play_item.num = i_entry;
p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; {
vcdplayer_set_origin(p_access); vcdinfo_itemid_t itemid;
VCDUpdateTitle(p_access); itemid.num = i_entry;
itemid.type = VCDINFO_ITEM_TYPE_ENTRY;
VCDSetOrigin(p_access, p_vcd->i_lsn, p_vcd->i_track,
&itemid);
}
} }
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK), dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK),
...@@ -327,155 +290,6 @@ VCDSeek( access_t * p_access, int64_t i_pos ) ...@@ -327,155 +290,6 @@ VCDSeek( access_t * p_access, int64_t i_pos )
} }
/*****************************************************************************
VCDPlay: set up internal structures so seeking/reading places an item.
itemid: the thing to play.
user_entry: true if itemid is a user selection (rather than internally-
generated selection such as via PBC) in which case we may have to adjust
for differences in numbering.
*****************************************************************************/
int
VCDPlay( access_t *p_access, vcdinfo_itemid_t itemid )
{
if (!p_access || !p_access->p_sys) return VLC_EGENERIC;
{
vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys;
#if 0
const vlc_bool_t b_was_still = p_vcd->in_still;
#endif
dbg_print(INPUT_DBG_CALL, "itemid.num: %d, itemid.type: %d\n",
itemid.num, itemid.type);
switch (itemid.type) {
case VCDINFO_ITEM_TYPE_TRACK:
{
track_t i_track = itemid.num;
unsigned int i_entry =
vcdinfo_track_get_entry( p_vcd->vcd, i_track);
/* Valid MPEG tracks go from 1...i_tracks. */
if (i_track == 0 || i_track > p_vcd->i_tracks) {
LOG_ERR ("Invalid track number %d", i_track );
return VLC_EGENERIC;
}
p_vcd->in_still = VLC_FALSE;
VCDSetOrigin( p_access,
vcdinfo_get_entry_lba(p_vcd->vcd, i_entry),
i_track, &itemid );
break;
}
case VCDINFO_ITEM_TYPE_SEGMENT:
{
int i_seg = itemid.num;
/* Valid segments go from 0...i_segments-1. */
if (itemid.num >= p_vcd->i_segments) {
LOG_ERR ( "Invalid segment number: %d", i_seg );
return VLC_EGENERIC;
} else {
vcdinfo_video_segment_type_t segtype =
vcdinfo_get_video_type(p_vcd->vcd, i_seg);
dbg_print(INPUT_DBG_PBC, "%s (%d), seg_num: %d",
vcdinfo_video_type2str(p_vcd->vcd, i_seg),
(int) segtype, 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 = VLC_TRUE;
break;
default:
p_vcd->in_still = VLC_FALSE;
}
VCDSetOrigin( p_access, p_vcd->p_segments[i_seg],
0, &itemid );
}
}
break;
case VCDINFO_ITEM_TYPE_LID:
/* LIDs go from 1..i_lids. */
if (itemid.num == 0 || itemid.num > p_vcd->i_lids) {
LOG_ERR ( "Invalid LID number: %d", itemid.num );
return VLC_EGENERIC;
} else {
p_vcd->i_lid = itemid.num;
vcdinfo_lid_get_pxd(p_vcd->vcd, &(p_vcd->pxd), itemid.num);
switch (p_vcd->pxd.descriptor_type) {
case PSD_TYPE_SELECTION_LIST:
case PSD_TYPE_EXT_SELECTION_LIST: {
vcdinfo_itemid_t trans_itemid;
uint16_t trans_itemid_num;
if (p_vcd->pxd.psd == NULL) return VLC_EGENERIC;
trans_itemid_num = vcdinf_psd_get_itemid(p_vcd->pxd.psd);
vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid);
p_vcd->loop_count = 1;
p_vcd->loop_item = trans_itemid;
return VCDPlay( p_access, trans_itemid );
break;
}
case PSD_TYPE_PLAY_LIST: {
if (p_vcd->pxd.pld == NULL) return VLC_EGENERIC;
p_vcd->pdi = -1;
return vcdplayer_inc_play_item(p_access)
? VLC_SUCCESS : VLC_EGENERIC;
break;
}
case PSD_TYPE_END_LIST:
case PSD_TYPE_COMMAND_LIST:
default:
;
}
}
return VLC_EGENERIC;
case VCDINFO_ITEM_TYPE_ENTRY:
{
int i_entry = itemid.num;
/* Entries go from 0..i_entries-1. */
if (itemid.num >= p_vcd->i_entries) {
LOG_ERR ("Invalid entry number: %d", i_entry );
return VLC_EGENERIC;
} else {
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_entry),
i_track, &itemid );
}
break;
}
default:
LOG_ERR ("unknown entry type" );
return VLC_EGENERIC;
}
p_vcd->play_item = itemid;
}
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
VCDEntryPoints: Reads the information about the entry points on the disc VCDEntryPoints: Reads the information about the entry points on the disc
and initializes area information with that. and initializes area information with that.
...@@ -526,7 +340,7 @@ VCDEntryPoints( access_t * p_access ) ...@@ -526,7 +340,7 @@ VCDEntryPoints( access_t * p_access )
* M2F2_SECTOR_SIZE; * M2F2_SECTOR_SIZE;
dbg_print( INPUT_DBG_MRL, dbg_print( INPUT_DBG_MRL,
"%s, lsn %d, byte_offset %ld\n", "%s, lsn %d, byte_offset %ld",
s->psz_name, p_vcd->p_entries[i], s->psz_name, p_vcd->p_entries[i],
(unsigned long int) s->i_byte_offset); (unsigned long int) s->i_byte_offset);
TAB_APPEND( p_vcd->p_title[i_track-1]->i_seekpoint, TAB_APPEND( p_vcd->p_title[i_track-1]->i_seekpoint,
...@@ -553,7 +367,7 @@ VCDSegments( access_t * p_access ) ...@@ -553,7 +367,7 @@ VCDSegments( access_t * p_access )
p_vcd->i_segments = vcdinfo_get_num_segments(p_vcd->vcd); p_vcd->i_segments = vcdinfo_get_num_segments(p_vcd->vcd);
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL), dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL),
"num LIDs=%d", p_vcd->i_segments); "Segments: %d", p_vcd->i_segments);
if ( 0 == p_vcd->i_segments ) return VLC_FALSE; if ( 0 == p_vcd->i_segments ) return VLC_FALSE;
...@@ -652,7 +466,7 @@ VCDLIDs( access_t * p_access ) ...@@ -652,7 +466,7 @@ VCDLIDs( access_t * p_access )
p_vcd->i_lid = VCDINFO_INVALID_ENTRY; p_vcd->i_lid = VCDINFO_INVALID_ENTRY;
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL), dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL),
"num LIDs=%d", p_vcd->i_lids); "LIDs: %d", p_vcd->i_lids);
if ( 0 == p_vcd->i_lids ) return VLC_FALSE; if ( 0 == p_vcd->i_lids ) return VLC_FALSE;
...@@ -826,51 +640,57 @@ VCDParse( access_t * p_access, /*out*/ vcdinfo_itemid_t * p_itemid, ...@@ -826,51 +640,57 @@ VCDParse( access_t * p_access, /*out*/ vcdinfo_itemid_t * p_itemid,
/* /*
Set's start origin subsequent seeks/reads Set's start origin subsequent seeks/reads
*/ */
static void void
VCDSetOrigin( access_t *p_access, lsn_t i_lsn, track_t i_track, VCDSetOrigin( access_t *p_access, lsn_t i_lsn, track_t i_track,
const vcdinfo_itemid_t *p_itemid ) const vcdinfo_itemid_t *p_itemid )
{ {
vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys; vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys;
unsigned int i_title = i_track - 1; /* For now */
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN), dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN),
"i_lsn: %lu, track: %d", (long unsigned int) i_lsn, "i_lsn: %lu, track: %d", (long unsigned int) i_lsn,
i_track ); i_track );
p_vcd->i_lsn = i_lsn; vcdplayer_set_origin(p_access, i_lsn, i_track, p_itemid);
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_pos = ( i_lsn - p_vcd->track_lsn ) p_access->info.i_pos = ( i_lsn - p_vcd->track_lsn )
* M2F2_SECTOR_SIZE; * M2F2_SECTOR_SIZE;
p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE
| INPUT_UPDATE_SEEKPOINT; | INPUT_UPDATE_SEEKPOINT;
if (p_itemid->type == VCDINFO_ITEM_TYPE_ENTRY) {
VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, switch (p_vcd->play_item.type) {
"chapter", _("Entry"), "Setting entry/segment"); case VCDINFO_ITEM_TYPE_ENTRY:
p_access->info.i_title = i_track-1; VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE,
p_access->info.i_size = p_vcd->p_title[i_title]->i_size; "chapter", _("Entry"), "Setting entry/segment");
p_access->info.i_seekpoint = p_itemid->num; p_access->info.i_title = i_track-1;
} else if (p_itemid->type == VCDINFO_ITEM_TYPE_SEGMENT) { p_access->info.i_size = p_vcd->p_title[i_track-1]->i_size;
VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, 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"); "chapter", _("Segment"), "Setting entry/segment");
/* The last title entry is the for segments (when segments exist /* The last title entry is the for segments (when segments exist
and they must here. The segment seekpoints are stored after and they must here. The segment seekpoints are stored after
the entry seekpoints and (zeroed) lid seekpoints. the entry seekpoints and (zeroed) lid seekpoints.
*/ */
p_access->info.i_title = p_vcd->i_titles - 1; p_access->info.i_title = p_vcd->i_titles - 1;
p_access->info.i_size = 150 * M2F2_SECTOR_SIZE; p_access->info.i_size = 150 * M2F2_SECTOR_SIZE;
p_access->info.i_seekpoint = p_vcd->i_entries p_access->info.i_seekpoint = p_vcd->i_entries
+ p_vcd->i_lids + p_itemid->num; + p_vcd->i_lids + p_itemid->num;
break;
case VCDINFO_ITEM_TYPE_TRACK:
p_access->info.i_title = i_track-1;
p_access->info.i_size = p_vcd->p_title[i_track-1]->i_size;
p_access->info.i_seekpoint = vcdinfo_track_get_entry(p_vcd->vcd,
i_track);
break;
default:
msg_Warn( p_access, "can't set origin for play type %d",
p_vcd->play_item.type );
} }
VCDUpdateTitle( p_access ); VCDUpdateTitle( p_access );
...@@ -889,7 +709,7 @@ vcd_Open( vlc_object_t *p_this, const char *psz_dev ) ...@@ -889,7 +709,7 @@ vcd_Open( vlc_object_t *p_this, const char *psz_dev )
char *actual_dev; char *actual_dev;
unsigned int i; unsigned int i;
dbg_print(INPUT_DBG_CALL, "called with %s\n", psz_dev); dbg_print(INPUT_DBG_CALL, "called with %s", psz_dev);
if( !psz_dev ) return NULL; if( !psz_dev ) return NULL;
...@@ -945,34 +765,6 @@ vcd_Open( vlc_object_t *p_this, const char *psz_dev ) ...@@ -945,34 +765,6 @@ vcd_Open( vlc_object_t *p_this, const char *psz_dev )
return p_vcdobj; return p_vcdobj;
} }
/****************************************************************************
* VCDReadSector: Read a sector (2324 bytes)
****************************************************************************/
static int
VCDReadSector( vlc_object_t *p_this, const vcdinfo_obj_t *p_vcd,
lsn_t i_lsn, byte_t * p_buffer )
{
typedef struct {
uint8_t subheader [CDIO_CD_SUBHEADER_SIZE];
uint8_t data [M2F2_SECTOR_SIZE];
uint8_t spare [4];
} vcdsector_t;
vcdsector_t vcd_sector;
if( cdio_read_mode2_sector( vcdinfo_get_cd_image( p_vcd ),
&vcd_sector, i_lsn, VLC_TRUE )
!= 0)
{
msg_Warn( p_this, "Could not read LSN %lu",
(long unsigned int) i_lsn );
return -1;
}
memcpy (p_buffer, vcd_sector.data, M2F2_SECTOR_SIZE);
return( 0 );
}
/**************************************************************************** /****************************************************************************
Update the "varname" variable to i_num without triggering a callback. Update the "varname" variable to i_num without triggering a callback.
****************************************************************************/ ****************************************************************************/
...@@ -1016,7 +808,6 @@ E_(VCDOpen) ( vlc_object_t *p_this ) ...@@ -1016,7 +808,6 @@ E_(VCDOpen) ( vlc_object_t *p_this )
vcdplayer_t *p_vcd; vcdplayer_t *p_vcd;
char *psz_source; char *psz_source;
vcdinfo_itemid_t itemid; vcdinfo_itemid_t itemid;
vlc_bool_t b_play_ok;
vlc_bool_t play_single_item = VLC_FALSE; vlc_bool_t play_single_item = VLC_FALSE;
p_access->pf_read = NULL; p_access->pf_read = NULL;
...@@ -1105,15 +896,16 @@ E_(VCDOpen) ( vlc_object_t *p_this ) ...@@ -1105,15 +896,16 @@ E_(VCDOpen) ( vlc_object_t *p_this )
msg_Warn( p_access, "could not read entry LIDs" ); msg_Warn( p_access, "could not read entry LIDs" );
} }
/* Do we set PBC (via LID) on? */
p_vcd->i_lid =
( VCDINFO_ITEM_TYPE_LID == itemid.type && p_vcd->i_lids > itemid.num )
? itemid.num
: VCDINFO_INVALID_ENTRY;
/* Initialize segment information and add that a "Track". */ /* Initialize segment information and add that a "Track". */
VCDSegments( p_access ); VCDSegments( p_access );
b_play_ok = (VLC_SUCCESS == VCDPlay( p_access, itemid )); vcdplayer_play( p_access, itemid );
if ( ! b_play_ok ) {
vcdinfo_close( p_vcd->vcd );
goto err_exit;
}
p_access->psz_demux = strdup( "ps" ); p_access->psz_demux = strdup( "ps" );
......
...@@ -47,6 +47,9 @@ ...@@ -47,6 +47,9 @@
#define sleep(A) Sleep((A)*1000) #define sleep(A) Sleep((A)*1000)
#endif #endif
extern void VCDSetOrigin ( access_t *p_access, lsn_t i_lsn, track_t i_track,
const vcdinfo_itemid_t * p_itemid );
/*! /*!
Return VLC_TRUE if playback control (PBC) is on Return VLC_TRUE if playback control (PBC) is on
*/ */
...@@ -80,7 +83,7 @@ vcdplayer_get_item_size(access_t * p_access, vcdinfo_itemid_t itemid) ...@@ -80,7 +83,7 @@ vcdplayer_get_item_size(access_t * p_access, vcdinfo_itemid_t itemid)
case VCDINFO_ITEM_TYPE_NOTFOUND: case VCDINFO_ITEM_TYPE_NOTFOUND:
case VCDINFO_ITEM_TYPE_SPAREID2: case VCDINFO_ITEM_TYPE_SPAREID2:
default: default:
LOG_ERR("%s %d\n", _("bad item type"), itemid.type); LOG_ERR("%s %d", _("bad item type"), itemid.type);
return 0; return 0;
} }
} }
...@@ -97,7 +100,7 @@ vcdplayer_update_entry( access_t * p_access, uint16_t ofs, ...@@ -97,7 +100,7 @@ vcdplayer_update_entry( access_t * p_access, uint16_t ofs,
vcdinfo_offset_t *off = vcdinfo_get_offset_t(p_vcd->vcd, ofs); vcdinfo_offset_t *off = vcdinfo_get_offset_t(p_vcd->vcd, ofs);
if (off != NULL) { if (off != NULL) {
*entry = off->lid; *entry = off->lid;
dbg_print(INPUT_DBG_PBC, "%s: LID %d\n", label, off->lid); dbg_print(INPUT_DBG_PBC, "%s: LID %d", label, off->lid);
} else } else
*entry = VCDINFO_INVALID_ENTRY; *entry = VCDINFO_INVALID_ENTRY;
} }
...@@ -119,10 +122,10 @@ vcdplayer_non_pbc_nav ( access_t *p_access ) ...@@ -119,10 +122,10 @@ vcdplayer_non_pbc_nav ( access_t *p_access )
switch (p_vcd->play_item.type) { switch (p_vcd->play_item.type) {
case VCDINFO_ITEM_TYPE_TRACK: case VCDINFO_ITEM_TYPE_TRACK:
case VCDINFO_ITEM_TYPE_ENTRY: { case VCDINFO_ITEM_TYPE_ENTRY: {
if ( ! vcdplayer_play_next( p_access ) )
dbg_print( INPUT_DBG_LSN, "new track %d, lsn %d", p_vcd->i_track+1, {
vcdinfo_get_track_lsn(p_vcd->vcd, p_vcd->i_track+1) ); return READ_END;
return READ_END; }
break; break;
} }
case VCDINFO_ITEM_TYPE_SPAREID2: case VCDINFO_ITEM_TYPE_SPAREID2:
...@@ -154,7 +157,6 @@ vcdplayer_non_pbc_nav ( access_t *p_access ) ...@@ -154,7 +157,6 @@ vcdplayer_non_pbc_nav ( access_t *p_access )
return READ_BLOCK; return READ_BLOCK;
} }
#if 1
/*! /*!
Set reading to play an entire track. Set reading to play an entire track.
*/ */
...@@ -171,14 +173,11 @@ _vcdplayer_set_track(access_t * p_access, track_t i_track) ...@@ -171,14 +173,11 @@ _vcdplayer_set_track(access_t * p_access, track_t i_track)
itemid.num = i_track; itemid.num = i_track;
itemid.type = VCDINFO_ITEM_TYPE_TRACK; itemid.type = VCDINFO_ITEM_TYPE_TRACK;
p_vcd->in_still = 0; 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); VCDSetOrigin(p_access, vcdinfo_get_track_lsn(p_obj, i_track),
i_track, &itemid);
dbg_print(INPUT_DBG_LSN, "LSN: %u\n", p_vcd->i_lsn); dbg_print(INPUT_DBG_LSN, "LSN: %u", p_vcd->i_lsn);
} }
} }
...@@ -193,7 +192,7 @@ _vcdplayer_set_entry(access_t * p_access, unsigned int num) ...@@ -193,7 +192,7 @@ _vcdplayer_set_entry(access_t * p_access, unsigned int num)
unsigned int num_entries = vcdinfo_get_num_entries(p_obj); unsigned int num_entries = vcdinfo_get_num_entries(p_obj);
if (num >= num_entries) { if (num >= num_entries) {
LOG_ERR("%s %d\n", _("bad entry number"), num); LOG_ERR("%s %d", _("bad entry number"), num);
return; return;
} else { } else {
vcdinfo_itemid_t itemid; vcdinfo_itemid_t itemid;
...@@ -201,16 +200,11 @@ _vcdplayer_set_entry(access_t * p_access, unsigned int num) ...@@ -201,16 +200,11 @@ _vcdplayer_set_entry(access_t * p_access, unsigned int num)
itemid.num = num; itemid.num = num;
itemid.type = VCDINFO_ITEM_TYPE_ENTRY; itemid.type = VCDINFO_ITEM_TYPE_ENTRY;
p_vcd->in_still = 0; 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); VCDSetOrigin(p_access, vcdinfo_get_entry_lba(p_obj, num),
vcdinfo_get_track(p_obj, num), &itemid);
dbg_print(INPUT_DBG_LSN, "LSN: %u, track_end LSN: %u\n", dbg_print(INPUT_DBG_LSN, "LSN: %u, track_end LSN: %u",
p_vcd->i_lsn, p_vcd->track_end_lsn); p_vcd->i_lsn, p_vcd->track_end_lsn);
} }
} }
...@@ -226,27 +220,23 @@ _vcdplayer_set_segment(access_t * p_access, unsigned int num) ...@@ -226,27 +220,23 @@ _vcdplayer_set_segment(access_t * p_access, unsigned int num)
segnum_t num_segs = vcdinfo_get_num_segments(p_obj); segnum_t num_segs = vcdinfo_get_num_segments(p_obj);
if (num >= num_segs) { if (num >= num_segs) {
LOG_ERR("%s %d\n", _("bad segment number"), num); LOG_ERR("%s %d", _("bad segment number"), num);
return; return;
} else { } else {
vcdinfo_itemid_t itemid; 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) { if (VCDINFO_NULL_LSN==p_vcd->i_lsn) {
LOG_ERR("%s %d\n", LOG_ERR("%s %d",
_("Error in getting current segment number"), num); _("Error in getting current segment number"), num);
return; return;
} }
itemid.num = num; itemid.num = num;
itemid.type = VCDINFO_ITEM_TYPE_SEGMENT; itemid.type = VCDINFO_ITEM_TYPE_SEGMENT;
p_vcd->play_item = itemid;
vcdplayer_set_origin(p_access); VCDSetOrigin(p_access, vcdinfo_get_seg_lsn(p_obj, num), 0, &itemid);
dbg_print(INPUT_DBG_LSN, "LSN: %u\n", p_vcd->i_lsn); dbg_print(INPUT_DBG_LSN, "LSN: %u", p_vcd->i_lsn);
} }
} }
...@@ -258,7 +248,7 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid) ...@@ -258,7 +248,7 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid)
vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys;
vcdinfo_obj_t *p_obj = p_vcd->vcd; vcdinfo_obj_t *p_obj = p_vcd->vcd;
dbg_print(INPUT_DBG_CALL, "called itemid.num: %d, itemid.type: %d\n", dbg_print(INPUT_DBG_CALL, "called itemid.num: %d, itemid.type: %d",
itemid.num, itemid.type); itemid.num, itemid.type);
p_vcd->in_still = 0; p_vcd->in_still = 0;
...@@ -270,7 +260,7 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid) ...@@ -270,7 +260,7 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid)
= vcdinfo_get_video_type(p_obj, itemid.num); = vcdinfo_get_video_type(p_obj, itemid.num);
segnum_t num_segs = vcdinfo_get_num_segments(p_obj); segnum_t num_segs = vcdinfo_get_num_segments(p_obj);
dbg_print(INPUT_DBG_PBC, "%s (%d), itemid.num: %d\n", dbg_print(INPUT_DBG_PBC, "%s (%d), itemid.num: %d",
vcdinfo_video_type2str(p_obj, itemid.num), vcdinfo_video_type2str(p_obj, itemid.num),
(int) segtype, itemid.num); (int) segtype, itemid.num);
...@@ -293,7 +283,7 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid) ...@@ -293,7 +283,7 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid)
} }
case VCDINFO_ITEM_TYPE_TRACK: case VCDINFO_ITEM_TYPE_TRACK:
dbg_print(INPUT_DBG_PBC, "track %d\n", itemid.num); dbg_print(INPUT_DBG_PBC, "track %d", itemid.num);
if (itemid.num < 1 || itemid.num > p_vcd->i_tracks) return; if (itemid.num < 1 || itemid.num > p_vcd->i_tracks) return;
_vcdplayer_set_track(p_access, itemid.num); _vcdplayer_set_track(p_access, itemid.num);
break; break;
...@@ -301,23 +291,23 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid) ...@@ -301,23 +291,23 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid)
case VCDINFO_ITEM_TYPE_ENTRY: case VCDINFO_ITEM_TYPE_ENTRY:
{ {
unsigned int num_entries = vcdinfo_get_num_entries(p_obj); unsigned int num_entries = vcdinfo_get_num_entries(p_obj);
dbg_print(INPUT_DBG_PBC, "entry %d\n", itemid.num); dbg_print(INPUT_DBG_PBC, "entry %d", itemid.num);
if (itemid.num >= num_entries) return; if (itemid.num >= num_entries) return;
_vcdplayer_set_entry(p_access, itemid.num); _vcdplayer_set_entry(p_access, itemid.num);
break; break;
} }
case VCDINFO_ITEM_TYPE_LID: case VCDINFO_ITEM_TYPE_LID:
LOG_ERR("%s\n", _("Should have converted p_vcd above")); LOG_ERR("%s", _("Should have converted p_vcd above"));
break; break;
case VCDINFO_ITEM_TYPE_NOTFOUND: case VCDINFO_ITEM_TYPE_NOTFOUND:
dbg_print(INPUT_DBG_PBC, "play nothing\n"); dbg_print(INPUT_DBG_PBC, "play nothing");
p_vcd->i_lsn = p_vcd->end_lsn; p_vcd->i_lsn = p_vcd->end_lsn;
return; return;
default: default:
LOG_ERR("item type %d not implemented.\n", itemid.type); LOG_ERR("item type %d not implemented.", itemid.type);
return; return;
} }
...@@ -327,11 +317,8 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid) ...@@ -327,11 +317,8 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid)
that need to be flushed when playing a new selection. */ that need to be flushed when playing a new selection. */
/* if (p_vcd->flush_buffers) /* if (p_vcd->flush_buffers)
p_vcd->flush_buffers(); */ p_vcd->flush_buffers(); */
} }
#endif /* FINISHED */
/* /*
Set's start origin and size for subsequent seeks. Set's start origin and size for subsequent seeks.
input: p_vcd->i_lsn, p_vcd->play_item input: p_vcd->i_lsn, p_vcd->play_item
...@@ -340,15 +327,24 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid) ...@@ -340,15 +327,24 @@ vcdplayer_play_single_item( access_t * p_access, vcdinfo_itemid_t itemid)
/* FIXME: add parameters lsn, i_track, p_itemid and set accordingly. */ /* FIXME: add parameters lsn, i_track, p_itemid and set accordingly. */
void void
vcdplayer_set_origin(access_t *p_access) vcdplayer_set_origin(access_t *p_access, lsn_t i_lsn, track_t i_track,
const vcdinfo_itemid_t *p_itemid)
{ {
vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys;
size_t i_size= vcdplayer_get_item_size(p_access, p_vcd->play_item); const size_t i_size= vcdplayer_get_item_size(p_access, *p_itemid);
p_vcd->end_lsn = p_vcd->i_lsn + i_size; p_vcd->play_item.num = p_itemid->num;
p_vcd->origin_lsn = p_vcd->i_lsn; p_vcd->play_item.type = p_itemid->type;
p_vcd->i_lsn = i_lsn;
dbg_print((INPUT_DBG_CALL|INPUT_DBG_LSN), "end LSN: %u\n", p_vcd->end_lsn); p_vcd->end_lsn = p_vcd->i_lsn + i_size;
p_vcd->origin_lsn = p_vcd->i_lsn;
p_vcd->i_track = i_track;
p_vcd->track_lsn = vcdinfo_get_track_lba(p_vcd->vcd, i_track);
dbg_print((INPUT_DBG_CALL|INPUT_DBG_LSN),
"lsn %u, end LSN: %u item.num %d, item.type %d",
p_vcd->i_lsn, p_vcd->end_lsn,
p_vcd->play_item.num, p_vcd->play_item.type);
} }
/* /*
...@@ -363,7 +359,7 @@ _vcdplayer_inc_play_item(access_t *p_access) ...@@ -363,7 +359,7 @@ _vcdplayer_inc_play_item(access_t *p_access)
vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys; vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys;
int noi; int noi;
dbg_print(INPUT_DBG_CALL, "called pli: %d\n", p_vcd->pdi); dbg_print(INPUT_DBG_CALL, "called pli: %d", p_vcd->pdi);
if ( NULL == p_vcd || NULL == p_vcd->pxd.pld ) return false; if ( NULL == p_vcd || NULL == p_vcd->pxd.pld ) return false;
...@@ -385,13 +381,65 @@ _vcdplayer_inc_play_item(access_t *p_access) ...@@ -385,13 +381,65 @@ _vcdplayer_inc_play_item(access_t *p_access)
if (VCDINFO_INVALID_ITEMID == trans_itemid_num) return false; if (VCDINFO_INVALID_ITEMID == trans_itemid_num) return false;
vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid); vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid);
dbg_print(INPUT_DBG_PBC, " play-item[%d]: %s\n", dbg_print(INPUT_DBG_PBC, " play-item[%d]: %s",
p_vcd->pdi, vcdinfo_pin2str (trans_itemid_num)); p_vcd->pdi, vcdinfo_pin2str (trans_itemid_num));
vcdplayer_play_single_item(p_access, trans_itemid); vcdplayer_play_single_item(p_access, trans_itemid);
return true; return true;
} }
} }
void
vcdplayer_play(access_t *p_access, vcdinfo_itemid_t itemid)
{
vcdplayer_t *p_vcd = (vcdplayer_t *)p_access->p_sys;
dbg_print(INPUT_DBG_CALL, "called itemid.num: %d itemid.type: %d",
itemid.num, itemid.type);
if (!vcdplayer_pbc_is_on(p_vcd)) {
vcdplayer_play_single_item(p_access, itemid);
} else {
/* PBC on - Itemid.num is LID. */
vcdinfo_obj_t *obj = p_vcd->vcd;
if (obj == NULL) return;
p_vcd->i_lid = itemid.num;
vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), itemid.num);
switch (p_vcd->pxd.descriptor_type) {
case PSD_TYPE_SELECTION_LIST:
case PSD_TYPE_EXT_SELECTION_LIST: {
vcdinfo_itemid_t trans_itemid;
uint16_t trans_itemid_num;
if (p_vcd->pxd.psd == NULL) return;
trans_itemid_num = vcdinf_psd_get_itemid(p_vcd->pxd.psd);
vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid);
p_vcd->loop_count = 1;
p_vcd->loop_item = trans_itemid;
vcdplayer_play_single_item(p_access, trans_itemid);
break;
}
case PSD_TYPE_PLAY_LIST: {
if (p_vcd->pxd.pld == NULL) return;
p_vcd->pdi = -1;
_vcdplayer_inc_play_item(p_access);
break;
}
case PSD_TYPE_END_LIST:
case PSD_TYPE_COMMAND_LIST:
default:
;
}
}
}
/* Handles PBC navigation when reaching the end of a play item. */ /* Handles PBC navigation when reaching the end of a play item. */
vcdplayer_read_status_t vcdplayer_read_status_t
vcdplayer_pbc_nav ( access_t * p_access ) vcdplayer_pbc_nav ( access_t * p_access )
...@@ -410,7 +458,7 @@ vcdplayer_pbc_nav ( access_t * p_access ) ...@@ -410,7 +458,7 @@ vcdplayer_pbc_nav ( access_t * p_access )
p_vcd->play_item.num++; p_vcd->play_item.num++;
dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC),
"continuing into next entry: %u", p_vcd->play_item.num); "continuing into next entry: %u", p_vcd->play_item.num);
VCDPlay( p_access, p_vcd->play_item ); vcdplayer_play( p_access, p_vcd->play_item );
/* p_vcd->update_title(); */ /* p_vcd->update_title(); */
return READ_BLOCK; return READ_BLOCK;
} }
...@@ -439,7 +487,7 @@ vcdplayer_pbc_nav ( access_t * p_access ) ...@@ -439,7 +487,7 @@ vcdplayer_pbc_nav ( access_t * p_access )
vcdinf_pld_get_next_offset(p_vcd->pxd.pld), vcdinf_pld_get_next_offset(p_vcd->pxd.pld),
&itemid.num, "next" ); &itemid.num, "next" );
itemid.type = VCDINFO_ITEM_TYPE_LID; itemid.type = VCDINFO_ITEM_TYPE_LID;
VCDPlay( p_access, itemid ); vcdplayer_play( p_access, itemid );
break; break;
} }
case PSD_TYPE_SELECTION_LIST: /* Selection List (+Ext. for SVCD) */ case PSD_TYPE_SELECTION_LIST: /* Selection List (+Ext. for SVCD) */
...@@ -479,7 +527,7 @@ vcdplayer_pbc_nav ( access_t * p_access ) ...@@ -479,7 +527,7 @@ vcdplayer_pbc_nav ( access_t * p_access )
itemid.num = offset_timeout_LID->lid; itemid.num = offset_timeout_LID->lid;
itemid.type = VCDINFO_ITEM_TYPE_LID; itemid.type = VCDINFO_ITEM_TYPE_LID;
dbg_print(INPUT_DBG_PBC, "timeout to: %d", itemid.num); dbg_print(INPUT_DBG_PBC, "timeout to: %d", itemid.num);
VCDPlay( p_access, itemid ); vcdplayer_play( p_access, itemid );
return READ_BLOCK; return READ_BLOCK;
} else { } else {
int num_selections = vcdinf_get_num_selections(p_vcd->pxd.psd); int num_selections = vcdinf_get_num_selections(p_vcd->pxd.psd);
...@@ -495,7 +543,7 @@ vcdplayer_pbc_nav ( access_t * p_access ) ...@@ -495,7 +543,7 @@ vcdplayer_pbc_nav ( access_t * p_access )
itemid.type = VCDINFO_ITEM_TYPE_LID; itemid.type = VCDINFO_ITEM_TYPE_LID;
dbg_print(INPUT_DBG_PBC, "random selection %d, lid: %d", dbg_print(INPUT_DBG_PBC, "random selection %d, lid: %d",
rand_selection - bsn, rand_lid); rand_selection - bsn, rand_lid);
VCDPlay( p_access, itemid ); vcdplayer_play( p_access, itemid );
return READ_BLOCK; return READ_BLOCK;
} else if (p_vcd->in_still) { } else if (p_vcd->in_still) {
/* Hack: Just go back and do still again */ /* Hack: Just go back and do still again */
...@@ -523,6 +571,83 @@ vcdplayer_pbc_nav ( access_t * p_access ) ...@@ -523,6 +571,83 @@ vcdplayer_pbc_nav ( access_t * p_access )
return READ_ERROR; return READ_ERROR;
} }
/*!
Read block into p_buf and return the status back.
This routine is a bit complicated because on reaching the end of
a track or entry we may automatically advance to the item, or
interpret the next item in the playback-control list.
*/
vcdplayer_read_status_t
vcdplayer_read (access_t * p_access, uint8_t *p_buf)
{
/* p_access->handle_events (); */
vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys;
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: %u, end: %u\n", p_vcd->i_lsn, p_vcd->end_lsn);
handle_item_continuation:
read_status = vcdplayer_pbc_is_on( p_vcd )
? vcdplayer_pbc_nav( p_access )
: vcdplayer_non_pbc_nav( p_access );
if (READ_BLOCK != read_status) return read_status;
}
/* Read the next block.
Important note: we probably speed things up by removing "data"
and the memcpy to it by extending vcd_image_source_read_mode2
to allow a mode to do what's below in addition to its
"raw" and "block" mode. It also would probably improve the modularity
a little bit as well.
*/
{
CdIo *p_img = vcdinfo_get_cd_image(p_vcd->vcd);
typedef struct {
uint8_t subheader [CDIO_CD_SUBHEADER_SIZE];
uint8_t data [M2F2_SECTOR_SIZE];
uint8_t spare [4];
} vcdsector_t;
vcdsector_t vcd_sector;
do {
if (cdio_read_mode2_sector(p_img, &vcd_sector, p_vcd->i_lsn, true)!=0) {
dbg_print(INPUT_DBG_LSN, "read error\n");
return READ_ERROR;
}
p_vcd->i_lsn++;
if ( p_vcd->i_lsn >= p_vcd->end_lsn ) {
/* We've run off of the end of p_vcd entry. Do we continue or stop? */
dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC),
"end reached in reading, cur: %u, end: %u\n",
p_vcd->i_lsn, p_vcd->end_lsn);
break;
}
/* Check header ID for a padding sector and simply discard
these. It is alleged that VCD's put these in to keep the
bitrate constant.
*/
} while((vcd_sector.subheader[2]&~0x01)==0x60);
if ( p_vcd->i_lsn >= p_vcd->end_lsn )
/* We've run off of the end of this entry. Do we continue or stop? */
goto handle_item_continuation;
memcpy (p_buf, vcd_sector.data, M2F2_SECTOR_SIZE);
return READ_BLOCK;
}
}
/*! /*!
Get the next play-item in the list given in the LIDs. Note play-item 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 here refers to list of play-items for a single LID It shouldn't be
...@@ -560,7 +685,8 @@ vcdplayer_inc_play_item( access_t *p_access ) ...@@ -560,7 +685,8 @@ vcdplayer_inc_play_item( access_t *p_access )
vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid); vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid);
dbg_print(INPUT_DBG_PBC, " play-item[%d]: %s", dbg_print(INPUT_DBG_PBC, " play-item[%d]: %s",
p_vcd->pdi, vcdinfo_pin2str (trans_itemid_num)); p_vcd->pdi, vcdinfo_pin2str (trans_itemid_num));
return VLC_SUCCESS == VCDPlay( p_access, trans_itemid ); vcdplayer_play( p_access, trans_itemid );
return VLC_SUCCESS;
} }
} }
...@@ -597,9 +723,9 @@ vcdplayer_play_default( access_t * p_access ) ...@@ -597,9 +723,9 @@ vcdplayer_play_default( access_t * p_access )
if (VCDINFO_INVALID_LID != lid) { if (VCDINFO_INVALID_LID != lid) {
itemid.num = lid; itemid.num = lid;
itemid.type = VCDINFO_ITEM_TYPE_LID; itemid.type = VCDINFO_ITEM_TYPE_LID;
dbg_print(INPUT_DBG_PBC, "DEFAULT to %d\n", itemid.num); dbg_print(INPUT_DBG_PBC, "DEFAULT to %d", itemid.num);
} else { } else {
dbg_print(INPUT_DBG_PBC, "no DEFAULT for LID %d\n", p_vcd->i_lid); dbg_print(INPUT_DBG_PBC, "no DEFAULT for LID %d", p_vcd->i_lid);
} }
#else #else
...@@ -634,7 +760,8 @@ vcdplayer_play_default( access_t * p_access ) ...@@ -634,7 +760,8 @@ vcdplayer_play_default( access_t * p_access )
} }
/** ??? p_vcd->update_title(); ***/ /** ??? p_vcd->update_title(); ***/
return VLC_SUCCESS == VCDPlay( p_access, itemid ); vcdplayer_play( p_access, itemid );
return VLC_SUCCESS;
} }
...@@ -732,7 +859,8 @@ vcdplayer_play_next( access_t * p_access ) ...@@ -732,7 +859,8 @@ vcdplayer_play_next( access_t * p_access )
} }
/** ??? p_vcd->update_title(); ***/ /** ??? p_vcd->update_title(); ***/
return VLC_SUCCESS == VCDPlay( p_access, itemid ); vcdplayer_play( p_access, itemid );
return VLC_SUCCESS;
} }
...@@ -797,7 +925,8 @@ vcdplayer_play_prev( access_t * p_access ) ...@@ -797,7 +925,8 @@ vcdplayer_play_prev( access_t * p_access )
} }
/** ??? p_vcd->update_title(); ***/ /** ??? p_vcd->update_title(); ***/
return VLC_SUCCESS == VCDPlay( p_access, itemid ); vcdplayer_play( p_access, itemid );
return VLC_SUCCESS;
} }
...@@ -855,6 +984,7 @@ vcdplayer_play_return( access_t * p_access ) ...@@ -855,6 +984,7 @@ vcdplayer_play_return( access_t * p_access )
} }
/** ??? p_vcd->update_title(); ***/ /** ??? p_vcd->update_title(); ***/
return VLC_SUCCESS == VCDPlay( p_access, itemid ); vcdplayer_play( p_access, itemid );
return VLC_SUCCESS;
} }
...@@ -196,11 +196,17 @@ vcdplayer_play_return( access_t * p_access ); ...@@ -196,11 +196,17 @@ vcdplayer_play_return( access_t * p_access );
input: p_vcd->i_lsn, p_vcd->play_item input: p_vcd->i_lsn, p_vcd->play_item
changed: p_vcd->origin_lsn, p_vcd->end_lsn changed: p_vcd->origin_lsn, p_vcd->end_lsn
*/ */
void vcdplayer_set_origin(access_t * p_access); void vcdplayer_set_origin(access_t *p_access, lsn_t i_lsn, track_t i_track,
const vcdinfo_itemid_t *p_itemid);
void vcdplayer_play(access_t *p_access, vcdinfo_itemid_t itemid);
vcdplayer_read_status_t vcdplayer_pbc_nav ( 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 ); vcdplayer_read_status_t vcdplayer_non_pbc_nav ( access_t * p_access );
vcdplayer_read_status_t vcdplayer_read (access_t * p_access_t,
uint8_t *p_buf);
#endif /* _VCDPLAYER_H_ */ #endif /* _VCDPLAYER_H_ */
/* /*
* Local variables: * Local variables:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment