access.c
来自「VLC媒体播放程序」· C语言 代码 · 共 1,611 行 · 第 1/4 页
C
1,611 行
if( p_vcd->cur_lsn < p_vcd->p_entries[i_entry] ) { VCDUpdateVar( p_input, i_entry, VLC_VAR_SETVALUE, "chapter", _("Entry"), "Setting entry" ); break; } } p_vcd->play_item.num = p_area->i_part = i_entry; p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; }#undef p_area 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, p_input->stream.p_selected_area->i_start, i_entry ); vlc_mutex_unlock( &p_input->stream.stream_lock );}/***************************************************************************** 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. *****************************************************************************/intVCDPlay( input_thread_t *p_input, vcdinfo_itemid_t itemid ){ 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; b_was_still = p_vcd->in_still;#define area p_input->stream.pp_areas switch (itemid.type) { case VCDINFO_ITEM_TYPE_TRACK: /* Valid tracks go from 1...num_tracks-1, because track 0 is unplayable. */ if (itemid.num == 0 || itemid.num >= p_vcd->num_tracks) { 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; break; case VCDINFO_ITEM_TYPE_SEGMENT: /* Valid segments go from 0...num_segments-1. */ if (itemid.num >= p_vcd->num_segments) { LOG_ERR ( "Invalid segment number: %d", itemid.num ); return VLC_EGENERIC; } else { vcdinfo_video_segment_type_t segtype = vcdinfo_get_video_type(p_vcd->vcd, itemid.num); dbg_print(INPUT_DBG_PBC, "%s (%d), seg_num: %d", vcdinfo_video_type2str(p_vcd->vcd, itemid.num), (int) segtype, itemid.num); p_area = area[0]; p_area->i_part = 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_input->stream.b_seekable = 0; p_vcd->in_still = true; break; default: p_input->stream.b_seekable = 1; p_vcd->in_still = false; } } break; case VCDINFO_ITEM_TYPE_LID: /* LIDs go from 1..num_lids. */ if (itemid.num == 0 || itemid.num > p_vcd->num_lids) { LOG_ERR ( "Invalid LID number: %d", itemid.num ); return VLC_EGENERIC; } else { p_vcd->cur_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_input, 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_input) ? VLC_SUCCESS : VLC_EGENERIC; break; } case PSD_TYPE_END_LIST: case PSD_TYPE_COMMAND_LIST: default: ; } } return VLC_EGENERIC; case VCDINFO_ITEM_TYPE_ENTRY: /* Entries go from 0..num_entries-1. */ if (itemid.num >= p_vcd->num_entries) { LOG_ERR ("Invalid entry number: %d", itemid.num ); 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; } break; default: LOG_ERR ("unknown entry type" ); return VLC_EGENERIC; } VCDSetArea( p_input, p_area );#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", p_area->i_start, p_area->i_size, p_area->i_tell, p_vcd->cur_lsn ); return VLC_SUCCESS;}/***************************************************************************** VCDEntryPoints: Reads the information about the entry points on the disc and initializes area information with that. Before calling this track information should have been read in. *****************************************************************************/static intVCDEntryPoints( input_thread_t * p_input ){ thread_vcd_data_t * p_vcd; unsigned int i_nb; unsigned int i, i_entry_index = 0; unsigned int i_previous_track = CDIO_INVALID_TRACK; p_vcd = (thread_vcd_data_t *) p_input->p_access_data; i_nb = vcdinfo_get_num_entries(p_vcd->vcd); if (0 == i_nb) return -1; p_vcd->p_entries = malloc( sizeof( lba_t ) * i_nb ); if( p_vcd->p_entries == NULL ) { LOG_ERR ("not enough memory for entry points treatment" ); return -1; } p_vcd->num_entries = 0; for( i = 0 ; i < i_nb ; i++ ) { track_t i_track = vcdinfo_get_track(p_vcd->vcd, i); if( i_track <= p_input->stream.i_area_nb ) { p_vcd->p_entries[i] = vcdinfo_get_entry_lsn(p_vcd->vcd, i); p_input->stream.pp_areas[i_track]->i_part_nb ++; /* if this entry belongs to a new track */ if( i_track != i_previous_track ) { /* i_plugin_data is used to store the first entry of the area*/ p_input->stream.pp_areas[i_track]->i_plugin_data = i_entry_index; i_previous_track = i_track; p_input->stream.pp_areas[i_track]->i_part_nb = 1; } i_entry_index ++; p_vcd->num_entries ++; } else msg_Warn( p_input, "wrong track number found in entry points" ); } p_vcd->b_valid_ep = true; return 0;}/***************************************************************************** * VCDSegments: Reads the information about the segments the disc. *****************************************************************************/static intVCDSegments( input_thread_t * p_input ){ thread_vcd_data_t * p_vcd; unsigned int i; unsigned int num_segments; p_vcd = (thread_vcd_data_t *) p_input->p_access_data; num_segments = p_vcd->num_segments = vcdinfo_get_num_segments(p_vcd->vcd);#define area p_input->stream.pp_areas /* area 0 is reserved for segments. Set Absolute start offset and size */ area[0]->i_plugin_data = 0; input_DelArea( p_input, area[0] ); input_AddArea( p_input, 0, 0 ); area[0]->i_start = (off_t)p_vcd->p_sectors[0] * (off_t)M2F2_SECTOR_SIZE; area[0]->i_size = (off_t)(p_vcd->p_sectors[1] - p_vcd->p_sectors[0]) * (off_t)M2F2_SECTOR_SIZE; /* Default Segment */ area[0]->i_part = 0; /* i_plugin_data is used to store which entry point is the first of the track (area) */ area[0]->i_plugin_data = 0; area[0]->i_part_nb = 0; dbg_print( INPUT_DBG_MRL, "area[0] id: %d, i_start: %lld, i_size: %lld", area[0]->i_id, area[0]->i_start, area[0]->i_size ); if (num_segments == 0) return 0; /* We have one additional segment allocated so we can get the size by subtracting seg[i+1] - seg[i]. */ p_vcd->p_segments = malloc( sizeof( lba_t ) * (num_segments+1) ); if( p_vcd->p_segments == NULL ) { LOG_ERR ("not enough memory for segment treatment" ); return -1; } /* Update the navigation variables without triggering a callback */ 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", _("Segment"), "Adding segment choice"); }#undef area p_vcd->p_segments[num_segments] = p_vcd->p_segments[num_segments-1]+ vcdinfo_get_seg_sector_count(p_vcd->vcd, num_segments-1); return 0;}/***************************************************************************** VCDTracks: initializes area information. Before calling this track information should have been read in. *****************************************************************************/static voidVCDTracks( input_thread_t * p_input ){ thread_vcd_data_t * p_vcd; unsigned int i; p_vcd = (thread_vcd_data_t *) p_input->p_access_data;#define area p_input->stream.pp_areas /* We start area addressing for tracks at 1 since the default area 0 is reserved for segments */ for( i = 1 ; i < p_vcd->num_tracks ; i++ ) { /* Tracks are Program Chains */ input_AddArea( p_input, i, i ); /* Absolute start byte offset and byte size */ area[i]->i_start = (off_t) p_vcd->p_sectors[i] * (off_t)M2F2_SECTOR_SIZE; area[i]->i_size = (off_t)(p_vcd->p_sectors[i+1] - p_vcd->p_sectors[i]) * (off_t)M2F2_SECTOR_SIZE; /* Current entry being played in track */ area[i]->i_part = 0; /* i_plugin_data is used to store which entry point is the first * of the track (area) */ area[i]->i_plugin_data = 0; dbg_print( INPUT_DBG_MRL, "area[%d] id: %d, i_start: %lld, i_size: %lld", i, area[i]->i_id, area[i]->i_start, area[i]->i_size ); }#undef area return ;}/***************************************************************************** VCDLIDs: Reads the LIST IDs from the LOT. *****************************************************************************/static intVCDLIDs( input_thread_t * p_input ){ thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data; p_vcd->num_lids = vcdinfo_get_num_LIDs(p_vcd->vcd); p_vcd->cur_lid = VCDINFO_INVALID_ENTRY; if (vcdinfo_read_psd (p_vcd->vcd)) { vcdinfo_visit_lot (p_vcd->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_vcd->vcd)) vcdinfo_visit_lot (p_vcd->vcd, true);#endif } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL), "num LIDs=%d", p_vcd->num_lids); return 0;}/***************************************************************************** * VCDParse: parse command line *****************************************************************************/static char *VCDParse( input_thread_t * p_input, /*out*/ vcdinfo_itemid_t * p_itemid, /*out*/ bool *play_single_item ){ thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_input->p_access_data; char * psz_parser; char * psz_source; char * psz_next; if ( config_GetInt( p_input, MODULE_STRING "-PBC" ) ) { p_itemid->type=VCDINFO_ITEM_TYPE_LID; p_itemid->num=1; *play_single_item=false; } else { p_itemid->type=VCDINFO_ITEM_TYPE_ENTRY; p_itemid->num=0; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?