Commit 1743aae3 authored by Rafaël Carré's avatar Rafaël Carré
Browse files

sout: allow duplicate outputs to be merged

The stream_out_t chain creation is modified: all modules are created by
the core (or by stream_out_duplicate) instead of being created by the
previous module.

sout_StreamChain{New,Delete} replace sout_Stream{New,Delete} to handle
modules chains instead of individual modules

sout_Stream{New,Delete} are still used by those new functions but made
static inside stream_output.c

Remove now unneeded psz_chain from struct sout_instance_t
Replace pointer to chain of next module by pointer to next module in
struct sout_stream_t

Example use:

vlc --sout-all input.mp4 --sout
"#duplicate{dst=transcode{vcodec=mp2v},select=es=0,dst=transcode,select=es=1}:std{...}"

(dst=transcode without acodec/vcodec is a hack to pass the encoded stream to
stream_out_standard without transcoding)
parent d83a491d
......@@ -45,7 +45,6 @@ struct sout_instance_t
VLC_COMMON_MEMBERS
char *psz_sout;
char *psz_chain;
/* meta data (Read only) XXX it won't be set before the first packet received */
vlc_meta_t *p_meta;
......@@ -208,7 +207,7 @@ struct sout_stream_t
char *psz_name;
config_chain_t *p_cfg;
char *psz_next;
sout_stream_t *p_next;
/* Subpicture unit */
spu_t *p_spu;
......@@ -223,8 +222,9 @@ struct sout_stream_t
sout_stream_sys_t *p_sys;
};
VLC_EXPORT( sout_stream_t *, sout_StreamNew, ( sout_instance_t *, char *psz_chain ) );
VLC_EXPORT( void, sout_StreamDelete, ( sout_stream_t * ) );
VLC_EXPORT( void, sout_StreamChainDelete, (sout_stream_t *p_first, sout_stream_t *p_last ) );
VLC_EXPORT( sout_stream_t *, sout_StreamChainNew, (sout_instance_t *p_sout,
char *psz_chain, sout_stream_t *p_next, sout_stream_t **p_last) );
static inline sout_stream_id_t *sout_StreamIdAdd( sout_stream_t *s, es_format_t *fmt )
{
......
......@@ -68,7 +68,6 @@ struct sout_stream_id_t
struct sout_stream_sys_t
{
sout_stream_t *p_out;
sout_stream_id_t **pp_es;
int i_es_num;
};
......@@ -83,8 +82,7 @@ static int Open( vlc_object_t *p_this )
p_sys = malloc( sizeof( sout_stream_sys_t ) );
p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
if( !p_sys->p_out )
if( !p_stream->p_next )
{
msg_Err( p_stream, "cannot create chain" );
free( p_sys );
......@@ -113,7 +111,6 @@ static void Close( vlc_object_t * p_this )
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
sout_StreamDelete( p_sys->p_out );
p_stream->p_sout->i_out_pace_nocontrol--;
free( p_sys );
......@@ -142,7 +139,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *p_es )
free( p_es );
if ( id != NULL )
return p_sys->p_out->pf_del( p_sys->p_out, id );
return p_stream->p_next->pf_del( p_stream->p_next, id );
else
return VLC_SUCCESS;
}
......@@ -157,7 +154,7 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *p_es,
p_es->i_last = p_buffer->i_dts;
if ( p_es->id == NULL && p_es->b_error != true )
{
p_es->id = p_sys->p_out->pf_add( p_sys->p_out, &p_es->fmt );
p_es->id = p_stream->p_next->pf_add( p_stream->p_next, &p_es->fmt );
if ( p_es->id == NULL )
{
p_es->b_error = true;
......@@ -167,7 +164,7 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *p_es,
}
if ( p_es->b_error != true )
p_sys->p_out->pf_send( p_sys->p_out, p_es->id, p_buffer );
p_stream->p_next->pf_send( p_stream->p_next, p_es->id, p_buffer );
else
block_ChainRelease( p_buffer );
......@@ -178,7 +175,7 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *p_es,
|| p_sys->pp_es[i]->fmt.i_cat == AUDIO_ES)
&& p_sys->pp_es[i]->i_last < i_current )
{
p_sys->p_out->pf_del( p_sys->p_out, p_sys->pp_es[i]->id );
p_stream->p_next->pf_del( p_stream->p_next, p_sys->pp_es[i]->id );
p_sys->pp_es[i]->id = NULL;
}
}
......
......@@ -363,7 +363,6 @@ static int SendOut( sout_stream_t *p_stream, sout_stream_id_t *id,
typedef struct in_sout_stream_sys_t
{
sout_stream_t *p_out;
vlc_mutex_t *p_lock;
int i_id_offset;
mtime_t i_delay;
......@@ -395,8 +394,7 @@ static int OpenIn( vlc_object_t *p_this )
if( unlikely( !p_sys ) )
return VLC_ENOMEM;
p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
if( !p_sys->p_out )
if( !p_stream->p_next )
{
msg_Err( p_stream, "cannot create chain" );
free( p_sys );
......@@ -461,7 +459,6 @@ static void CloseIn( vlc_object_t * p_this )
sout_stream_t *p_stream = (sout_stream_t*)p_this;
in_sout_stream_sys_t *p_sys = (in_sout_stream_sys_t *)p_stream->p_sys;
sout_StreamDelete( p_sys->p_out );
p_stream->p_sout->i_out_pace_nocontrol--;
free( p_sys->psz_name );
......@@ -481,7 +478,7 @@ static sout_stream_id_t * AddIn( sout_stream_t *p_stream, es_format_t *p_fmt )
sout_stream_id_t *id = malloc( sizeof( sout_stream_id_t ) );
if( !id ) return NULL;
id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
id->id = p_stream->p_next->pf_add( p_stream->p_next, p_fmt );
if( !id->id )
{
free( id );
......@@ -516,7 +513,7 @@ static int DelIn( sout_stream_t *p_stream, sout_stream_id_t *id )
if( id == p_sys->id_video ) p_sys->id_video = NULL;
if( id == p_sys->id_audio ) p_sys->id_audio = NULL;
int ret = p_sys->p_out->pf_del( p_sys->p_out, id->id );
int ret = p_stream->p_next->pf_del( p_stream->p_next, id->id );
free( id );
return ret;
......@@ -533,7 +530,7 @@ static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
/* First forward the packet for our own ES */
if( !p_sys->b_placeholder )
p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
/* Then check all bridged streams */
vlc_mutex_lock( p_sys->p_lock );
......@@ -570,7 +567,7 @@ static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
{
if ( p_bridge->pp_es[i]->b_empty && p_bridge->pp_es[i]->id != NULL )
{
p_sys->p_out->pf_del( p_sys->p_out, p_bridge->pp_es[i]->id );
p_stream->p_next->pf_del( p_stream->p_next, p_bridge->pp_es[i]->id );
}
else
{
......@@ -584,8 +581,8 @@ static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
p_bridge->pp_es[i]->fmt.i_id += p_sys->i_id_offset;
if( !p_sys->b_placeholder )
{
p_bridge->pp_es[i]->id = p_sys->p_out->pf_add(
p_sys->p_out, &p_bridge->pp_es[i]->fmt );
p_bridge->pp_es[i]->id = p_stream->p_next->pf_add(
p_stream->p_next, &p_bridge->pp_es[i]->fmt );
if ( p_bridge->pp_es[i]->id == NULL )
{
msg_Warn( p_stream, "couldn't create chain for id %d",
......@@ -608,7 +605,7 @@ static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
&& p_bridge->pp_es[i]->i_last < i_date )
{
if( !p_sys->b_placeholder )
p_sys->p_out->pf_del( p_sys->p_out,
p_stream->p_next->pf_del( p_stream->p_next,
p_bridge->pp_es[i]->id );
p_bridge->pp_es[i]->fmt.i_id -= p_sys->i_id_offset;
p_bridge->pp_es[i]->b_changed = true;
......@@ -642,7 +639,7 @@ static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
( p_bridge->pp_es[i]->fmt.i_cat == VIDEO_ES &&
p_bridge->pp_es[i]->p_block->i_flags & BLOCK_FLAG_TYPE_I ) )
{
p_sys->p_out->pf_send( p_sys->p_out,
p_stream->p_next->pf_send( p_stream->p_next,
newid,
p_bridge->pp_es[i]->p_block );
p_sys->i_state = placeholder_off;
......@@ -654,14 +651,14 @@ static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
break;
p_sys->i_last_audio = i_date;
default:
p_sys->p_out->pf_send( p_sys->p_out,
p_stream->p_next->pf_send( p_stream->p_next,
newid?newid:p_bridge->pp_es[i]->id,
p_bridge->pp_es[i]->p_block );
break;
}
}
else /* !b_placeholder */
p_sys->p_out->pf_send( p_sys->p_out,
p_stream->p_next->pf_send( p_stream->p_next,
p_bridge->pp_es[i]->id,
p_bridge->pp_es[i]->p_block );
}
......@@ -694,7 +691,7 @@ static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
|| p_buffer->i_flags & BLOCK_FLAG_TYPE_I ) )
|| p_sys->i_state == placeholder_on )
{
p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
p_sys->i_state = placeholder_on;
}
else
......@@ -703,7 +700,7 @@ static int SendIn( sout_stream_t *p_stream, sout_stream_id_t *id,
case AUDIO_ES:
if( p_sys->i_last_audio + p_sys->i_placeholder_delay < i_date )
p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
else
block_Release( p_buffer );
break;
......
......@@ -64,6 +64,9 @@ struct sout_stream_sys_t
int i_nb_streams;
sout_stream_t **pp_streams;
int i_nb_last_streams;
sout_stream_t **pp_last_streams;
int i_nb_select;
char **ppsz_select;
};
......@@ -92,20 +95,24 @@ static int Open( vlc_object_t *p_this )
return VLC_ENOMEM;
TAB_INIT( p_sys->i_nb_streams, p_sys->pp_streams );
TAB_INIT( p_sys->i_nb_last_streams, p_sys->pp_last_streams );
TAB_INIT( p_sys->i_nb_select, p_sys->ppsz_select );
for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next )
{
if( !strncmp( p_cfg->psz_name, "dst", strlen( "dst" ) ) )
{
sout_stream_t *s;
sout_stream_t *s, *p_last;
msg_Dbg( p_stream, " * adding `%s'", p_cfg->psz_value );
s = sout_StreamNew( p_stream->p_sout, p_cfg->psz_value );
s = sout_StreamChainNew( p_stream->p_sout, p_cfg->psz_value,
p_stream->p_next, &p_last );
if( s )
{
TAB_APPEND( p_sys->i_nb_streams, p_sys->pp_streams, s );
TAB_APPEND( p_sys->i_nb_last_streams, p_sys->pp_last_streams,
p_last );
TAB_APPEND( p_sys->i_nb_select, p_sys->ppsz_select, NULL );
}
}
......@@ -164,10 +171,11 @@ static void Close( vlc_object_t * p_this )
msg_Dbg( p_stream, "closing a duplication" );
for( i = 0; i < p_sys->i_nb_streams; i++ )
{
sout_StreamDelete( p_sys->pp_streams[i] );
sout_StreamChainDelete(p_sys->pp_streams[i], p_sys->pp_last_streams[i]);
free( p_sys->ppsz_select[i] );
}
free( p_sys->pp_streams );
free( p_sys->pp_last_streams );
free( p_sys->ppsz_select );
free( p_sys );
......
......@@ -64,8 +64,6 @@ struct sout_stream_id_t
struct sout_stream_sys_t
{
sout_stream_t *p_out;
int i_id;
sout_stream_id_t **id;
};
......@@ -82,8 +80,7 @@ static int Open( vlc_object_t *p_this )
if( p_sys == NULL )
return VLC_EGENERIC;
p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
if( p_sys->p_out == NULL )
if( !p_stream->p_next )
{
free( p_sys );
return VLC_EGENERIC;
......@@ -110,13 +107,12 @@ static void Close( vlc_object_t * p_this )
{
sout_stream_id_t *id = p_sys->id[i];
sout_StreamIdDel( p_sys->p_out, id->id );
sout_StreamIdDel( p_stream->p_next, id->id );
es_format_Clean( &id->fmt );
free( id );
}
TAB_CLEAN( p_sys->i_id, p_sys->id );
sout_StreamDelete( p_sys->p_out );
free( p_sys );
}
......@@ -168,7 +164,7 @@ static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
if( !id->b_used && id->fmt.i_cat == p_fmt->i_cat )
{
TAB_REMOVE( p_sys->i_id, p_sys->id, id );
sout_StreamIdDel( p_sys->p_out, id->id );
sout_StreamIdDel( p_stream->p_next, id->id );
es_format_Clean( &id->fmt );
free( id );
......@@ -183,7 +179,7 @@ static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
return NULL;
es_format_Copy( &id->fmt, p_fmt );
id->b_used = true;
id->id = sout_StreamIdAdd( p_sys->p_out, &id->fmt );
id->id = sout_StreamIdAdd( p_stream->p_next, &id->fmt );
if( id->id == NULL )
{
free( id );
......@@ -210,7 +206,5 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
static int Send( sout_stream_t *p_stream,
sout_stream_id_t *id, block_t *p_buffer )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
return sout_StreamIdSend( p_stream->p_next, id->id, p_buffer );
}
......@@ -170,7 +170,7 @@ static void Close( vlc_object_t * p_this )
sout_stream_sys_t *p_sys = p_stream->p_sys;
if( p_sys->p_out )
sout_StreamDelete( p_sys->p_out );
sout_StreamChainDelete( p_sys->p_out, p_sys->p_out );
TAB_CLEAN( p_sys->i_id, p_sys->id );
free( p_sys->psz_prefix );
......@@ -327,7 +327,7 @@ static int OutputNew( sout_stream_t *p_stream,
/* Create the output */
msg_Dbg( p_stream, "Using record output `%s'", psz_output );
p_sys->p_out = sout_StreamNew( p_stream->p_sout, psz_output );
p_sys->p_out = sout_StreamChainNew( p_stream->p_sout, psz_output, NULL, NULL );
if( !p_sys->p_out )
goto error;
......@@ -460,7 +460,7 @@ static void OutputStart( sout_stream_t *p_stream )
id->id = NULL;
}
if( p_sys->p_out )
sout_StreamDelete( p_sys->p_out );
sout_StreamChainDelete( p_sys->p_out, p_sys->p_out );
p_sys->p_out = NULL;
if( i_es > i_best_es )
......
......@@ -143,7 +143,6 @@ static const char *const ppsz_sout_options[] = {
struct sout_stream_sys_t
{
sout_stream_t *p_out;
int i_gop;
int i_qscale;
int i_aspect;
......@@ -191,8 +190,7 @@ static int Open( vlc_object_t *p_this )
if( !p_sys )
return VLC_ENOMEM;
p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
if( !p_sys->p_out )
if( !p_stream->p_next )
{
msg_Err( p_stream, "cannot create chain" );
free( p_sys );
......@@ -306,8 +304,6 @@ static void Close( vlc_object_t * p_this )
sout_stream_t *p_stream = (sout_stream_t *)p_this;
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_StreamDelete( p_sys->p_out );
free( p_sys );
}
......@@ -427,7 +423,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
memcpy( &id->f_src, p_fmt, sizeof( es_format_t ) );
/* open output stream */
id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
id->id = p_stream->p_next->pf_add( p_stream->p_next, p_fmt );
if( id->id != NULL )
return id;
......@@ -475,7 +471,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
if ( id->id )
{
p_sys->p_out->pf_del( p_sys->p_out, id->id );
p_stream->p_next->pf_del( p_stream->p_next, id->id );
}
free( id );
......@@ -498,7 +494,7 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
if ( !id->b_switcher_video && !id->b_switcher_audio )
{
return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
return p_stream->p_next->pf_send( p_stream->p_next, id->id, p_buffer );
}
block_ChainAppend( &id->p_queued, p_buffer );
......@@ -557,7 +553,7 @@ static mtime_t Process( sout_stream_t *p_stream, sout_stream_id_t *id,
{
/* Full forward */
if ( p_blocks != NULL )
p_sys->p_out->pf_send( p_sys->p_out, id->id, p_blocks );
p_stream->p_next->pf_send( p_stream->p_next, id->id, p_blocks );
return i_dts;
}
......@@ -594,7 +590,7 @@ static mtime_t Process( sout_stream_t *p_stream, sout_stream_id_t *id,
}
if ( p_blocks_out != NULL )
p_sys->p_out->pf_send( p_sys->p_out, id->id, p_blocks_out );
p_stream->p_next->pf_send( p_stream->p_next, id->id, p_blocks_out );
return i_dts;
}
......
......@@ -438,7 +438,7 @@ bool transcode_audio_add( sout_stream_t *p_stream, es_format_t *p_fmt,
}
/* Open output stream */
id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out );
id->b_transcode = true;
if( !id->id )
......
......@@ -68,7 +68,7 @@ int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
}
/* open output stream */
id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out );
id->b_transcode = true;
if( !id->id ) goto error;
......@@ -77,7 +77,7 @@ int transcode_osd_new( sout_stream_t *p_stream, sout_stream_id_t *id )
{
msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
(char*)&id->p_decoder->fmt_out.i_codec );
id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_decoder->fmt_out );
id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_decoder->fmt_out );
id->b_transcode = false;
if( !id->id ) goto error;
......
......@@ -173,7 +173,7 @@ bool transcode_spu_add( sout_stream_t *p_stream, es_format_t *p_fmt,
}
/* open output stream */
id->id = sout_StreamIdAdd( p_sys->p_out, &id->p_encoder->fmt_out );
id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out );
id->b_transcode = true;
if( !id->id )
......
......@@ -258,8 +258,7 @@ static int Open( vlc_object_t *p_this )
p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) );
p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
if( !p_sys->p_out )
if( !p_stream->p_next )
{
msg_Err( p_stream, "cannot create chain" );
vlc_object_release( p_sys );
......@@ -515,8 +514,6 @@ static void Close( vlc_object_t * p_this )
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_StreamDelete( p_sys->p_out );
free( p_sys->psz_af );
config_ChainDestroy( p_sys->p_audio_cfg );
......@@ -596,7 +593,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
{
msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
(char*)&p_fmt->i_codec );
id->id = sout_StreamIdAdd( p_sys->p_out, p_fmt );
id->id = sout_StreamIdAdd( p_stream->p_next, p_fmt );
id->b_transcode = false;
success = id->id;
......@@ -653,7 +650,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
}
}
if( id->id ) sout_StreamIdDel( p_sys->p_out, id->id );
if( id->id ) sout_StreamIdDel( p_stream->p_next, id->id );
if( id->p_decoder )
{
......@@ -683,7 +680,7 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
if( !id->b_transcode )
{
if( id->id )
return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
return sout_StreamIdSend( p_stream->p_next, id->id, p_buffer );
block_Release( p_buffer );
return VLC_EGENERIC;
......@@ -727,6 +724,6 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
}
if( p_out )
return sout_StreamIdSend( p_sys->p_out, id->id, p_out );
return sout_StreamIdSend( p_stream->p_next, id->id, p_out );
return VLC_SUCCESS;
}
......@@ -19,7 +19,6 @@ struct sout_stream_sys_t
{
VLC_COMMON_MEMBERS
sout_stream_t *p_out;
sout_stream_id_t *id_video;
block_t *p_buffers;
vlc_mutex_t lock_out;
......
......@@ -482,8 +482,7 @@ static int transcode_video_encoder_open( sout_stream_t *p_stream,
id->p_encoder->fmt_out.i_codec =
vlc_fourcc_GetCodec( VIDEO_ES, id->p_encoder->fmt_out.i_codec );
id->id = sout_StreamIdAdd( p_stream->p_sys->p_out,
&id->p_encoder->fmt_out );
id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out );
if( !id->id )
{
msg_Err( p_stream, "cannot add this stream" );
......
......@@ -367,8 +367,8 @@ sout_MuxGetStream
sout_MuxNew
sout_MuxSendBuffer
sout_SAPMethod
sout_StreamDelete
sout_StreamNew
sout_StreamChainDelete
sout_StreamChainNew
sout_UpdateStatistic
__spu_Create
spu_Destroy
......
......@@ -31,6 +31,8 @@
# include "config.h"
#endif
#include <assert.h>
#include <vlc_common.h>
#include <stdlib.h> /* free() */
......@@ -53,9 +55,7 @@
/*****************************************************************************
* Local prototypes
*****************************************************************************/
#define sout_stream_url_to_chain( p, s ) \
_sout_stream_url_to_chain( VLC_OBJECT(p), s )
static char *_sout_stream_url_to_chain( vlc_object_t *, const char * );
static char *sout_stream_url_to_chain( bool, const char * );
/*
* Generic MRL parser
......@@ -82,12 +82,27 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, const char *psz_des
static const char typename[] = "stream output";
sout_instance_t *p_sout;
char *psz_chain;
if( psz_dest && psz_dest[0] == '#' )
{
psz_chain = strdup( &psz_dest[1] );
}
else
{
psz_chain = sout_stream_url_to_chain(
config_GetInt(p_parent, "sout-display") > 0, psz_dest );
}
if(!psz_chain)
return NULL;
/* *** Allocate descriptor *** */
p_sout = vlc_custom_create( p_parent, sizeof( *p_sout ),
VLC_OBJECT_GENERIC, typename );
if( p_sout == NULL )
return NULL;
msg_Dbg( p_sout, "using sout chain=`%s'", psz_chain );
/* *** init descriptor *** */
p_sout->psz_sout = strdup( psz_dest );
p_sout->p_meta = NULL;
......@@ -95,38 +110,28 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, const char *psz_des
p_sout->p_sys = NULL;
vlc_mutex_init( &p_sout->lock );
if( psz_dest && psz_dest[0] == '#' )
{
p_sout->psz_chain = strdup( &psz_dest[1] );
}
else
{
p_sout->psz_chain = sout_stream_url_to_chain( p_sout, psz_dest );
msg_Dbg( p_sout, "using sout chain=`%s'", p_sout->psz_chain );
}
p_sout->p_stream = NULL;
/* attach it for inherit */
vlc_object_attach( p_sout, p_parent );
/* */
var_Create( p_sout, "sout-mux-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
/* */