📄 input.c
字号:
es_out_Control( p_input->p->p_es_out, ES_OUT_SET_ACTIVE, false ); es_out_Control( p_input->p->p_es_out, ES_OUT_SET_MODE, ES_OUT_MODE_NONE ); var_Create( p_input, "bit-rate", VLC_VAR_INTEGER ); var_Create( p_input, "sample-rate", VLC_VAR_INTEGER ); if( InputSourceInit( p_input, &p_input->p->input, p_input->p->input.p_item->psz_uri, NULL ) ) { goto error; } InitTitle( p_input ); /* Load master infos */ /* Init length */ if( !demux_Control( p_input->p->input.p_demux, DEMUX_GET_LENGTH, &val.i_time ) && val.i_time > 0 ) { var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); UpdateItemLength( p_input, val.i_time ); } else { val.i_time = input_item_GetDuration( p_input->p->input.p_item ); if( val.i_time > 0 ) { /* fallback: gets length from metadata */ var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); UpdateItemLength( p_input, val.i_time ); } } StartTitle( p_input ); InitPrograms( p_input ); if( !p_input->b_preparsing && p_input->p->p_sout ) { p_input->p->b_out_pace_control = (p_input->p->p_sout->i_out_pace_nocontrol > 0); if( p_input->b_can_pace_control && p_input->p->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->p->b_out_pace_control ? "async" : "sync" ); } p_meta = vlc_meta_New(); /* Get meta data from users */ InputMetaUser( p_input, p_meta ); /* Get meta data from master input */ DemuxMeta( p_input, p_meta, p_input->p->input.p_demux ); /* Access_file does not give any meta, and there are no slave */ AccessMeta( p_input, p_meta ); InputUpdateMeta( p_input, p_meta ); if( !p_input->b_preparsing ) { msg_Dbg( p_input, "`%s' successfully opened", p_input->p->input.p_item->psz_uri ); } /* initialization is complete */ input_ChangeState( p_input, PLAYING_S ); return VLC_SUCCESS;error: input_ChangeState( p_input, ERROR_S ); if( p_input->p->p_es_out ) input_EsOutDelete( p_input->p->p_es_out );#ifdef ENABLE_SOUT if( p_input->p->p_sout ) { vlc_object_detach( p_input->p->p_sout ); sout_DeleteInstance( p_input->p->p_sout ); }#endif if( !p_input->b_preparsing && libvlc_stats (p_input) ) {#define EXIT_COUNTER( c ) do { if( p_input->p->counters.p_##c ) \ stats_CounterClean( p_input->p->counters.p_##c );\ p_input->p->counters.p_##c = NULL; } while(0) EXIT_COUNTER( read_bytes ); EXIT_COUNTER( read_packets ); EXIT_COUNTER( demux_read ); EXIT_COUNTER( input_bitrate ); EXIT_COUNTER( demux_bitrate ); EXIT_COUNTER( played_abuffers ); EXIT_COUNTER( lost_abuffers ); EXIT_COUNTER( displayed_pictures ); EXIT_COUNTER( lost_pictures ); EXIT_COUNTER( decoded_audio ); EXIT_COUNTER( decoded_video ); EXIT_COUNTER( decoded_sub ); if( p_input->p->p_sout ) { EXIT_COUNTER( sout_sent_packets ); EXIT_COUNTER (sout_sent_bytes ); EXIT_COUNTER( sout_send_bitrate ); }#undef EXIT_COUNTER } /* Mark them deleted */ p_input->p->input.p_demux = NULL; p_input->p->input.p_stream = NULL; p_input->p->input.p_access = NULL; p_input->p->p_es_out = NULL; p_input->p->p_sout = NULL; return VLC_EGENERIC;}/***************************************************************************** * WaitDie: Wait until we are asked to die. ***************************************************************************** * This function is called when an error occurred during thread main's loop. *****************************************************************************/static void WaitDie( input_thread_t *p_input ){ input_ChangeState( p_input, p_input->b_error ? ERROR_S : END_S ); 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 ){ int i; /* We are at the end */ input_ChangeState( p_input, END_S ); /* Clean control variables */ input_ControlVarStop( p_input ); /* Clean up master */ InputSourceClean( &p_input->p->input ); /* Delete slave */ for( i = 0; i < p_input->p->i_slave; i++ ) { InputSourceClean( p_input->p->slave[i] ); free( p_input->p->slave[i] ); } free( p_input->p->slave ); /* Unload all modules */ if( p_input->p->p_es_out ) input_EsOutDelete( p_input->p->p_es_out ); if( !p_input->b_preparsing ) {#define CL_CO( c ) stats_CounterClean( p_input->p->counters.p_##c ); p_input->p->counters.p_##c = NULL; if( libvlc_stats (p_input) ) { libvlc_priv_t *priv = libvlc_priv (p_input->p_libvlc); /* make sure we are up to date */ stats_ComputeInputStats( p_input, p_input->p->input.p_item->p_stats ); if( priv->p_stats_computer == p_input ) { stats_ComputeGlobalStats( p_input->p_libvlc, p_input->p_libvlc->p_stats ); priv->p_stats_computer = NULL; } CL_CO( read_bytes ); CL_CO( read_packets ); CL_CO( demux_read ); CL_CO( input_bitrate ); CL_CO( demux_bitrate ); CL_CO( played_abuffers ); CL_CO( lost_abuffers ); CL_CO( displayed_pictures ); CL_CO( lost_pictures ); CL_CO( decoded_audio) ; CL_CO( decoded_video ); CL_CO( decoded_sub) ; } /* Close optional stream output instance */ if( p_input->p->p_sout ) { CL_CO( sout_sent_packets ); CL_CO( sout_sent_bytes ); CL_CO( sout_send_bitrate ); vlc_object_detach( p_input->p->p_sout ); }#undef CL_CO } if( p_input->p->i_attachment > 0 ) { for( i = 0; i < p_input->p->i_attachment; i++ ) vlc_input_attachment_Delete( p_input->p->attachment[i] ); TAB_CLEAN( p_input->p->i_attachment, p_input->p->attachment ); } /* Tell we're dead */ p_input->b_dead = true;}/***************************************************************************** * Control *****************************************************************************/static inline int ControlPopNoLock( input_thread_t *p_input, int *pi_type, vlc_value_t *p_val ){ if( p_input->p->i_control <= 0 ) { return VLC_EGENERIC; } *pi_type = p_input->p->control[0].i_type; *p_val = p_input->p->control[0].val; p_input->p->i_control--; if( p_input->p->i_control > 0 ) { int i; for( i = 0; i < p_input->p->i_control; i++ ) { p_input->p->control[i].i_type = p_input->p->control[i+1].i_type; p_input->p->control[i].val = p_input->p->control[i+1].val; } } return VLC_SUCCESS;}static void ControlReduce( input_thread_t *p_input ){ int i; if( !p_input ) return; for( i = 1; i < p_input->p->i_control; i++ ) { const int i_lt = p_input->p->control[i-1].i_type; const int i_ct = p_input->p->control[i].i_type; /* XXX We can't merge INPUT_CONTROL_SET_ES *//* msg_Dbg( p_input, "[%d/%d] l=%d c=%d", i, p_input->p->i_control, i_lt, i_ct );*/ if( i_lt == i_ct && ( i_ct == INPUT_CONTROL_SET_STATE || i_ct == INPUT_CONTROL_SET_RATE || i_ct == INPUT_CONTROL_SET_POSITION || i_ct == INPUT_CONTROL_SET_TIME || i_ct == INPUT_CONTROL_SET_PROGRAM || i_ct == INPUT_CONTROL_SET_TITLE || i_ct == INPUT_CONTROL_SET_SEEKPOINT || i_ct == INPUT_CONTROL_SET_BOOKMARK ) ) { int j;// msg_Dbg( p_input, "merged at %d", i ); /* Remove the i-1 */ for( j = i; j < p_input->p->i_control; j++ ) p_input->p->control[j-1] = p_input->p->control[j]; p_input->p->i_control--; } else { /* TODO but that's not that important - merge SET_X with SET_X_CMD - remove SET_SEEKPOINT/SET_POSITION/SET_TIME before a SET_TITLE - remove SET_SEEKPOINT/SET_POSITION/SET_TIME before another among them - ? */ } }}static bool Control( input_thread_t *p_input, int i_type, vlc_value_t val ){ bool b_force_update = false; if( !p_input ) return b_force_update; switch( i_type ) { case INPUT_CONTROL_SET_DIE: msg_Dbg( p_input, "control: stopping input" ); /* Mark all submodules to die */ ObjectKillChildrens( p_input, VLC_OBJECT(p_input) ); break; case INPUT_CONTROL_SET_POSITION: case INPUT_CONTROL_SET_POSITION_OFFSET: { double f_pos; if( i_type == INPUT_CONTROL_SET_POSITION ) { f_pos = val.f_float; } else { /* Should not fail */ demux_Control( p_input->p->input.p_demux, DEMUX_GET_POSITION, &f_pos ); f_pos += val.f_float; } if( f_pos < 0.0 ) f_pos = 0.0; if( f_pos > 1.0 ) f_pos = 1.0; /* Reset the decoders states and clock sync (before calling the demuxer */ input_EsOutChangePosition( p_input->p->p_es_out ); if( demux_Control( p_input->p->input.p_demux, DEMUX_SET_POSITION, f_pos ) ) { msg_Err( p_input, "INPUT_CONTROL_SET_POSITION(_OFFSET) " "%2.1f%% failed", f_pos * 100 ); } else { if( p_input->p->i_slave > 0 ) SlaveSeek( p_input ); b_force_update = true; } break; } case INPUT_CONTROL_SET_TIME: case INPUT_CONTROL_SET_TIME_OFFSET: { int64_t i_time; int i_ret; if( i_type == INPUT_CONTROL_SET_TIME ) { i_time = val.i_time; } else { /* Should not fail */ demux_Control( p_input->p->input.p_demux, DEMUX_GET_TIME, &i_time ); i_time += val.i_time; } if( i_time < 0 ) i_time = 0; /* Reset the decoders states and clock sync (before calling the demuxer */ input_EsOutChangePosition( p_input->p->p_es_out ); i_ret = demux_Control( p_input->p->input.p_demux, DEMUX_SET_TIME, i_time ); if( i_ret ) { int64_t i_length; /* Emulate it with a SET_POS */ demux_Control( p_input->p->input.p_demux, DEMUX_GET_LENGTH, &i_length ); if( i_length > 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -