access.c
来自「VLC媒体播放程序」· C语言 代码 · 共 1,611 行 · 第 1/4 页
C
1,611 行
#ifdef WIN32 /* On Win32 we want the VCD access plugin to be explicitly requested, * we end up with lots of problems otherwise */ if( !p_input->psz_access || !*p_input->psz_access ) return NULL;#endif if( !p_input->psz_name ) { return NULL; } psz_parser = psz_source = strdup( p_input->psz_name ); /* Parse input string : * [device][@[type][title]] */ while( *psz_parser && *psz_parser != '@' ) { psz_parser++; } if( *psz_parser == '@' ) { /* Found the divide between the source name and the type+entry number. */ unsigned int num; *psz_parser = '\0'; ++psz_parser; if( *psz_parser ) { switch(*psz_parser) { case 'E': p_itemid->type = VCDINFO_ITEM_TYPE_ENTRY; ++psz_parser; *play_single_item = true; break; case 'P': p_itemid->type = VCDINFO_ITEM_TYPE_LID; ++psz_parser; *play_single_item = false; break; case 'S': p_itemid->type = VCDINFO_ITEM_TYPE_SEGMENT; ++psz_parser; *play_single_item = true; break; case 'T': p_itemid->type = VCDINFO_ITEM_TYPE_TRACK; ++psz_parser; *play_single_item = true; break; default: ; } } num = strtol( psz_parser, &psz_next, 10 ); if ( *psz_parser != '\0' && *psz_next == '\0') { p_itemid->num = num; } } else { *play_single_item = ( VCDINFO_ITEM_TYPE_LID == p_itemid->type ); } if( !*psz_source ) { /* No source specified, so figure it out. */ if( !p_input->psz_access ) return NULL; psz_source = config_GetPsz( p_input, "vcd" ); if( !psz_source || 0==strlen(psz_source) ) { /* Scan for a CD-ROM drive with a VCD in it. */ char **cd_drives = cdio_get_devices_with_cap(NULL, (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD |CDIO_FS_ANAL_VIDEOCD|CDIO_FS_UNKNOWN), true); if (NULL == cd_drives) return NULL; if (cd_drives[0] == NULL) { cdio_free_device_list(cd_drives); return NULL; } psz_source = strdup(cd_drives[0]); cdio_free_device_list(cd_drives); } } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL), "source=%s entry=%d type=%d", psz_source, p_itemid->num, p_itemid->type); return psz_source;}/* Set's start origin subsequent seeks/reads*/static voidVCDSetOrigin( input_thread_t *p_input, lsn_t origin_lsn, lsn_t cur_lsn, lsn_t end_lsn, int cur_entry, track_t cur_track ){ thread_vcd_data_t * p_vcd = (thread_vcd_data_t *) p_input->p_access_data; p_vcd->origin_lsn = origin_lsn; p_vcd->cur_lsn = cur_lsn; p_vcd->end_lsn = end_lsn; p_vcd->cur_track = cur_track; p_vcd->play_item.num = cur_entry; 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 ); 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", p_vcd->play_item.type == VCDINFO_ITEM_TYPE_ENTRY ? _("Entry") : _("Segment"), "Setting entry/segment");}/***************************************************************************** * vcd_Open: Opens a VCD device or file and returns an opaque handle *****************************************************************************/static vcdinfo_obj_t *vcd_Open( vlc_object_t *p_this, const char *psz_dev ){ vcdinfo_obj_t *p_vcdobj; char *actual_dev; if( !psz_dev ) return NULL; actual_dev=strdup(psz_dev); if ( vcdinfo_open(&p_vcdobj, &actual_dev, DRIVER_UNKNOWN, NULL) != VCDINFO_OPEN_VCD) { free(actual_dev); return NULL; } free(actual_dev); return p_vcdobj;}/**************************************************************************** * VCDReadSector: Read a sector (2324 bytes) ****************************************************************************/static intVCDReadSector( vlc_object_t *p_this, const vcdinfo_obj_t *p_vcd, lsn_t cur_lsn, byte_t * p_buffer ){ typedef struct { uint8_t subheader [8]; 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, cur_lsn, true) != 0) { msg_Warn( p_this, "Could not read LSN %d", cur_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.****************************************************************************/static voidVCDUpdateVar( input_thread_t *p_input, int i_num, int i_action, 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", p_debug_label, i_num ); } 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 );}static inline voidMetaInfoAddStr(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 voidMetaInfoAddNum(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 ); 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" ); 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; \ } \ saw_control_prefix = false; \ } \ }#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) { \ strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \ tp += len; \ } \ saw_control_prefix = false; \ }/*! Take a format string and expand escape sequences, that is sequences that begin with %, with information from the current VCD. The expanded string is returned. Here is a list of escape sequences: %A : The album information %C : The VCD volume count - the number of CD's in the collection. %c : The VCD volume num - the number of the CD in the collection. %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT... %L : The playlist ID prefixed with " LID" if it exists %M : MRL %N : The current number of the %I - a decimal number %P : The publisher ID %p : The preparer ID %S : If we are in a segment (menu), the kind of segment %T : The track number %V : The volume set ID %v : The volume ID A number between 1 and the volume count. %% : a %*/static char *VCDFormatStr(const input_thread_t *p_input, thread_vcd_data_t *p_vcd, const char format_str[], const char *mrl, const vcdinfo_itemid_t *itemid){#define TEMP_STR_SIZE 256#define TEMP_STR_LEN (TEMP_STR_SIZE-1) static char temp_str[TEMP_STR_SIZE]; size_t i; char * tp = temp_str; bool saw_control_prefix = false; size_t format_len = strlen(format_str); bzero(temp_str, TEMP_STR_SIZE); for (i=0; i<format_len; i++) { if (!saw_control_prefix && format_str[i] != '%') { *tp++ = format_str[i]; saw_control_prefix = false; continue; } switch(format_str[i]) { case '%': if (saw_control_prefix) { *tp++ = '%'; } saw_control_prefix = !saw_control_prefix; break; case 'A': add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcd->vcd), MAX_ALBUM_LEN)); break; case 'c': add_format_num_info(vcdinfo_get_volume_num(p_vcd->vcd), "%d"); break; case 'C': add_format_num_info(vcdinfo_get_volume_count(p_vcd->vcd), "%d"); break; case 'F': add_format_str_info(vcdinfo_get_format_version_str(p_vcd->vcd)); break; case 'I': { switch (itemid->type) { case VCDINFO_ITEM_TYPE_TRACK: strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str)); tp += strlen(_("Track")); break; case VCDINFO_ITEM_TYPE_ENTRY: strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?