Commit 920692ff authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

input: Split Init() into multiple subfunctions to try to isolate the different...

input: Split Init() into multiple subfunctions to try to isolate the different part of the function.
parent f94a2f9c
...@@ -91,6 +91,7 @@ static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item, ...@@ -91,6 +91,7 @@ static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item,
static void SoutKeep( sout_instance_t * ); static void SoutKeep( sout_instance_t * );
static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_demux ); static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_demux );
static void AccessMeta( input_thread_t * p_input, vlc_meta_t *p_meta );
static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment, static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment,
int i_new, input_attachment_t **pp_new ); int i_new, input_attachment_t **pp_new );
...@@ -768,408 +769,437 @@ static void MainLoop( input_thread_t *p_input ) ...@@ -768,408 +769,437 @@ static void MainLoop( input_thread_t *p_input )
} }
} }
static int Init( input_thread_t * p_input ) static void InitStatistics( input_thread_t * p_input )
{ {
char *psz; if( p_input->b_preparsing ) return;
char *psz_subtitle;
vlc_value_t val;
double f_fps;
vlc_meta_t *p_meta;
int i_es_out_mode;
int i, i_delay;
for( i = 0; i < p_input->p->input.p_item->i_options; i++ ) /* Prepare statistics */
{ #define INIT_COUNTER( c, type, compute ) p_input->p->counters.p_##c = \
if( !strncmp( p_input->p->input.p_item->ppsz_options[i], "meta-file", 9 ) ) stats_CounterCreate( p_input, VLC_VAR_##type, STATS_##compute);
{ if( p_input->p_libvlc->b_stats )
msg_Dbg( p_input, "Input is a meta file: disabling unneeded options" ); {
var_SetString( p_input, "sout", "" ); INIT_COUNTER( read_bytes, INTEGER, COUNTER );
var_SetBool( p_input, "sout-all", false ); INIT_COUNTER( read_packets, INTEGER, COUNTER );
var_SetString( p_input, "input-slave", "" ); INIT_COUNTER( demux_read, INTEGER, COUNTER );
var_SetInteger( p_input, "input-repeat", 0 ); INIT_COUNTER( input_bitrate, FLOAT, DERIVATIVE );
var_SetString( p_input, "sub-file", "" ); INIT_COUNTER( demux_bitrate, FLOAT, DERIVATIVE );
var_SetBool( p_input, "sub-autodetect-file", false ); INIT_COUNTER( played_abuffers, INTEGER, COUNTER );
} INIT_COUNTER( lost_abuffers, INTEGER, COUNTER );
INIT_COUNTER( displayed_pictures, INTEGER, COUNTER );
INIT_COUNTER( lost_pictures, INTEGER, COUNTER );
INIT_COUNTER( decoded_audio, INTEGER, COUNTER );
INIT_COUNTER( decoded_video, INTEGER, COUNTER );
INIT_COUNTER( decoded_sub, INTEGER, COUNTER );
p_input->p->counters.p_sout_send_bitrate = NULL;
p_input->p->counters.p_sout_sent_packets = NULL;
p_input->p->counters.p_sout_sent_bytes = NULL;
if( p_input->p->counters.p_demux_bitrate )
p_input->p->counters.p_demux_bitrate->update_interval = 1000000;
if( p_input->p->counters.p_input_bitrate )
p_input->p->counters.p_input_bitrate->update_interval = 1000000;
} }
}
if( !p_input->b_preparsing ) static int InitSout( input_thread_t * p_input )
{
char *psz;
if( p_input->b_preparsing ) return VLC_SUCCESS;
/* Find a usable sout and attach it to p_input */
psz = var_GetNonEmptyString( p_input, "sout" );
if( psz && strncasecmp( p_input->p->input.p_item->psz_uri, "vlc:", 4 ) )
{ {
/* Prepare statistics */ /* Check the validity of the provided sout */
#define INIT_COUNTER( c, type, compute ) p_input->p->counters.p_##c = \ if( p_input->p->p_sout )
stats_CounterCreate( p_input, VLC_VAR_##type, STATS_##compute);
if( p_input->p_libvlc->b_stats )
{ {
INIT_COUNTER( read_bytes, INTEGER, COUNTER ); if( strcmp( p_input->p->p_sout->psz_sout, psz ) )
INIT_COUNTER( read_packets, INTEGER, COUNTER );
INIT_COUNTER( demux_read, INTEGER, COUNTER );
INIT_COUNTER( input_bitrate, FLOAT, DERIVATIVE );
INIT_COUNTER( demux_bitrate, FLOAT, DERIVATIVE );
INIT_COUNTER( played_abuffers, INTEGER, COUNTER );
INIT_COUNTER( lost_abuffers, INTEGER, COUNTER );
INIT_COUNTER( displayed_pictures, INTEGER, COUNTER );
INIT_COUNTER( lost_pictures, INTEGER, COUNTER );
INIT_COUNTER( decoded_audio, INTEGER, COUNTER );
INIT_COUNTER( decoded_video, INTEGER, COUNTER );
INIT_COUNTER( decoded_sub, INTEGER, COUNTER );
p_input->p->counters.p_sout_send_bitrate = NULL;
p_input->p->counters.p_sout_sent_packets = NULL;
p_input->p->counters.p_sout_sent_bytes = NULL;
if( p_input->p->counters.p_demux_bitrate )
p_input->p->counters.p_demux_bitrate->update_interval = 1000000;
if( p_input->p->counters.p_input_bitrate )
p_input->p->counters.p_input_bitrate->update_interval = 1000000;
}
/* Find a usable sout and attach it to p_input */
psz = var_GetNonEmptyString( p_input, "sout" );
if( psz && strncasecmp( p_input->p->input.p_item->psz_uri, "vlc:", 4 ) )
{
/* Check the validity of the provided sout */
if( p_input->p->p_sout )
{ {
if( strcmp( p_input->p->p_sout->psz_sout, psz ) ) msg_Dbg( p_input, "destroying unusable sout" );
{
msg_Dbg( p_input, "destroying unusable sout" );
sout_DeleteInstance( p_input->p->p_sout ); sout_DeleteInstance( p_input->p->p_sout );
p_input->p->p_sout = NULL; p_input->p->p_sout = NULL;
}
}
if( p_input->p->p_sout )
{
/* Reuse it */
msg_Dbg( p_input, "sout keep: reusing sout" );
msg_Dbg( p_input, "sout keep: you probably want to use "
"gather stream_out" );
vlc_object_attach( p_input->p->p_sout, p_input );
}
else
{
/* Create a new one */
p_input->p->p_sout = sout_NewInstance( p_input, psz );
if( !p_input->p->p_sout )
{
input_ChangeState( p_input, ERROR_S );
msg_Err( p_input, "cannot start stream output instance, " \
"aborting" );
free( psz );
return VLC_EGENERIC;
}
} }
}
if( p_input->p_libvlc->b_stats ) if( p_input->p->p_sout )
{
/* Reuse it */
msg_Dbg( p_input, "sout keep: reusing sout" );
msg_Dbg( p_input, "sout keep: you probably want to use "
"gather stream_out" );
vlc_object_attach( p_input->p->p_sout, p_input );
}
else
{
/* Create a new one */
p_input->p->p_sout = sout_NewInstance( p_input, psz );
if( !p_input->p->p_sout )
{ {
INIT_COUNTER( sout_sent_packets, INTEGER, COUNTER ); input_ChangeState( p_input, ERROR_S );
INIT_COUNTER (sout_sent_bytes, INTEGER, COUNTER ); msg_Err( p_input, "cannot start stream output instance, " \
INIT_COUNTER( sout_send_bitrate, FLOAT, DERIVATIVE ); "aborting" );
if( p_input->p->counters.p_sout_send_bitrate ) free( psz );
p_input->p->counters.p_sout_send_bitrate->update_interval = return VLC_EGENERIC;
1000000;
} }
} }
else if( p_input->p->p_sout ) if( p_input->p_libvlc->b_stats )
{ {
msg_Dbg( p_input, "destroying useless sout" ); INIT_COUNTER( sout_sent_packets, INTEGER, COUNTER );
INIT_COUNTER (sout_sent_bytes, INTEGER, COUNTER );
sout_DeleteInstance( p_input->p->p_sout ); INIT_COUNTER( sout_send_bitrate, FLOAT, DERIVATIVE );
p_input->p->p_sout = NULL; if( p_input->p->counters.p_sout_send_bitrate )
p_input->p->counters.p_sout_send_bitrate->update_interval =
1000000;
} }
free( psz );
} }
else if( p_input->p->p_sout )
/* Create es out */
p_input->p->p_es_out = input_EsOutNew( p_input, p_input->p->i_rate );
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; msg_Dbg( p_input, "destroying useless sout" );
sout_DeleteInstance( p_input->p->p_sout );
p_input->p->p_sout = NULL;
} }
free( psz );
/* Create global title (from master) */ return VLC_SUCCESS;
if( !p_input->b_preparsing ) }
{
p_input->p->i_title = p_input->p->input.i_title;
p_input->p->title = p_input->p->input.title;
p_input->p->i_title_offset = p_input->p->input.i_title_offset;
p_input->p->i_seekpoint_offset = p_input->p->input.i_seekpoint_offset;
if( p_input->p->i_title > 0 )
{
/* Setup variables */
input_ControlVarNavigation( p_input );
input_ControlVarTitle( p_input, 0 );
}
/* Global flag */ static void InitTitle( input_thread_t * p_input )
p_input->b_can_pace_control = p_input->p->input.b_can_pace_control; {
p_input->p->b_can_pause = p_input->p->input.b_can_pause; vlc_value_t val;
p_input->p->b_can_rate_control = p_input->p->input.b_can_rate_control;
/* Fix pts delay */ if( p_input->b_preparsing ) return;
if( p_input->i_pts_delay < 0 )
p_input->i_pts_delay = 0;
/* If the desynchronisation requested by the user is < 0, we need to /* Create global title (from master) */
* cache more data. */ p_input->p->i_title = p_input->p->input.i_title;
var_Get( p_input, "audio-desync", &val ); p_input->p->title = p_input->p->input.title;
if( val.i_int < 0 ) p_input->i_pts_delay -= (val.i_int * 1000); p_input->p->i_title_offset = p_input->p->input.i_title_offset;
p_input->p->i_seekpoint_offset = p_input->p->input.i_seekpoint_offset;
if( p_input->p->i_title > 0 )
{
/* Setup variables */
input_ControlVarNavigation( p_input );
input_ControlVarTitle( p_input, 0 );
}
/* Global flag */
p_input->b_can_pace_control = p_input->p->input.b_can_pace_control;
p_input->p->b_can_pause = p_input->p->input.b_can_pause;
p_input->p->b_can_rate_control = p_input->p->input.b_can_rate_control;
/* Fix pts delay */
if( p_input->i_pts_delay < 0 )
p_input->i_pts_delay = 0;
/* If the desynchronisation requested by the user is < 0, we need to
* cache more data. */
var_Get( p_input, "audio-desync", &val );
if( val.i_int < 0 ) p_input->i_pts_delay -= (val.i_int * 1000);
/* Update cr_average depending on the caching */
p_input->p->input.i_cr_average *= (10 * p_input->i_pts_delay / 200000);
p_input->p->input.i_cr_average /= 10;
if( p_input->p->input.i_cr_average < 10 ) p_input->p->input.i_cr_average = 10;
}
/* Update cr_average depending on the caching */ static void StartTitle( input_thread_t * p_input )
p_input->p->input.i_cr_average *= (10 * p_input->i_pts_delay / 200000); {
p_input->p->input.i_cr_average /= 10; double f_fps;
if( p_input->p->input.i_cr_average < 10 ) p_input->p->input.i_cr_average = 10; vlc_value_t val;
} int i, i_delay;
char *psz;
char *psz_subtitle;
/* Load master infos */ /* Start title/chapter */
/* Init length */
if( !demux_Control( p_input->p->input.p_demux, DEMUX_GET_LENGTH, if( p_input->b_preparsing )
&val.i_time ) && val.i_time > 0 )
{ {
var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); p_input->p->i_start = 0;
UpdateItemLength( p_input, val.i_time ); return;
} }
else
val.i_int = p_input->p->input.i_title_start -
p_input->p->input.i_title_offset;
if( val.i_int > 0 && val.i_int < p_input->p->input.i_title )
input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE, &val );
val.i_int = p_input->p->input.i_seekpoint_start -
p_input->p->input.i_seekpoint_offset;
if( val.i_int > 0 /* TODO: check upper boundary */ )
input_ControlPush( p_input, INPUT_CONTROL_SET_SEEKPOINT, &val );
/* Start time*/
/* Set start time */
p_input->p->i_start = I64C(1000000) * var_GetInteger( p_input, "start-time" );
p_input->p->i_stop = I64C(1000000) * var_GetInteger( p_input, "stop-time" );
p_input->p->i_run = I64C(1000000) * var_GetInteger( p_input, "run-time" );
if( p_input->p->i_run < 0 )
{ {
val.i_time = input_item_GetDuration( p_input->p->input.p_item ); msg_Warn( p_input, "invalid run-time ignored" );
if( val.i_time > 0 ) p_input->p->i_run = 0;
{ /* fallback: gets length from metadata */
var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
UpdateItemLength( p_input, val.i_time );
}
} }
/* Start title/chapter */ if( p_input->p->i_start > 0 )
if( !p_input->b_preparsing )
{ {
val.i_int = p_input->p->input.i_title_start - if( p_input->p->i_start >= val.i_time )
p_input->p->input.i_title_offset;
if( val.i_int > 0 && val.i_int < p_input->p->input.i_title )
input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE, &val );
val.i_int = p_input->p->input.i_seekpoint_start -
p_input->p->input.i_seekpoint_offset;
if( val.i_int > 0 /* TODO: check upper boundary */ )
input_ControlPush( p_input, INPUT_CONTROL_SET_SEEKPOINT, &val );
/* Start time*/
/* Set start time */
p_input->p->i_start = I64C(1000000) * var_GetInteger( p_input, "start-time" );
p_input->p->i_stop = I64C(1000000) * var_GetInteger( p_input, "stop-time" );
p_input->p->i_run = I64C(1000000) * var_GetInteger( p_input, "run-time" );
if( p_input->p->i_run < 0 )
{ {
msg_Warn( p_input, "invalid run-time ignored" ); msg_Warn( p_input, "invalid start-time ignored" );
p_input->p->i_run = 0;
} }
else
if( p_input->p->i_start > 0 )
{ {
if( p_input->p->i_start >= val.i_time ) vlc_value_t s;
{
msg_Warn( p_input, "invalid start-time ignored" );
}
else
{
vlc_value_t s;
msg_Dbg( p_input, "starting at time: %ds", msg_Dbg( p_input, "starting at time: %ds",
(int)( p_input->p->i_start / I64C(1000000) ) ); (int)( p_input->p->i_start / I64C(1000000) ) );
s.i_time = p_input->p->i_start; s.i_time = p_input->p->i_start;
input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, &s ); input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, &s );
}
} }
if( p_input->p->i_stop > 0 && p_input->p->i_stop <= p_input->p->i_start ) }
{ if( p_input->p->i_stop > 0 && p_input->p->i_stop <= p_input->p->i_start )
msg_Warn( p_input, "invalid stop-time ignored" ); {
p_input->p->i_stop = 0; msg_Warn( p_input, "invalid stop-time ignored" );
} p_input->p->i_stop = 0;
}
/* Load subtitles */
/* Get fps and set it if not already set */
if( !demux_Control( p_input->p->input.p_demux, DEMUX_GET_FPS, &f_fps ) &&
f_fps > 1.0 )
{
float f_requested_fps;
var_Create( p_input, "sub-original-fps", VLC_VAR_FLOAT ); /* Load subtitles */
var_SetFloat( p_input, "sub-original-fps", f_fps ); /* Get fps and set it if not already set */
if( !demux_Control( p_input->p->input.p_demux, DEMUX_GET_FPS, &f_fps ) &&
f_fps > 1.0 )
{
float f_requested_fps;
f_requested_fps = var_CreateGetFloat( p_input, "sub-fps" ); var_Create( p_input, "sub-original-fps", VLC_VAR_FLOAT );
if( f_requested_fps != f_fps ) var_SetFloat( p_input, "sub-original-fps", f_fps );
{
var_Create( p_input, "sub-fps", VLC_VAR_FLOAT|
VLC_VAR_DOINHERIT );
var_SetFloat( p_input, "sub-fps", f_requested_fps );
}
}
i_delay = var_CreateGetInteger( p_input, "sub-delay" ); f_requested_fps = var_CreateGetFloat( p_input, "sub-fps" );
if( i_delay != 0 ) if( f_requested_fps != f_fps )
{ {
var_SetTime( p_input, "spu-delay", (mtime_t)i_delay * 100000 ); var_Create( p_input, "sub-fps", VLC_VAR_FLOAT|
VLC_VAR_DOINHERIT );
var_SetFloat( p_input, "sub-fps", f_requested_fps );
} }
}
/* Look for and add subtitle files */ i_delay = var_CreateGetInteger( p_input, "sub-delay" );
psz_subtitle = var_GetNonEmptyString( p_input, "sub-file" ); if( i_delay != 0 )
if( psz_subtitle != NULL ) {
var_SetTime( p_input, "spu-delay", (mtime_t)i_delay * 100000 );
}
/* Look for and add subtitle files */
psz_subtitle = var_GetNonEmptyString( p_input, "sub-file" );
if( psz_subtitle != NULL )
{
msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle );
input_AddSubtitles( p_input, psz_subtitle, false );
}
var_Get( p_input, "sub-autodetect-file", &val );
if( val.b_bool )
{
char *psz_autopath = var_GetNonEmptyString( p_input, "sub-autodetect-path" );
char **subs = subtitles_Detect( p_input, psz_autopath,
p_input->p->input.p_item->psz_uri );
input_source_t *sub;
i = 0;
if( psz_autopath == NULL )
psz_autopath = strdup("");
/* Try to autoselect the first autodetected subtitles file
* if no subtitles file was specified */
if( ( psz_subtitle == NULL ) && subs && subs[0] )
{ {
msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle ); input_AddSubtitles( p_input, subs[0], false );
input_AddSubtitles( p_input, psz_subtitle, false ); free( subs[0] );
i = 1;
} }
var_Get( p_input, "sub-autodetect-file", &val ); /* Then, just add the following subtitles files */
if( val.b_bool ) for( ; subs && subs[i]; i++ )
{ {
char *psz_autopath = var_GetNonEmptyString( p_input, "sub-autodetect-path" ); if( !psz_subtitle || strcmp( psz_subtitle, subs[i] ) )
char **subs = subtitles_Detect( p_input, psz_autopath,
p_input->p->input.p_item->psz_uri );
input_source_t *sub;
i = 0;
if( psz_autopath == NULL )
psz_autopath = strdup("");
/* Try to autoselect the first autodetected subtitles file
* if no subtitles file was specified */
if( ( psz_subtitle == NULL ) && subs && subs[0] )
{ {
input_AddSubtitles( p_input, subs[0], false ); sub = InputSourceNew( p_input );
free( subs[0] ); if( !InputSourceInit( p_input, sub, subs[i], "subtitle" ) )
i = 1;
}
/* Then, just add the following subtitles files */
for( ; subs && subs[i]; i++ )
{
if( !psz_subtitle || strcmp( psz_subtitle, subs[i] ) )
{ {
sub = InputSourceNew( p_input ); TAB_APPEND( p_input->p->i_slave, p_input->p->slave, sub );
if( !InputSourceInit( p_input, sub, subs[i], "subtitle" ) )
{
TAB_APPEND( p_input->p->i_slave, p_input->p->slave, sub );
}
else free( sub );
} }
free( subs[i] ); else free( sub );
} }
free( subs ); free( subs[i] );
free( psz_autopath );
} }
free( psz_subtitle ); free( subs );
free( psz_autopath );
}
free( psz_subtitle );
/* Look for slave */ /* Look for slave */
psz = var_GetNonEmptyString( p_input, "input-slave" ); psz = var_GetNonEmptyString( p_input, "input-slave" );
if( psz != NULL ) if( psz != NULL )
{
char *psz_delim;
input_source_t *slave;
while( psz && *psz )
{ {
char *psz_delim; while( *psz == ' ' || *psz == '#' )
input_source_t *slave;
while( psz && *psz )
{ {
while( *psz == ' ' || *psz == '#' ) psz++;
{ }
psz++; if( ( psz_delim = strchr( psz, '#' ) ) )
} {
if( ( psz_delim = strchr( psz, '#' ) ) ) *psz_delim++ = '\0';
{ }
*psz_delim++ = '\0'; if( *psz == 0 )
} {
if( *psz == 0 ) break;
{ }
break;
}
msg_Dbg( p_input, "adding slave input '%s'", psz ); msg_Dbg( p_input, "adding slave input '%s'", psz );
slave = InputSourceNew( p_input ); slave = InputSourceNew( p_input );
if( !InputSourceInit( p_input, slave, psz, NULL ) ) if( !InputSourceInit( p_input, slave, psz, NULL ) )
{ {
TAB_APPEND( p_input->p->i_slave, p_input->p->slave, slave ); TAB_APPEND( p_input->p->i_slave, p_input->p->slave, slave );
}
else free( slave );
psz = psz_delim;
} }
free( psz ); else free( slave );
psz = psz_delim;
} }
free( psz );
} }
else }
{
p_input->p->i_start = 0; static void InitPrograms( input_thread_t * p_input )
p_input->p->i_start = 0; {
} int i_es_out_mode;
vlc_value_t val;
if( p_input->b_preparsing ) return;
/* Set up es_out */ /* Set up es_out */
if( !p_input->b_preparsing ) es_out_Control( p_input->p->p_es_out, ES_OUT_SET_ACTIVE, true );
i_es_out_mode = ES_OUT_MODE_AUTO;
val.p_list = NULL;
if( p_input->p->p_sout )
{ {
es_out_Control( p_input->p->p_es_out, ES_OUT_SET_ACTIVE, true ); var_Get( p_input, "sout-all", &val );
i_es_out_mode = ES_OUT_MODE_AUTO; if ( val.b_bool )
val.p_list = NULL;
if( p_input->p->p_sout )
{ {
var_Get( p_input, "sout-all", &val ); i_es_out_mode = ES_OUT_MODE_ALL;
if ( val.b_bool ) 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_ALL; i_es_out_mode = ES_OUT_MODE_PARTIAL;
val.p_list = NULL; /* Note : we should remove the "program" callback. */
} }
else else
{ var_Change( p_input, "programs", VLC_VAR_FREELIST, &val,
var_Get( p_input, "programs", &val ); NULL );
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->p_es_out, ES_OUT_SET_MODE, i_es_out_mode ); }
es_out_Control( p_input->p->p_es_out, ES_OUT_SET_MODE, i_es_out_mode );
/* Inform the demuxer about waited group (needed only for DVB) */ /* Inform the demuxer about waited group (needed only for DVB) */
if( i_es_out_mode == ES_OUT_MODE_ALL ) if( i_es_out_mode == ES_OUT_MODE_ALL )
{ {
demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, -1, NULL ); demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, -1, NULL );
} }
else if( i_es_out_mode == ES_OUT_MODE_PARTIAL ) else if( i_es_out_mode == ES_OUT_MODE_PARTIAL )
{
demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, -1,
val.p_list );
}
else
{
demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP,
(int) var_GetInteger( p_input, "program" ), NULL );
}
}
static int Init( input_thread_t * p_input )
{
vlc_meta_t *p_meta;
vlc_value_t val;
int i, ret;
for( i = 0; i < p_input->p->input.p_item->i_options; i++ )
{
if( !strncmp( p_input->p->input.p_item->ppsz_options[i], "meta-file", 9 ) )
{ {
demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, -1, msg_Dbg( p_input, "Input is a meta file: disabling unneeded options" );
val.p_list ); var_SetString( p_input, "sout", "" );
var_SetBool( p_input, "sout-all", false );
var_SetString( p_input, "input-slave", "" );
var_SetInteger( p_input, "input-repeat", 0 );
var_SetString( p_input, "sub-file", "" );
var_SetBool( p_input, "sub-autodetect-file", false );
} }
else }
{
demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, InitStatistics( p_input );
(int) var_GetInteger( p_input, "program" ), NULL ); ret = InitSout( p_input );
if( ret != VLC_SUCCESS )
return ret; /* FIXME: goto error; should be better here */
/* Create es out */
p_input->p->p_es_out = input_EsOutNew( p_input, p_input->p->i_rate );
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 );
} }
}
if( p_input->p->p_sout ) StartTitle( p_input );
{
if( p_input->p->p_sout->i_out_pace_nocontrol > 0 )
{
p_input->p->b_out_pace_control = false;
}
else
{
p_input->p->b_out_pace_control = true;
}
if( p_input->b_can_pace_control && p_input->p->b_out_pace_control ) InitPrograms( p_input );
{
/* We don't want a high input priority here or we'll if( !p_input->b_preparsing && p_input->p->p_sout )
* end-up sucking up all the CPU time */ {
vlc_thread_set_priority( p_input, VLC_THREAD_PRIORITY_LOW ); p_input->p->b_out_pace_control = (p_input->p->p_sout->i_out_pace_nocontrol > 0);
}
msg_Dbg( p_input, "starting in %s mode", if( p_input->b_can_pace_control && p_input->p->b_out_pace_control )
p_input->p->b_out_pace_control ? "async" : "sync" ); {
/* 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(); p_meta = vlc_meta_New();
/* Get meta data from users */ /* Get meta data from users */
InputMetaUser( p_input, p_meta ); InputMetaUser( p_input, p_meta );
...@@ -1177,25 +1207,7 @@ static int Init( input_thread_t * p_input ) ...@@ -1177,25 +1207,7 @@ static int Init( input_thread_t * p_input )
DemuxMeta( p_input, p_meta, p_input->p->input.p_demux ); DemuxMeta( p_input, p_meta, p_input->p->input.p_demux );
/* Access_file does not give any meta, and there are no slave */ /* Access_file does not give any meta, and there are no slave */
if( !p_input->b_preparsing ) AccessMeta( p_input, p_meta );
{
if( p_input->p->input.p_access )
access_Control( p_input->p->input.p_access, ACCESS_GET_META,
p_meta );
/* Get meta data from slave input */
for( i = 0; i < p_input->p->i_slave; i++ )
{
DemuxMeta( p_input, p_meta, p_input->p->slave[i]->p_demux );
if( p_input->p->slave[i]->p_access )
{
access_Control( p_input->p->slave[i]->p_access,
ACCESS_GET_META, p_meta );
}
}
}
InputUpdateMeta( p_input, p_meta );
if( !p_input->b_preparsing ) if( !p_input->b_preparsing )
{ {
...@@ -2716,6 +2728,29 @@ static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_atta ...@@ -2716,6 +2728,29 @@ static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_atta
*ppp_attachment = attachment; *ppp_attachment = attachment;
} }
static void AccessMeta( input_thread_t * p_input, vlc_meta_t *p_meta )
{
int i;
if( p_input->b_preparsing )
return;
if( p_input->p->input.p_access )
access_Control( p_input->p->input.p_access, ACCESS_GET_META,
p_meta );
/* Get meta data from slave input */
for( i = 0; i < p_input->p->i_slave; i++ )
{
DemuxMeta( p_input, p_meta, p_input->p->slave[i]->p_demux );
if( p_input->p->slave[i]->p_access )
{
access_Control( p_input->p->slave[i]->p_access,
ACCESS_GET_META, p_meta );
}
}
}
static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_demux ) static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_demux )
{ {
bool b_bool; bool b_bool;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment