@ -902,6 +902,63 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
return 0 ;
}
static int ofilter_bind_ifilter ( OutputFilter * ofilter , InputFilterPriv * ifp ,
const OutputFilterOptions * opts )
{
OutputFilterPriv * ofp = ofp_from_ofilter ( ofilter ) ;
av_assert0 ( ! ofilter - > bound ) ;
av_assert0 ( ofilter - > type = = ifp - > type ) ;
ofilter - > bound = 1 ;
av_freep ( & ofilter - > linklabel ) ;
ofp - > name = av_strdup ( opts - > name ) ;
if ( ! ofp - > name )
return AVERROR ( EINVAL ) ;
av_strlcatf ( ofp - > log_name , sizeof ( ofp - > log_name ) , " ->%s " , ofp - > name ) ;
return 0 ;
}
static int ifilter_bind_fg ( InputFilterPriv * ifp , FilterGraph * fg_src , int out_idx )
{
FilterGraphPriv * fgp = fgp_from_fg ( ifp - > ifilter . graph ) ;
OutputFilter * ofilter_src = fg_src - > outputs [ out_idx ] ;
OutputFilterOptions opts ;
char name [ 32 ] ;
int ret ;
av_assert0 ( ! ifp - > bound ) ;
ifp - > bound = 1 ;
if ( ifp - > type ! = ofilter_src - > type ) {
av_log ( fgp , AV_LOG_ERROR , " Tried to connect %s output to %s input \n " ,
av_get_media_type_string ( ofilter_src - > type ) ,
av_get_media_type_string ( ifp - > type ) ) ;
return AVERROR ( EINVAL ) ;
}
ifp - > type_src = ifp - > type ;
memset ( & opts , 0 , sizeof ( opts ) ) ;
snprintf ( name , sizeof ( name ) , " fg:%d:%d " , fgp - > fg . index , ifp - > index ) ;
opts . name = name ;
ret = ofilter_bind_ifilter ( ofilter_src , ifp , & opts ) ;
if ( ret < 0 )
return ret ;
ret = sch_connect ( fgp - > sch , SCH_FILTER_OUT ( fg_src - > index , out_idx ) ,
SCH_FILTER_IN ( fgp - > sch_idx , ifp - > index ) ) ;
if ( ret < 0 )
return ret ;
return 0 ;
}
static InputFilter * ifilter_alloc ( FilterGraph * fg )
{
InputFilterPriv * ifp ;
@ -1213,12 +1270,38 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter)
ifilter - > name ) ;
return ret ;
} else if ( ifp - > linklabel ) {
// bind to an explicitly specified demuxer stream
AVFormatContext * s ;
AVStream * st = NULL ;
char * p ;
int file_idx = strtol ( ifp - > linklabel , & p , 0 ) ;
int file_idx ;
// try finding an unbound filtergraph output with this label
for ( int i = 0 ; i < nb_filtergraphs ; i + + ) {
FilterGraph * fg_src = filtergraphs [ i ] ;
if ( fg = = fg_src )
continue ;
for ( int j = 0 ; j < fg_src - > nb_outputs ; j + + ) {
OutputFilter * ofilter = fg_src - > outputs [ j ] ;
if ( ! ofilter - > bound & & ofilter - > linklabel & &
! strcmp ( ofilter - > linklabel , ifp - > linklabel ) ) {
av_log ( fg , AV_LOG_VERBOSE ,
" Binding input with label '%s' to filtergraph output %d:%d \n " ,
ifp - > linklabel , i , j ) ;
ret = ifilter_bind_fg ( ifp , fg_src , j ) ;
if ( ret < 0 )
av_log ( fg , AV_LOG_ERROR , " Error binding filtergraph input %s \n " ,
ifp - > linklabel ) ;
return ret ;
}
}
}
// bind to an explicitly specified demuxer stream
file_idx = strtol ( ifp - > linklabel , & p , 0 ) ;
if ( file_idx < 0 | | file_idx > = nb_input_files ) {
av_log ( fg , AV_LOG_FATAL , " Invalid file index %d in filtergraph description %s. \n " ,
file_idx , fgp - > graph_desc ) ;
@ -1274,7 +1357,7 @@ static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter)
static int bind_inputs ( FilterGraph * fg )
{
// bind filtergraph inputs to input streams
// bind filtergraph inputs to input streams or other filtergraphs
for ( int i = 0 ; i < fg - > nb_inputs ; i + + ) {
InputFilterPriv * ifp = ifp_from_ifilter ( fg - > inputs [ i ] ) ;
int ret ;