* using libcdio, libvcd and libvcdinfo. vlc-specific things tend
* to go here.
*****************************************************************************
- * Copyright (C) 2000, 2003 VideoLAN
- * $Id: access.c,v 1.13 2003/12/22 14:32:55 sam Exp $
+ * Copyright (C) 2000, 2003, 2004 VideoLAN
+ * $Id$
*
* Authors: Rocky Bernstein <rocky@panix.com>
* Johan Bilien <jobi@via.ecp.fr>
/*out*/ bool *play_single_item );
static void VCDUpdateVar( input_thread_t *p_input, int i_entry, int i_action,
- const char *varname, const char *label );
+ const char *p_varname, char *p_label,
+ const char *p_debug_label );
static vcdinfo_obj_t *vcd_Open ( vlc_object_t *p_this, const char *psz_dev );
i_read = 0;
- dbg_print( (INPUT_DBG_CALL), "lsn: %u", p_vcd->cur_lsn );
+ dbg_print( (INPUT_DBG_CALL), "lsn: %lu",
+ (long unsigned int) p_vcd->cur_lsn );
/* Compute the number of blocks we have to read */
/* 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", p_vcd->cur_lsn );
+ "end reached, cur: %lu",
+ (long unsigned int) p_vcd->cur_lsn );
read_status = vcdplayer_pbc_is_on( p_vcd )
? vcdplayer_pbc_nav( p_input )
p_vcd->cur_lsn,
p_buffer + (i_index*M2F2_SECTOR_SIZE) ) < 0 )
{
- LOG_ERR ("could not read sector %d", p_vcd->cur_lsn );
+ LOG_ERR ("could not read sector %lu",
+ (long unsigned int) p_vcd->cur_lsn );
return -1;
}
p_vcd->cur_lsn >= p_vcd->p_entries[i_entry+1] )
{
dbg_print( INPUT_DBG_PBC,
- "new entry, i_entry %d, sector %d, es %d",
- i_entry, p_vcd->cur_lsn,
+ "new entry, i_entry %d, sector %lu, es %u",
+ i_entry, (long unsigned int) p_vcd->cur_lsn,
p_vcd->p_entries[i_entry] );
p_vcd->play_item.num =
++ p_input->stream.p_selected_area->i_part;
p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY;
VCDUpdateVar( p_input, p_vcd->play_item.num, VLC_VAR_SETVALUE,
- "chapter", "Setting entry" );
+ "chapter", _("Entry"), "Setting entry" );
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
if ( VCDReadSector( VLC_OBJECT(p_input), p_vcd->vcd,
p_vcd->cur_lsn, p_last_sector ) < 0 )
{
- LOG_ERR ("could not read sector %d", p_vcd->cur_lsn );
+ LOG_ERR ("could not read sector %lu",
+ (long unsigned int) p_vcd->cur_lsn );
return -1;
}
p_input->stream.p_selected_area = p_area;
/* Update the navigation variables without triggering a callback */
+
VCDUpdateVar( p_input, i_track, VLC_VAR_SETVALUE, "title",
- "Setting track");
+ _("Track"), "Setting track");
var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL );
for( i = p_area->i_plugin_data; i < i_nb; i++ )
{
VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE,
- "chapter", "Adding entry choice");
+ "chapter",
+ p_vcd->play_item.type == VCDINFO_ITEM_TYPE_SEGMENT ?
+ _("Segment"): _("Entry"),
+ "Adding entry choice");
}
+
+ if (p_vcd->b_svd) {
+ unsigned int audio_type =
+ vcdinfo_get_track_audio_type(p_vcd->vcd, i_track);
+ unsigned int i_channels =
+ vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type);
+
+ var_Change( p_input, "audio_channels", VLC_VAR_CLEARCHOICES, NULL,
+ NULL );
+
+ for( i = 0; i < i_channels; i++ )
+ {
+ VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE,
+ "audio_channels", NULL, "Adding audio choice");
+ }
+ }
+
}
if (i_track == 0)
if( p_vcd->cur_lsn < p_vcd->p_entries[i_entry] )
{
VCDUpdateVar( p_input, i_entry, VLC_VAR_SETVALUE,
- "chapter", "Setting entry" );
+ "chapter", _("Entry"), "Setting entry" );
break;
}
}
p_input->stream.p_selected_area->i_tell = i_off;
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK),
- "orig %d, cur: %d, offset: %lld, start: %lld, entry %d",
- p_vcd->origin_lsn, p_vcd->cur_lsn, i_off,
+ "orig %lu, cur: %lu, offset: %lld, start: %lld, entry %d",
+ (long unsigned int) p_vcd->origin_lsn,
+ (long unsigned int) p_vcd->cur_lsn, i_off,
p_input->stream.p_selected_area->i_start, i_entry );
vlc_mutex_unlock( &p_input->stream.stream_lock );
{
thread_vcd_data_t * p_vcd= (thread_vcd_data_t *)p_input->p_access_data;
input_area_t * p_area;
+ bool b_was_still;
dbg_print(INPUT_DBG_CALL, "itemid.num: %d, itemid.type: %d\n",
itemid.num, itemid.type);
if (!p_input->p_access_data) return VLC_EGENERIC;
-
- p_vcd->in_still = false;
- p_vcd->cur_lid = VCDINFO_INVALID_LID;
+
+ b_was_still = p_vcd->in_still;
#define area p_input->stream.pp_areas
LOG_ERR ("Invalid track number %d", itemid.num );
return VLC_EGENERIC;
}
+ p_vcd->in_still = false;
p_area = area[itemid.num];
p_area->i_part = p_area->i_plugin_data;
p_input->stream.b_seekable = 1;
return VLC_EGENERIC;
} else {
track_t cur_track = vcdinfo_get_track(p_vcd->vcd, itemid.num);
+ p_vcd->in_still = false;
p_area = area[cur_track];
p_area->i_part = itemid.num;
p_input->stream.b_seekable = 1;
#undef area
+#if 1
+ if ( p_vcd->in_still != b_was_still ) {
+ if (p_input->stream.pp_selected_es) {
+ input_SetStatus( p_input, INPUT_STATUS_END );
+ input_SetStatus( p_input, INPUT_STATUS_PLAY );
+ }
+ }
+#endif
+
p_vcd->play_item = itemid;
dbg_print( (INPUT_DBG_CALL),
- "i_start %lld, i_size: %lld, i_tell: %lld, lsn %d",
+ "i_start %lld, i_size: %lld, i_tell: %lld, lsn %lu",
p_area->i_start, p_area->i_size,
- p_area->i_tell, p_vcd->cur_lsn );
+ p_area->i_tell,
+ (long unsigned int) p_vcd->cur_lsn );
return VLC_SUCCESS;
}
}
/* Update the navigation variables without triggering a callback */
- VCDUpdateVar( p_input, 0, VLC_VAR_SETVALUE, "title", "Setting track" );
+ VCDUpdateVar( p_input, 0, VLC_VAR_SETVALUE, "title", _("Track"),
+ "Setting track" );
+
var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL );
for( i = 0 ; i < num_segments ; i++ )
p_vcd->p_segments[i] = vcdinfo_get_seg_lsn(p_vcd->vcd, i);
area[0]->i_part_nb ++;
VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE,
- "chapter", "Adding segment choice");
+ "chapter", _("Segment"), "Adding segment choice");
}
#undef area
p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY;
dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN),
- "origin: %d, cur_lsn: %d, end_lsn: %d, entry: %d, track: %d",
- origin_lsn, cur_lsn, end_lsn, cur_entry, cur_track );
+ "origin: %lu, cur_lsn: %lu, end_lsn: %lu, entry: %d, track: %d",
+ (long unsigned int) origin_lsn,
+ (long unsigned int) cur_lsn,
+ (long unsigned int) end_lsn, cur_entry, cur_track );
p_input->stream.p_selected_area->i_tell =
(off_t) (p_vcd->cur_lsn - p_vcd->origin_lsn) * (off_t)M2F2_SECTOR_SIZE;
VCDUpdateVar( p_input, cur_entry, VLC_VAR_SETVALUE,
- "chapter", "Setting entry");
+ "chapter",
+ p_vcd->play_item.type == VCDINFO_ITEM_TYPE_ENTRY ?
+ _("Entry") : _("Segment"),
+ "Setting entry/segment");
}
/*****************************************************************************
typedef struct {
uint8_t subheader [8];
uint8_t data [M2F2_SECTOR_SIZE];
+ uint8_t spare [4];
} vcdsector_t;
vcdsector_t vcd_sector;
&vcd_sector, cur_lsn, true)
!= 0)
{
- msg_Warn( p_this, "Could not read LSN %d", cur_lsn );
+ msg_Warn( p_this, "Could not read LSN %lu",
+ (long unsigned int) cur_lsn );
return -1;
}
****************************************************************************/
static void
VCDUpdateVar( input_thread_t *p_input, int i_num, int i_action,
- const char *varname, const char *label)
+ const char *p_varname, char *p_label,
+ const char *p_debug_label)
{
vlc_value_t val;
val.i_int = i_num;
if (NULL != p_vcd_input) {
thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_vcd_input->p_access_data;
- dbg_print( INPUT_DBG_PBC, "%s %d", label, i_num );
+ dbg_print( INPUT_DBG_PBC, "%s %d", p_debug_label, i_num );
}
- var_Change( p_input, varname, i_action, &val, NULL );
+ if (p_label) {
+ vlc_value_t text;
+ text.psz_string = p_label;
+ var_Change( p_input, p_varname, VLC_VAR_SETTEXT, &text, NULL );
+ }
+ var_Change( p_input, p_varname, i_action, &val, NULL );
}
-#define meta_info_add_str(title, str) \
- if ( str ) { \
- dbg_print( INPUT_DBG_META, "field: %s: %s\n", title, str); \
- input_AddInfo( p_cat, _(title), "%s", str ); \
+static inline void
+MetaInfoAddStr(input_thread_t *p_input, input_info_category_t *p_cat,
+ playlist_t *p_playlist, char *title,
+ const char *str)
+{
+ thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;
+ playlist_item_t *p_item;
+ if ( str ) {
+ dbg_print( INPUT_DBG_META, "field: %s: %s\n", title, str);
+ input_AddInfo( p_cat, title, "%s", str );
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+ p_item = playlist_ItemGetByPos( p_playlist, -1 );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ vlc_mutex_lock( &p_item->lock );
+ playlist_ItemAddInfo( p_item, p_cat->psz_name, title,
+ "%s",str );
+ vlc_mutex_unlock( &p_item->lock );
}
+}
+
+
+static inline void
+MetaInfoAddNum(input_thread_t *p_input, input_info_category_t *p_cat,
+ playlist_t *p_playlist, char *title, int num)
+{
+ thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;
+ playlist_item_t *p_item;
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+ p_item = playlist_ItemGetByPos( p_playlist, -1 );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ dbg_print( INPUT_DBG_META, "field %s: %d\n", title, num);
+ input_AddInfo( p_cat, title, "%d", num );
-#define meta_info_add_num(title, num) \
- dbg_print( INPUT_DBG_META, "field %s: %d\n", title, num); \
- input_AddInfo( p_cat, _(title), "%d", num ); \
+ vlc_mutex_lock( &p_item->lock );
+ playlist_ItemAddInfo( p_item , p_cat->psz_name, title, "%d",num );
+ vlc_mutex_unlock( &p_item->lock );
+}
+
+#define addstr(title, str) \
+ MetaInfoAddStr( p_input, p_cat, p_playlist, title, str );
+
+#define addnum(title, num) \
+ MetaInfoAddNum( p_input, p_cat, p_playlist, title, num );
static void InformationCreate( input_thread_t *p_input )
{
thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;
+ unsigned int i_nb = vcdinfo_get_num_entries(p_vcd->vcd);
+ unsigned int last_entry = 0;
input_info_category_t *p_cat;
+ track_t i_track;
+ playlist_t *p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
+ FIND_PARENT );
p_cat = input_InfoCategory( p_input, "General" );
- meta_info_add_str( "VCD Format", vcdinfo_get_format_version_str(p_vcd->vcd));
- meta_info_add_str( "Album", vcdinfo_get_album_id(p_vcd->vcd));
- meta_info_add_str( "Application",vcdinfo_get_application_id(p_vcd->vcd));
- meta_info_add_str( "Preparer", vcdinfo_get_preparer_id(p_vcd->vcd));
- meta_info_add_num( "Vol #", vcdinfo_get_volume_num(p_vcd->vcd));
- meta_info_add_num( "Vol max #", vcdinfo_get_volume_count(p_vcd->vcd));
- meta_info_add_str( "Volume Set", vcdinfo_get_volumeset_id(p_vcd->vcd));
- meta_info_add_str( "Volume", vcdinfo_get_volume_id(p_vcd->vcd));
- meta_info_add_str( "Publisher", vcdinfo_get_publisher_id(p_vcd->vcd));
- meta_info_add_str( "System Id", vcdinfo_get_system_id(p_vcd->vcd));
- meta_info_add_num( "LIDs", vcdinfo_get_num_LIDs(p_vcd->vcd));
- meta_info_add_num( "Entries", vcdinfo_get_num_entries(p_vcd->vcd));
- meta_info_add_num( "Segments", vcdinfo_get_num_segments(p_vcd->vcd));
- meta_info_add_num( "Tracks", vcdinfo_get_num_tracks(p_vcd->vcd));
+ addstr( _("VCD Format"), vcdinfo_get_format_version_str(p_vcd->vcd) );
+ addstr( _("Album"), vcdinfo_get_album_id(p_vcd->vcd));
+ addstr( _("Application"), vcdinfo_get_application_id(p_vcd->vcd) );
+ addstr( _("Preparer"), vcdinfo_get_preparer_id(p_vcd->vcd) );
+ addnum( _("Vol #"), vcdinfo_get_volume_num(p_vcd->vcd) );
+ addnum( _("Vol max #"), vcdinfo_get_volume_count(p_vcd->vcd) );
+ addstr( _("Volume Set"), vcdinfo_get_volumeset_id(p_vcd->vcd) );
+ addstr( _("Volume"), vcdinfo_get_volume_id(p_vcd->vcd) );
+ addstr( _("Publisher"), vcdinfo_get_publisher_id(p_vcd->vcd) );
+ addstr( _("System Id"), vcdinfo_get_system_id(p_vcd->vcd) );
+ addnum( "LIDs", vcdinfo_get_num_LIDs(p_vcd->vcd) );
+ addnum( _("Entries"), vcdinfo_get_num_entries(p_vcd->vcd) );
+ addnum( _("Segments"), vcdinfo_get_num_segments(p_vcd->vcd) );
+ addnum( _("Tracks"), vcdinfo_get_num_tracks(p_vcd->vcd) );
+
+ /* Spit out track information. Could also include MSF info.
+ */
+
+#define TITLE_MAX 30
+ for( i_track = 1 ; i_track < p_vcd->num_tracks ; i_track++ ) {
+ char track_str[TITLE_MAX];
+ unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcd->vcd,
+ i_track);
+ snprintf(track_str, TITLE_MAX, "%s%02d", _("Track"), i_track);
+ p_cat = input_InfoCategory( p_input, track_str );
+
+ if (p_vcd->b_svd) {
+ addnum(_("Audio Channels"),
+ vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type) );
+ }
+ addnum(_("First Entry Point"), last_entry );
+ for ( ; last_entry < i_nb
+ && vcdinfo_get_track(p_vcd->vcd, last_entry) == i_track;
+ last_entry++ ) ;
+ addnum(_("Last Entry Point"), last_entry-1 );
+ }
}
-#define add_format_str_info(val) \
- { \
- const char *str = val; \
- unsigned int len; \
- if (val != NULL) { \
- len=strlen(str); \
- if (len != 0) { \
- strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
- tp += len; \
+#define add_format_str_info(val) \
+ { \
+ const char *str = val; \
+ unsigned int len; \
+ if (val != NULL) { \
+ len=strlen(str); \
+ if (len != 0) { \
+ strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
+ tp += len; \
} \
- saw_control_prefix = false; \
- } \
+ saw_control_prefix = false; \
+ } \
}
-#define add_format_num_info(val, fmt) \
- { \
- char num_str[10]; \
- unsigned int len; \
+#define add_format_num_info(val, fmt) \
+ { \
+ char num_str[10]; \
+ unsigned int len; \
sprintf(num_str, fmt, val); \
- len=strlen(num_str); \
- if (len != 0) { \
+ len=strlen(num_str); \
+ if (len != 0) { \
strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
- tp += len; \
- } \
+ tp += len; \
+ } \
saw_control_prefix = false; \
}
const char *psz_source, int playlist_operation,
int i_pos)
{
- mtime_t i_duration = -1;
char *p_author;
char *p_title;
char c_type;
p_title =
VCDFormatStr( p_input, p_vcd,
- config_GetPsz( p_input, MODULE_STRING "-title-format" ),
- psz_mrl, itemid );
-
- playlist_AddExt( p_playlist, psz_mrl, p_title, i_duration,
- 0, 0, playlist_operation, i_pos );
+ config_GetPsz( p_input, MODULE_STRING "-title-format" ),
+ psz_mrl, itemid );
+
+ playlist_Add( p_playlist, psz_mrl, p_title, playlist_operation, i_pos );
p_author =
VCDFormatStr( p_input, p_vcd,
- config_GetPsz( p_input, MODULE_STRING "-author-format" ),
- psz_mrl, itemid );
+ config_GetPsz( p_input, MODULE_STRING "-author-format" ),
+ psz_mrl, itemid );
- /* FIXME: This is horrible, but until the playlist interface is fixed up
- something like this has to be done for the "Author" field.
- */
if( i_pos == PLAYLIST_END ) i_pos = p_playlist->i_size - 1;
- free(p_playlist->pp_items[i_pos]->psz_author);
- p_playlist->pp_items[i_pos]->psz_author = strdup(p_author);
+ playlist_AddInfo(p_playlist, i_pos, _("General"), _("Author"), "%s",
+ p_author);
}
static int
InformationCreate( p_input );
- if ( play_single_item ) {
+ if ( play_single_item )
+ {
/* May fill out more information when the playlist user interface becomes
more mature.
*/
VCDCreatePlayListItem(p_input, p_vcd, p_playlist, itemid,
psz_mrl, psz_mrl_max, psz_source, PLAYLIST_REPLACE,
p_playlist->i_index);
- } else {
+
+ }
+ else
+ {
vcdinfo_itemid_t list_itemid;
list_itemid.type=VCDINFO_ITEM_TYPE_ENTRY;
p_input->p_access_data = (void *)p_vcd;
p_vcd->i_debug = config_GetInt( p_this, MODULE_STRING "-debug" );
+ p_vcd->in_still = false;
+ p_vcd->play_item.type = VCDINFO_ITEM_TYPE_NOTFOUND;
/* Set where to log errors messages from libcdio. */
p_vcd_input = (input_thread_t *)p_this;
cdio_log_set_handler ( cdio_log_handler );
vcd_log_set_handler ( vcd_log_handler );
- psz_source = VCDParse( p_input, &itemid, &play_single_item );
+ psz_source = VCDParse( p_input, &itemid, &play_single_item );
if ( NULL == psz_source )
{
goto err_exit;
}
+ p_vcd->b_svd= vcdinfo_get_tracksSVD(p_vcd->vcd);;
+
/* Get track information. */
p_vcd->num_tracks = ioctl_GetTracksMap( VLC_OBJECT(p_input),
vcdinfo_get_cd_image(p_vcd->vcd),
p_vcd->p_intf->b_block = VLC_FALSE;
intf_RunThread( p_vcd->p_intf );
- VCDFixupPlayList( p_input, p_vcd, psz_source, &itemid, play_single_item );
+ if (play_single_item)
+ VCDFixupPlayList( p_input, p_vcd, psz_source, &itemid, play_single_item );
free( psz_source );
free( p_vcd->p_entries );
free( p_vcd->p_segments );
+ free( p_vcd->p_sectors );
/* 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