📄 access.c
字号:
return p_vcdobj;}/**************************************************************************** Update the "varname" variable to i_num without triggering a callback.****************************************************************************/static voidVCDUpdateVar( access_t *p_access, 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 (p_access) { const vcdplayer_t *p_vcdplayer = (vcdplayer_t *)p_vcd_access->p_sys; 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_access, p_varname, VLC_VAR_SETTEXT, &text, NULL ); } var_Change( p_access, p_varname, i_action, &val, NULL );}/***************************************************************************** * Public routines. *****************************************************************************//***************************************************************************** VCDOpen: open VCD. read in meta-information about VCD: the number of tracks, segments, entries, size and starting information. Then set up state variables so that we read/seek starting at the location specified. On success we return VLC_SUCCESS, on memory exhausted VLC_ENOMEM, and VLC_EGENERIC for some other error. *****************************************************************************/intVCDOpen ( vlc_object_t *p_this ){ access_t *p_access = (access_t *)p_this; vcdplayer_t *p_vcdplayer; char *psz_source; vcdinfo_itemid_t itemid; vlc_bool_t play_single_item = VLC_FALSE; p_access->pf_read = NULL; p_access->pf_block = VCDReadBlock; p_access->pf_control = VCDControl; p_access->pf_seek = VCDSeek; p_access->info.i_update = 0; p_access->info.i_size = 0; p_access->info.i_pos = 0; p_access->info.b_eof = VLC_FALSE; p_access->info.i_title = 0; p_access->info.i_seekpoint = 0; p_vcdplayer = malloc( sizeof(vcdplayer_t) ); if( p_vcdplayer == NULL ) { LOG_ERR ("out of memory" ); return VLC_ENOMEM; } p_vcdplayer->i_debug = config_GetInt( p_this, MODULE_STRING "-debug" ); p_access->p_sys = (access_sys_t *) p_vcdplayer; /* Set where to log errors messages from libcdio. */ p_vcd_access = p_access; cdio_log_set_handler ( cdio_log_handler ); vcd_log_set_handler ( vcd_log_handler ); psz_source = VCDParse( p_access, &itemid, &play_single_item ); if ( NULL == psz_source ) { free( p_vcdplayer ); return( VLC_EGENERIC ); } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "source: %s: mrl: %s", psz_source, p_access->psz_path ); p_vcdplayer->psz_source = strdup(psz_source); p_vcdplayer->i_blocks_per_read = config_GetInt( p_this, MODULE_STRING "-blocks-per-read" ); p_vcdplayer->b_track_length = config_GetInt( p_this, MODULE_STRING "-track-length" ); p_vcdplayer->in_still = VLC_FALSE; p_vcdplayer->play_item.type = VCDINFO_ITEM_TYPE_NOTFOUND; p_vcdplayer->p_input = vlc_object_find( p_access, VLC_OBJECT_INPUT, FIND_PARENT ); p_vcdplayer->p_meta = vlc_meta_New(); p_vcdplayer->p_segments = NULL; p_vcdplayer->p_entries = NULL; /* set up input */ if( !(p_vcdplayer->vcd = vcd_Open( p_this, psz_source )) ) { goto err_exit; } p_vcdplayer->b_svd= (vlc_bool_t) vcdinfo_get_tracksSVD(p_vcdplayer->vcd);; /* Get track information. */ p_vcdplayer->i_tracks = vcdinfo_get_num_tracks(p_vcdplayer->vcd); if( p_vcdplayer->i_tracks < 1 || CDIO_INVALID_TRACK == p_vcdplayer->i_tracks ) { vcdinfo_close( p_vcdplayer->vcd ); LOG_ERR ("no movie tracks found" ); goto err_exit; } /* Build Navigation Title table for the tracks. */ VCDTitles( p_access ); /* Add into the above entry points as "Chapters". */ if( ! VCDEntryPoints( p_access ) ) { msg_Warn( p_access, "could not read entry points, will not use them" ); p_vcdplayer->b_valid_ep = VLC_FALSE; } /* Initialize LID info and add that as a menu item */ if( ! VCDLIDs( p_access ) ) { msg_Warn( p_access, "could not read entry LIDs" ); } /* Do we set PBC (via LID) on? */ p_vcdplayer->i_lid = ( VCDINFO_ITEM_TYPE_LID == itemid.type && p_vcdplayer->i_lids > itemid.num ) ? itemid.num : VCDINFO_INVALID_ENTRY; /* Initialize segment information and add that a "Track". */ VCDSegments( p_access ); vcdplayer_play( p_access, itemid ); p_access->psz_demux = strdup( "ps" );#if FIXED if (play_single_item) VCDFixupPlayList( p_access, p_vcd, psz_source, &itemid, play_single_item );#endif#if FIXED p_vcdplayer->p_intf = intf_Create( p_access, "vcdx" ); p_vcdplayer->p_intf->b_block = VLC_FALSE;#endif p_vcdplayer->p_access = p_access;#ifdef FIXED intf_RunThread( p_vcdplayer->p_intf );#endif free( psz_source ); return VLC_SUCCESS; err_exit: if( p_vcdplayer->p_input ) vlc_object_release( p_vcdplayer->p_input ); free( psz_source ); free( p_vcdplayer ); return VLC_EGENERIC;}/***************************************************************************** * VCDClose: closes VCD releasing allocated memory. *****************************************************************************/voidVCDClose ( vlc_object_t *p_this ){ access_t *p_access = (access_t *)p_this; vcdplayer_t *p_vcdplayer = (vcdplayer_t *)p_access->p_sys; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "VCDClose" ); { unsigned int i; for (i=0 ; i<p_vcdplayer->i_titles; i++) if (p_vcdplayer->p_title[i]) free(p_vcdplayer->p_title[i]->psz_name); } vcdinfo_close( p_vcdplayer->vcd ); if( p_vcdplayer->p_input ) vlc_object_release( p_vcdplayer->p_input ); FREE_AND_NULL( p_vcdplayer->p_entries ); FREE_AND_NULL( p_vcdplayer->p_segments ); FREE_AND_NULL( p_vcdplayer->psz_source ); FREE_AND_NULL( p_vcdplayer->track ); FREE_AND_NULL( p_vcdplayer->segment ); FREE_AND_NULL( p_vcdplayer->entry ); FREE_AND_NULL( p_access->psz_demux ); FREE_AND_NULL( p_vcdplayer ); p_vcd_access = NULL;}/***************************************************************************** * Control: The front-end or vlc engine calls here to ether get * information such as meta information or plugin capabilities or to * issue miscellaneous "set" requests. *****************************************************************************/static int VCDControl( access_t *p_access, int i_query, va_list args ){ vcdplayer_t *p_vcdplayer = (vcdplayer_t *)p_access->p_sys; int *pi_int; int i; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_EVENT), "query %d", i_query ); switch( i_query ) { /* Pass back a copy of meta information that was gathered when we during the Open/Initialize call. */ case ACCESS_GET_META: { vlc_meta_t **pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** ); dbg_print( INPUT_DBG_EVENT, "get meta info" ); if ( p_vcdplayer->p_meta ) { *pp_meta = vlc_meta_Duplicate( p_vcdplayer->p_meta ); dbg_print( INPUT_DBG_META, "%s", "Meta copied" ); } else msg_Warn( p_access, "tried to copy NULL meta info" ); return VLC_SUCCESS; } return VLC_EGENERIC; case ACCESS_CAN_SEEK: case ACCESS_CAN_FASTSEEK: case ACCESS_CAN_PAUSE: case ACCESS_CAN_CONTROL_PACE: { vlc_bool_t *pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); dbg_print( INPUT_DBG_EVENT, "seek/fastseek/pause/can_control_pace" ); *pb_bool = VLC_TRUE; return VLC_SUCCESS; break; } /* */ case ACCESS_GET_MTU: pi_int = (int*)va_arg( args, int * ); *pi_int = (p_vcdplayer->i_blocks_per_read * M2F2_SECTOR_SIZE); dbg_print( INPUT_DBG_EVENT, "GET MTU: %d", *pi_int ); break; case ACCESS_GET_PTS_DELAY: { int64_t *pi_64 = (int64_t*)va_arg( args, int64_t * ); *pi_64 = var_GetInteger( p_access, MODULE_STRING "-caching" ) * MILLISECONDS_PER_SEC; dbg_print( INPUT_DBG_EVENT, "GET PTS DELAY" ); return VLC_SUCCESS; break; } /* */ case ACCESS_SET_PAUSE_STATE: dbg_print( INPUT_DBG_EVENT, "SET PAUSE STATE" ); return VLC_SUCCESS; break; case ACCESS_GET_TITLE_INFO: { unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) + strlen(p_vcdplayer->psz_source) + sizeof("@E999")+3; input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); char *psz_mrl = malloc( psz_mrl_max ); unsigned int i; pi_int = (int*)va_arg( args, int* ); dbg_print( INPUT_DBG_EVENT, "GET TITLE: i_titles %d", p_vcdplayer->i_titles ); if( psz_mrl == NULL ) { msg_Warn( p_access, "out of memory" ); } else { snprintf(psz_mrl, psz_mrl_max, "%s%s", VCD_MRL_PREFIX, p_vcdplayer->psz_source); VCDMetaInfo( p_access, psz_mrl ); free(psz_mrl); } /* Duplicate title info */ if( p_vcdplayer->i_titles == 0 ) { *pi_int = 0; ppp_title = NULL; return VLC_SUCCESS; } *pi_int = p_vcdplayer->i_titles; *ppp_title = malloc( sizeof( input_title_t **) * p_vcdplayer->i_titles ); if (!*ppp_title) return VLC_ENOMEM; for( i = 0; i < p_vcdplayer->i_titles; i++ ) { if ( p_vcdplayer->p_title[i] ) (*ppp_title)[i] = vlc_input_title_Duplicate( p_vcdplayer->p_title[i] ); } } break; case ACCESS_SET_TITLE: i = (int)va_arg( args, int ); dbg_print( INPUT_DBG_EVENT, "set title %d" , i); if( i != p_access->info.i_title ) { vcdinfo_itemid_t itemid; track_t i_track = i+1; unsigned int i_entry = vcdinfo_track_get_entry( p_vcdplayer->vcd, i_track); /* FIXME! For now we are assuming titles are only tracks and that track == title+1 */ itemid.num = i_track; itemid.type = VCDINFO_ITEM_TYPE_TRACK; VCDSetOrigin(p_access, vcdinfo_get_entry_lsn(p_vcdplayer->vcd, i_entry), i_track, &itemid ); } break; case ACCESS_SET_SEEKPOINT: { input_title_t *t = p_vcdplayer->p_title[p_access->info.i_title]; unsigned int i = (unsigned int)va_arg( args, unsigned int ); dbg_print( INPUT_DBG_EVENT, "set seekpoint %d", i ); if( t->i_seekpoint > 0 ) { track_t i_track = p_access->info.i_title+1; lsn_t lsn; /* FIXME! For now we are assuming titles are only tracks and that track == title+1 and we the play item is entries (not tracks or lids). We need to generalize all of this. */ if (i < p_vcdplayer->i_entries) { p_vcdplayer->play_item.num = i; p_vcdplayer->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; lsn = vcdinfo_get_entry_lsn(p_vcdplayer->vcd, i); } else if ( i < p_vcdplayer->i_entries + p_vcdplayer->i_lids ) { p_vcdplayer->play_item.num = i = i - p_vcdplayer->i_entries; p_vcdplayer->play_item.type = VCDINFO_ITEM_TYPE_LID; lsn = 0; } else { p_vcdplayer->play_item.num = i = i - p_vcdplayer->i_entries - p_vcdplayer->i_lids; p_vcdplayer->play_item.type = VCDINFO_ITEM_TYPE_SEGMENT; lsn = vcdinfo_get_seg_lsn(p_vcdplayer->vcd, i); } VCDSetOrigin( p_access, vcdinfo_get_entry_lsn(p_vcdplayer->vcd, i), i_track, &(p_vcdplayer->play_item) ); } return VLC_SUCCESS; } case ACCESS_SET_PRIVATE_ID_STATE: dbg_print( INPUT_DBG_EVENT, "set private id" ); return VLC_EGENERIC; default: msg_Warn( p_access, "unimplemented query in control" ); return VLC_EGENERIC; } return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -