📄 input.c
字号:
/* Look for and add subtitle files */ psz_subtitle = var_GetString( p_input, "sub-file" ); if( *psz_subtitle ) { input_source_t *sub; vlc_value_t count; vlc_value_t list; msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle ); var_Change( p_input, "spu-es", VLC_VAR_CHOICESCOUNT, &count, NULL ); /* */ sub = InputSourceNew( p_input ); if( !InputSourceInit( p_input, sub, psz_subtitle, "subtitle", VLC_FALSE ) ) { TAB_APPEND( p_input->i_slave, p_input->slave, sub ); /* Select the ES */ if( !var_Change( p_input, "spu-es", VLC_VAR_GETLIST, &list, NULL ) ) { if( count.i_int == 0 ) count.i_int++; /* if it was first one, there is disable too */ if( count.i_int < list.p_list->i_count ) { input_ControlPush( p_input, INPUT_CONTROL_SET_ES, &list.p_list->p_values[count.i_int] ); } var_Change( p_input, "spu-es", VLC_VAR_FREELIST, &list, NULL ); } } } var_Get( p_input, "sub-autodetect-file", &val ); if( val.b_bool ) { char *psz_autopath = var_GetString( p_input, "sub-autodetect-path" ); char **subs = subtitles_Detect( p_input, psz_autopath, p_input->input.p_item->psz_uri ); input_source_t *sub; for( i = 0; subs[i] != NULL; i++ ) { if( strcmp( psz_subtitle, subs[i] ) ) { sub = InputSourceNew( p_input ); if( !InputSourceInit( p_input, sub, subs[i], "subtitle", VLC_FALSE ) ) { TAB_APPEND( p_input->i_slave, p_input->slave, sub ); } } free( subs[i] ); } free( subs ); free( psz_autopath ); } free( psz_subtitle ); /* Look for slave */ psz = var_GetString( p_input, "input-slave" ); if( *psz ) { char *psz_delim; input_source_t *slave; while( psz && *psz ) { while( *psz == ' ' || *psz == '#' ) { psz++; } if( ( psz_delim = strchr( psz, '#' ) ) ) { *psz_delim++ = '\0'; } if( *psz == 0 ) { break; } msg_Dbg( p_input, "adding slave input '%s'", psz ); slave = InputSourceNew( p_input ); if( !InputSourceInit( p_input, slave, psz, NULL, VLC_FALSE ) ) { TAB_APPEND( p_input->i_slave, p_input->slave, slave ); } psz = psz_delim; } } if( psz ) free( psz ); } else { p_input->i_start = 0; p_input->i_start = 0; } /* Set up es_out */ if( !b_quick ) { es_out_Control( p_input->p_es_out, ES_OUT_SET_ACTIVE, VLC_TRUE ); i_es_out_mode = ES_OUT_MODE_AUTO; val.p_list = NULL; if( p_input->p_sout ) { var_Get( p_input, "sout-all", &val ); if ( val.b_bool ) { i_es_out_mode = ES_OUT_MODE_ALL; val.p_list = NULL; } else { var_Get( p_input, "programs", &val ); if ( val.p_list && val.p_list->i_count ) { i_es_out_mode = ES_OUT_MODE_PARTIAL; /* Note : we should remove the "program" callback. */ } else var_Change( p_input, "programs", VLC_VAR_FREELIST, &val, NULL ); } } es_out_Control( p_input->p_es_out, ES_OUT_SET_MODE, i_es_out_mode ); /* Inform the demuxer about waited group (needed only for DVB) */ if( i_es_out_mode == ES_OUT_MODE_ALL ) { demux2_Control( p_input->input.p_demux, DEMUX_SET_GROUP, -1, NULL ); } else if( i_es_out_mode == ES_OUT_MODE_PARTIAL ) { demux2_Control( p_input->input.p_demux, DEMUX_SET_GROUP, -1, val.p_list ); } else { demux2_Control( p_input->input.p_demux, DEMUX_SET_GROUP, (int) var_GetInteger( p_input, "program" ), NULL ); } if( p_input->p_sout ) { if( p_input->p_sout->i_out_pace_nocontrol > 0 ) { p_input->b_out_pace_control = VLC_FALSE; } else { p_input->b_out_pace_control = VLC_TRUE; } if( p_input->b_can_pace_control && p_input->b_out_pace_control ) { /* We don't want a high input priority here or we'll * end-up sucking up all the CPU time */ vlc_thread_set_priority( p_input, VLC_THREAD_PRIORITY_LOW ); } msg_Dbg( p_input, "starting in %s mode", p_input->b_out_pace_control ? "asynch" : "synch" ); } } /* Get meta data from users */ p_meta_tmp = InputMetaUser( p_input ); /* Get meta data from master input */ if( demux2_Control( p_input->input.p_demux, DEMUX_GET_META, &p_meta ) ) p_meta = NULL; /* Merge them */ if( p_meta == NULL ) { p_meta = p_meta_tmp; } else if( p_meta_tmp ) { vlc_meta_Merge( p_meta, p_meta_tmp ); vlc_meta_Delete( p_meta_tmp ); } /* Access_file does not give any meta, and there are no slave */ if( !b_quick ) { if( !p_input->input.p_access || access2_Control( p_input->input.p_access, ACCESS_GET_META, &p_meta_tmp)) p_meta_tmp = NULL; if( p_meta == NULL ) { p_meta = p_meta_tmp; } else if( p_meta_tmp ) { vlc_meta_Merge( p_meta, p_meta_tmp ); vlc_meta_Delete( p_meta_tmp ); } /* Get meta data from slave input */ for( i = 0; i < p_input->i_slave; i++ ) { vlc_meta_t *p_meta_slave; if( !demux2_Control( p_input->slave[i]->p_demux, DEMUX_GET_META, &p_meta_slave ) ) { if( p_meta == NULL ) { p_meta = p_meta_slave; } else if( p_meta_slave ) { vlc_meta_Merge( p_meta, p_meta_slave ); vlc_meta_Delete( p_meta_slave ); } } if( p_input->slave[i]->p_access && !access2_Control( p_input->slave[i]->p_access, ACCESS_GET_META, &p_meta_slave ) ) { if( p_meta == NULL ) { p_meta = p_meta_slave; } else if( p_meta_slave ) { vlc_meta_Merge( p_meta, p_meta_slave ); vlc_meta_Delete( p_meta_slave ); } } } } p_input->p_meta = p_meta; UpdateMeta( p_input, b_quick ); if( !b_quick ) { msg_Dbg( p_input, "`%s' successfully opened", p_input->input.p_item->psz_uri ); } /* Trigger intf update for this item */ /* Playlist has a callback on this variable and will forward * it to intf */ var_SetInteger( p_input, "item-change", p_input->input.p_item->i_id ); /* initialization is complete */ p_input->i_state = PLAYING_S; val.i_int = PLAYING_S; var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); return VLC_SUCCESS;error: if( p_input->p_es_out ) input_EsOutDelete( p_input->p_es_out ); if( p_input->p_sout ) sout_DeleteInstance( p_input->p_sout ); /* Mark them deleted */ p_input->input.p_demux = NULL; p_input->input.p_stream = NULL; p_input->input.p_access = NULL; p_input->p_es_out = NULL; p_input->p_sout = NULL; return VLC_EGENERIC;}/***************************************************************************** * Error: RunThread() error loop ***************************************************************************** * This function is called when an error occurred during thread main's loop. *****************************************************************************/static void Error( input_thread_t *p_input ){ while( !p_input->b_die ) { /* Sleep a while */ msleep( INPUT_IDLE_SLEEP ); }}/***************************************************************************** * End: end the input thread *****************************************************************************/static void End( input_thread_t * p_input ){ vlc_value_t val; int i; msg_Dbg( p_input, "closing input" ); /* We are at the end */ p_input->i_state = END_S; val.i_int = END_S; var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); /* Clean control variables */ input_ControlVarClean( p_input ); /* Clean up master */ InputSourceClean( p_input, &p_input->input ); /* Delete slave */ for( i = 0; i < p_input->i_slave; i++ ) { InputSourceClean( p_input, p_input->slave[i] ); free( p_input->slave[i] ); } if( p_input->slave ) free( p_input->slave ); /* Unload all modules */ if( p_input->p_es_out ) input_EsOutDelete( p_input->p_es_out ); /* Close optional stream output instance */ if( p_input->p_sout ) { vlc_object_t *p_pl = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); vlc_value_t keep; if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool && p_pl ) { /* attach sout to the playlist */ msg_Warn( p_input, "keeping sout" ); vlc_object_detach( p_input->p_sout ); vlc_object_attach( p_input->p_sout, p_pl ); } else { msg_Warn( p_input, "destroying sout" ); sout_DeleteInstance( p_input->p_sout ); } if( p_pl ) vlc_object_release( p_pl ); } /* Delete meta */ if( p_input->p_meta ) vlc_meta_Delete( p_input->p_meta ); /* Tell we're dead */ p_input->b_dead = VLC_TRUE;}/***************************************************************************** * Control *****************************************************************************/static inline int ControlPopNoLock( input_thread_t *p_input, int *pi_type, vlc_value_t *p_val ){ if( p_input->i_control <= 0 ) { return VLC_EGENERIC; } *pi_type = p_input->control[0].i_type; *p_val = p_input->control[0].val; p_input->i_control--; if( p_input->i_control > 0 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -