@ -360,6 +360,47 @@ static int formats_declared(AVFilterContext *f)
return 1 ;
}
static AVFilterFormats * clone_filter_formats ( AVFilterFormats * arg )
{
AVFilterFormats * a = av_memdup ( arg , sizeof ( * arg ) ) ;
if ( a ) {
a - > refcount = 0 ;
a - > refs = NULL ;
a - > formats = av_memdup ( a - > formats , sizeof ( * a - > formats ) * a - > nb_formats ) ;
if ( ! a - > formats & & arg - > formats )
av_freep ( & a ) ;
}
return a ;
}
static int can_merge_formats ( AVFilterFormats * a_arg ,
AVFilterFormats * b_arg ,
enum AVMediaType type ,
int is_sample_rate )
{
AVFilterFormats * a , * b , * ret ;
if ( a = = b )
return 1 ;
a = clone_filter_formats ( a_arg ) ;
b = clone_filter_formats ( b_arg ) ;
if ( is_sample_rate ) {
ret = ff_merge_samplerates ( a , b ) ;
} else {
ret = ff_merge_formats ( a , b , type ) ;
}
if ( ret ) {
av_freep ( & ret - > formats ) ;
av_freep ( & ret ) ;
return 1 ;
} else {
av_freep ( & a - > formats ) ;
av_freep ( & b - > formats ) ;
av_freep ( & a ) ;
av_freep ( & b ) ;
return 0 ;
}
}
/**
* Perform one round of query_formats ( ) and merging formats lists on the
* filter graph .
@ -404,20 +445,30 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
if ( ! link )
continue ;
if ( link - > in_formats ! = link - > out_formats
& & link - > in_formats & & link - > out_formats )
if ( ! can_merge_formats ( link - > in_formats , link - > out_formats ,
link - > type , 0 ) )
convert_needed = 1 ;
if ( link - > type = = AVMEDIA_TYPE_AUDIO ) {
if ( link - > in_samplerates ! = link - > out_samplerates
& & link - > in_samplerates & & link - > out_samplerates )
if ( ! can_merge_formats ( link - > in_samplerates ,
link - > out_samplerates ,
0 , 1 ) )
convert_needed = 1 ;
}
# define MERGE_DISPATCH(field, statement) \
if ( ! ( link - > in_ # # field & & link - > out_ # # field ) ) { \
count_delayed + + ; \
} else if ( link - > in_ # # field = = link - > out_ # # field ) { \
count_already_merged + + ; \
} else { \
} else if ( ! convert_needed ) { \
count_merged + + ; \
statement \
}
MERGE_DISPATCH ( formats ,
if ( ! ff_merge_formats ( link - > in_formats , link - > out_formats ,
link - > type ) )
convert_needed = 1 ;
)
if ( link - > type = = AVMEDIA_TYPE_AUDIO ) {
MERGE_DISPATCH ( channel_layouts ,
if ( ! ff_merge_channel_layouts ( link - > in_channel_layouts ,
@ -430,6 +481,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
convert_needed = 1 ;
)
}
MERGE_DISPATCH ( formats ,
if ( ! ff_merge_formats ( link - > in_formats , link - > out_formats ,
link - > type ) )
convert_needed = 1 ;
)
# undef MERGE_DISPATCH
if ( convert_needed ) {