📄 access.c
字号:
t = p_vcdplayer->p_title[p_vcdplayer->i_titles] = vlc_input_title_New(); p_vcdplayer->i_titles++; t->i_size = 0; /* Not sure Segments have a size associated */ t->psz_name = strdup(_("Segments")); /* We have one additional segment allocated so we can get the size by subtracting seg[i+1] - seg[i]. */ p_vcdplayer->p_segments = malloc( sizeof( lsn_t ) * (p_vcdplayer->i_segments+1) ); if( p_vcdplayer->p_segments == NULL ) { LOG_ERR ("not enough memory for segment treatment" ); return VLC_FALSE; } for( i = 0 ; i < p_vcdplayer->i_segments ; i++ ) { char psz_segment[100]; seekpoint_t *s = vlc_seekpoint_New(); p_vcdplayer->p_segments[i] = vcdinfo_get_seg_lsn(p_vcdplayer->vcd, i); snprintf( psz_segment, sizeof(psz_segment), "%s%02d", _("Segment "), i ); s->i_byte_offset = 0; /* Not sure what this would mean here */ s->psz_name = strdup(psz_segment); TAB_APPEND( t->i_seekpoint, t->seekpoint, s ); } p_vcdplayer->p_segments[p_vcdplayer->i_segments] = p_vcdplayer->p_segments[p_vcdplayer->i_segments-1]+ vcdinfo_get_seg_sector_count(p_vcdplayer->vcd, p_vcdplayer->i_segments-1); return VLC_TRUE;}/***************************************************************************** Build title table which will be returned via ACCESS_GET_TITLE_INFO. We start area addressing for tracks at 1 since the default area 0 is reserved for segments. *****************************************************************************/static intVCDTitles( access_t * p_access ){ /* We'll assume a VCD has its first MPEG track cdio_get_first_track_num()+1 could be used if one wanted to be very careful about this. Note: cdio_get_first_track() will give the ISO-9660 track before the MPEG tracks. */ if (!p_access || !p_access->p_sys) return VLC_EGENERIC; { vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys; track_t i; p_vcdplayer->i_titles = 0; for( i = 1 ; i <= p_vcdplayer->i_tracks ; i++ ) { input_title_t *t = p_vcdplayer->p_title[i-1] = vlc_input_title_New(); char psz_track[80]; snprintf( psz_track, sizeof(psz_track), "%s%02d", _("Track "), i ); t->i_size = (int64_t) vcdinfo_get_track_size( p_vcdplayer->vcd, i ) * M2F2_SECTOR_SIZE / CDIO_CD_FRAMESIZE ; t->psz_name = strdup(psz_track); dbg_print( INPUT_DBG_MRL, "track[%d] i_size: %lld", i, t->i_size ); p_vcdplayer->i_titles++; } return VLC_SUCCESS; }}/***************************************************************************** VCDLIDs: Reads the LIST IDs from the LOT. *****************************************************************************/static vlc_bool_tVCDLIDs( access_t * p_access ){ vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys; input_title_t *t; unsigned int i_lid, i_title; p_vcdplayer->i_lids = vcdinfo_get_num_LIDs(p_vcdplayer->vcd); p_vcdplayer->i_lid = VCDINFO_INVALID_ENTRY; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL), "LIDs: %d", p_vcdplayer->i_lids); if ( 0 == p_vcdplayer->i_lids ) return VLC_FALSE; if (vcdinfo_read_psd (p_vcdplayer->vcd)) { vcdinfo_visit_lot (p_vcdplayer->vcd, false);#if FIXED /* We need to change libvcdinfo to be more robust when there are problems reading the extended PSD. Given that area-highlighting and selection features in the extended PSD haven't been implemented, it's best then to not try to read this at all. */ if (vcdinfo_get_psd_x_size(p_vcdplayer->vcd)) vcdinfo_visit_lot (p_vcdplayer->vcd, VLC_TRUE);#endif } /* Set up LIDs Navigation Menu */ t = vlc_input_title_New(); t->b_menu = VLC_TRUE; t->psz_name = strdup( "LIDs" ); i_title = p_vcdplayer->i_tracks; for( i_lid = 1 ; i_lid <= p_vcdplayer->i_lids ; i_lid++ ) { char psz_lid[100]; seekpoint_t *s = vlc_seekpoint_New(); snprintf( psz_lid, sizeof(psz_lid), "%s%02d", _("LID "), i_lid ); s->i_byte_offset = 0; /* A lid doesn't have an offset size associated with it */ s->psz_name = strdup(psz_lid); TAB_APPEND( t->i_seekpoint, t->seekpoint, s ); }#if DYNAMICALLY_ALLOCATED TAB_APPEND( p_vcdplayer->i_titles, p_vcdplayer->p_title, t );#else p_vcdplayer->p_title[p_vcdplayer->i_titles] = t; p_vcdplayer->i_titles++;#endif return VLC_TRUE;}/***************************************************************************** * VCDParse: parse command line *****************************************************************************/static char *VCDParse( access_t * p_access, /*out*/ vcdinfo_itemid_t * p_itemid, /*out*/ vlc_bool_t *play_single_item ){ vcdplayer_t *p_vcdplayer = (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; p_itemid->num = 1; *play_single_item = VLC_FALSE; } else { p_itemid->type = VCDINFO_ITEM_TYPE_ENTRY; p_itemid->num = 0; }#ifdef WIN32 /* On Win32 we want the VCD access plugin to be explicitly requested, * we end up with lots of problems otherwise */ if( !p_access->psz_access || !*p_access->psz_access ) return NULL;#endif if( !p_access->psz_path ) { return NULL; } psz_parser = psz_source = strdup( p_access->psz_path ); /* 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 = VLC_TRUE; break; case 'P': p_itemid->type = VCDINFO_ITEM_TYPE_LID; ++psz_parser; *play_single_item = VLC_FALSE; break; case 'S': p_itemid->type = VCDINFO_ITEM_TYPE_SEGMENT; ++psz_parser; *play_single_item = VLC_TRUE; break; case 'T': p_itemid->type = VCDINFO_ITEM_TYPE_TRACK; ++psz_parser; *play_single_item = VLC_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_access->psz_access ) return NULL; psz_source = config_GetPsz( p_access, "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 ), VLC_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;}/* Sets start origin for subsequent seeks/reads*/voidVCDSetOrigin( access_t *p_access, lsn_t i_lsn, track_t i_track, const vcdinfo_itemid_t *p_itemid ){ vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN), "i_lsn: %lu, track: %d", (long unsigned int) i_lsn, i_track ); vcdplayer_set_origin(p_access, i_lsn, i_track, p_itemid); switch (p_vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_ENTRY: VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, "chapter", _("Entry"), "Setting entry/segment"); p_access->info.i_title = i_track-1; if (p_vcdplayer->b_track_length) { p_access->info.i_size = p_vcdplayer->p_title[i_track-1]->i_size; p_access->info.i_pos = (int64_t) i_lsn * M2F2_SECTOR_SIZE; } else { p_access->info.i_size = M2F2_SECTOR_SIZE * (int64_t) vcdinfo_get_entry_sect_count(p_vcdplayer->vcd, p_itemid->num); p_access->info.i_pos = 0; } dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), "size: %llu, pos: %llu", p_access->info.i_size, p_access->info.i_pos ); 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"); /* The last title entry is the for segments (when segments exist and they must here. The segment seekpoints are stored after the entry seekpoints and (zeroed) lid seekpoints. */ p_access->info.i_title = p_vcdplayer->i_titles - 1; p_access->info.i_size = 0; /* No seeking on stills, please. */ p_access->info.i_pos = 0; p_access->info.i_seekpoint = p_vcdplayer->i_entries + p_vcdplayer->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_vcdplayer->p_title[i_track-1]->i_size; p_access->info.i_pos = 0; p_access->info.i_seekpoint = vcdinfo_track_get_entry(p_vcdplayer->vcd, i_track); break; default: msg_Warn( p_access, "can't set origin for play type %d", p_vcdplayer->play_item.type ); } p_access->info.i_update = INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE | INPUT_UPDATE_SEEKPOINT; VCDUpdateTitle( p_access );}/***************************************************************************** * 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_vcdplayer = (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", psz_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); /* Save summary info on tracks, segments and entries... */ if ( 0 < (p_vcdplayer->i_tracks = vcdinfo_get_num_tracks(p_vcdobj)) ) { p_vcdplayer->track = (vcdplayer_play_item_info_t *) calloc(p_vcdplayer->i_tracks, sizeof(vcdplayer_play_item_info_t)); for (i=0; i<p_vcdplayer->i_tracks; i++) { unsigned int track_num=i+1; p_vcdplayer->track[i].size = vcdinfo_get_track_sect_count(p_vcdobj, track_num); p_vcdplayer->track[i].start_LSN = vcdinfo_get_track_lsn(p_vcdobj, track_num); } } else p_vcdplayer->track = NULL; if ( 0 < (p_vcdplayer->i_entries = vcdinfo_get_num_entries(p_vcdobj)) ) { p_vcdplayer->entry = (vcdplayer_play_item_info_t *) calloc(p_vcdplayer->i_entries, sizeof(vcdplayer_play_item_info_t)); for (i=0; i<p_vcdplayer->i_entries; i++) { p_vcdplayer->entry[i].size = vcdinfo_get_entry_sect_count(p_vcdobj, i); p_vcdplayer->entry[i].start_LSN = vcdinfo_get_entry_lsn(p_vcdobj, i); } } else p_vcdplayer->entry = NULL; if ( 0 < (p_vcdplayer->i_segments = vcdinfo_get_num_segments(p_vcdobj)) ) { p_vcdplayer->segment = (vcdplayer_play_item_info_t *) calloc(p_vcdplayer->i_segments, sizeof(vcdplayer_play_item_info_t)); for (i=0; i<p_vcdplayer->i_segments; i++) { p_vcdplayer->segment[i].size = vcdinfo_get_seg_sector_count(p_vcdobj, i); p_vcdplayer->segment[i].start_LSN = vcdinfo_get_seg_lsn(p_vcdobj, i); } } else p_vcdplayer->segment = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -