@ -161,7 +161,6 @@ static int loop_output = AVFMT_NOOUTPUTLOOP;
static int qp_hist = 0 ;
# if CONFIG_AVFILTER
static char * vfilters = NULL ;
static AVFilterGraph * graph = NULL ;
# endif
static int intra_only = 0 ;
@ -291,6 +290,14 @@ typedef struct AVOutputStream {
AVFifoBuffer * fifo ; /* for compression: one audio fifo per codec */
FILE * logfile ;
# if CONFIG_AVFILTER
AVFilterContext * output_video_filter ;
AVFilterContext * input_video_filter ;
AVFilterBufferRef * picref ;
char * avfilter ;
AVFilterGraph * graph ;
# endif
int sws_flags ;
} AVOutputStream ;
@ -314,11 +321,8 @@ typedef struct AVInputStream {
int showed_multi_packet_warning ;
int is_past_recording_time ;
# if CONFIG_AVFILTER
AVFilterContext * output_video_filter ;
AVFilterContext * input_video_filter ;
AVFrame * filter_frame ;
int has_filter_frame ;
AVFilterBufferRef * picref ;
# endif
} AVInputStream ;
@ -342,7 +346,7 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost)
char args [ 255 ] ;
int ret ;
graph = avfilter_graph_alloc ( ) ;
ost - > graph = avfilter_graph_alloc ( ) ;
if ( ist - > st - > sample_aspect_ratio . num ) {
sample_aspect_ratio = ist - > st - > sample_aspect_ratio ;
@ -353,15 +357,15 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost)
ist - > st - > codec - > height , ist - > st - > codec - > pix_fmt , 1 , AV_TIME_BASE ,
sample_aspect_ratio . num , sample_aspect_ratio . den ) ;
ret = avfilter_graph_create_filter ( & i st- > input_video_filter , avfilter_get_by_name ( " buffer " ) ,
" src " , args , NULL , graph ) ;
ret = avfilter_graph_create_filter ( & o st- > input_video_filter , avfilter_get_by_name ( " buffer " ) ,
" src " , args , NULL , ost - > graph ) ;
if ( ret < 0 )
return ret ;
ret = avfilter_graph_create_filter ( & i st- > output_video_filter , & ffsink ,
" out " , NULL , & ffsink_ctx , graph ) ;
ret = avfilter_graph_create_filter ( & o st- > output_video_filter , & ffsink ,
" out " , NULL , & ffsink_ctx , ost - > graph ) ;
if ( ret < 0 )
return ret ;
last_filter = i st- > input_video_filter ;
last_filter = o st- > input_video_filter ;
if ( codec - > width ! = icodec - > width | | codec - > height ! = icodec - > height ) {
snprintf ( args , 255 , " %d:%d:flags=0x%X " ,
@ -369,7 +373,7 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost)
codec - > height ,
ost - > sws_flags ) ;
if ( ( ret = avfilter_graph_create_filter ( & filter , avfilter_get_by_name ( " scale " ) ,
NULL , args , NULL , graph ) ) < 0 )
NULL , args , NULL , ost - > graph ) ) < 0 )
return ret ;
if ( ( ret = avfilter_link ( last_filter , 0 , filter , 0 ) ) < 0 )
return ret ;
@ -377,9 +381,9 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost)
}
snprintf ( args , sizeof ( args ) , " flags=0x%X " , ost - > sws_flags ) ;
graph - > scale_sws_opts = av_strdup ( args ) ;
ost - > graph - > scale_sws_opts = av_strdup ( args ) ;
if ( vfilters ) {
if ( ost - > a vfilter) {
AVFilterInOut * outputs = av_malloc ( sizeof ( AVFilterInOut ) ) ;
AVFilterInOut * inputs = av_malloc ( sizeof ( AVFilterInOut ) ) ;
@ -389,25 +393,25 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost)
outputs - > next = NULL ;
inputs - > name = av_strdup ( " out " ) ;
inputs - > filter_ctx = i st- > output_video_filter ;
inputs - > filter_ctx = o st- > output_video_filter ;
inputs - > pad_idx = 0 ;
inputs - > next = NULL ;
if ( ( ret = avfilter_graph_parse ( graph , vfilters , inputs , outputs , NULL ) ) < 0 )
if ( ( ret = avfilter_graph_parse ( ost - > graph , ost - > a vfilter, inputs , outputs , NULL ) ) < 0 )
return ret ;
av_freep ( & vfilters ) ;
av_freep ( & ost - > a vfilter) ;
} else {
if ( ( ret = avfilter_link ( last_filter , 0 , i st- > output_video_filter , 0 ) ) < 0 )
if ( ( ret = avfilter_link ( last_filter , 0 , o st- > output_video_filter , 0 ) ) < 0 )
return ret ;
}
if ( ( ret = avfilter_graph_config ( graph , NULL ) ) < 0 )
if ( ( ret = avfilter_graph_config ( ost - > graph , NULL ) ) < 0 )
return ret ;
codec - > width = i st- > output_video_filter - > inputs [ 0 ] - > w ;
codec - > height = i st- > output_video_filter - > inputs [ 0 ] - > h ;
codec - > width = o st- > output_video_filter - > inputs [ 0 ] - > w ;
codec - > height = o st- > output_video_filter - > inputs [ 0 ] - > h ;
codec - > sample_aspect_ratio = ost - > st - > sample_aspect_ratio =
i st- > output_video_filter - > inputs [ 0 ] - > sample_aspect_ratio ;
o st- > output_video_filter - > inputs [ 0 ] - > sample_aspect_ratio ;
return 0 ;
}
@ -1549,14 +1553,21 @@ static int output_packet(AVInputStream *ist, int ist_index,
}
# if CONFIG_AVFILTER
if ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO & & ist - > input_video_filter ) {
AVRational sar ;
if ( ist - > st - > sample_aspect_ratio . num ) sar = ist - > st - > sample_aspect_ratio ;
else sar = ist - > st - > codec - > sample_aspect_ratio ;
// add it to be filtered
av_vsrc_buffer_add_frame ( ist - > input_video_filter , & picture ,
ist - > pts ,
sar ) ;
if ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
for ( i = 0 ; i < nb_ostreams ; i + + ) {
ost = ost_table [ i ] ;
if ( ost - > input_video_filter & & ost - > source_index = = ist_index ) {
AVRational sar ;
if ( ist - > st - > sample_aspect_ratio . num )
sar = ist - > st - > sample_aspect_ratio ;
else
sar = ist - > st - > codec - > sample_aspect_ratio ;
// add it to be filtered
av_vsrc_buffer_add_frame ( ost - > input_video_filter , & picture ,
ist - > pts ,
sar ) ;
}
}
}
# endif
@ -1581,26 +1592,24 @@ static int output_packet(AVInputStream *ist, int ist_index,
if ( pts > now )
usleep ( pts - now ) ;
}
# if CONFIG_AVFILTER
frame_available = ist - > st - > codec - > codec_type ! = AVMEDIA_TYPE_VIDEO | |
! ist - > output_video_filter | | avfilter_poll_frame ( ist - > output_video_filter - > inputs [ 0 ] ) ;
# endif
/* if output time reached then transcode raw format,
encode packets and output them */
if ( start_time = = 0 | | ist - > pts > = start_time )
# if CONFIG_AVFILTER
while ( frame_available ) {
AVRational ist_pts_tb ;
if ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO & & ist - > output_video_filter )
get_filtered_video_frame ( ist - > output_video_filter , & picture , & ist - > picref , & ist_pts_tb ) ;
if ( ist - > picref )
ist - > pts = av_rescale_q ( ist - > picref - > pts , ist_pts_tb , AV_TIME_BASE_Q ) ;
# endif
for ( i = 0 ; i < nb_ostreams ; i + + ) {
int frame_size ;
ost = ost_table [ i ] ;
if ( ost - > source_index = = ist_index ) {
# if CONFIG_AVFILTER
frame_available = ist - > st - > codec - > codec_type ! = AVMEDIA_TYPE_VIDEO | |
! ost - > output_video_filter | | avfilter_poll_frame ( ost - > output_video_filter - > inputs [ 0 ] ) ;
while ( frame_available ) {
AVRational ist_pts_tb ;
if ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO & & ost - > output_video_filter )
get_filtered_video_frame ( ost - > output_video_filter , & picture , & ost - > picref , & ist_pts_tb ) ;
if ( ost - > picref )
ist - > pts = av_rescale_q ( ost - > picref - > pts , ist_pts_tb , AV_TIME_BASE_Q ) ;
# endif
os = output_files [ ost - > file_index ] ;
/* set the input output pts pairs */
@ -1614,8 +1623,8 @@ static int output_packet(AVInputStream *ist, int ist_index,
break ;
case AVMEDIA_TYPE_VIDEO :
# if CONFIG_AVFILTER
if ( i st- > picref - > video )
ost - > st - > codec - > sample_aspect_ratio = i st- > picref - > video - > pixel_aspect ;
if ( o st- > picref - > video )
ost - > st - > codec - > sample_aspect_ratio = o st- > picref - > video - > pixel_aspect ;
# endif
do_video_out ( os , ost , ist , & picture , & frame_size ) ;
if ( vstats_filename & & frame_size )
@ -1636,7 +1645,11 @@ static int output_packet(AVInputStream *ist, int ist_index,
av_init_packet ( & opkt ) ;
if ( ( ! ost - > frame_number & & ! ( pkt - > flags & AV_PKT_FLAG_KEY ) ) & & ! copy_initial_nonkeyframes )
# if !CONFIG_AVFILTER
continue ;
# else
goto cont ;
# endif
/* no reencoding needed : output the packet directly */
/* force the input stream PTS */
@ -1684,16 +1697,17 @@ static int output_packet(AVInputStream *ist, int ist_index,
ost - > frame_number + + ;
av_free_packet ( & opkt ) ;
}
# if CONFIG_AVFILTER
cont :
frame_available = ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) & &
ost - > output_video_filter & & avfilter_poll_frame ( ost - > output_video_filter - > inputs [ 0 ] ) ;
if ( ost - > picref )
avfilter_unref_buffer ( ost - > picref ) ;
}
# endif
}
}
# if CONFIG_AVFILTER
frame_available = ( ist - > st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) & &
ist - > output_video_filter & & avfilter_poll_frame ( ist - > output_video_filter - > inputs [ 0 ] ) ;
if ( ist - > picref )
avfilter_unref_buffer ( ist - > picref ) ;
}
# endif
av_free ( buffer_to_free ) ;
/* XXX: allocate the subtitles in the codec ? */
if ( subtitle_to_free ) {
@ -2611,6 +2625,9 @@ static int transcode(AVFormatContext **output_files,
av_freep ( & ost - > st - > codec - > stats_in ) ;
avcodec_close ( ost - > st - > codec ) ;
}
# if CONFIG_AVFILTER
avfilter_graph_free ( & ost - > graph ) ;
# endif
}
/* close each decoder */
@ -2620,9 +2637,6 @@ static int transcode(AVFormatContext **output_files,
avcodec_close ( ist - > st - > codec ) ;
}
}
# if CONFIG_AVFILTER
avfilter_graph_free ( & graph ) ;
# endif
/* finished ! */
ret = 0 ;
@ -2765,12 +2779,6 @@ static void opt_frame_aspect_ratio(const char *arg)
ffmpeg_exit ( 1 ) ;
}
frame_aspect_ratio = ar ;
# if CONFIG_AVFILTER
x = vfilters ? strlen ( vfilters ) : 0 ;
vfilters = av_realloc ( vfilters , x + 100 ) ;
snprintf ( vfilters + x , x + 100 , " %csetdar=%f \n " , x ? ' , ' : ' ' , ar ) ;
# endif
}
static int opt_metadata ( const char * opt , const char * arg )
@ -3329,6 +3337,7 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
AVCodecContext * video_enc ;
enum CodecID codec_id = CODEC_ID_NONE ;
AVCodec * codec = NULL ;
int i ;
st = av_new_stream ( oc , oc - > nb_streams < nb_streamid_map ? streamid_map [ oc - > nb_streams ] : 0 ) ;
if ( ! st ) {
@ -3348,6 +3357,18 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
codec_id = av_guess_codec ( oc - > oformat , NULL , oc - > filename , NULL , AVMEDIA_TYPE_VIDEO ) ;
codec = avcodec_find_encoder ( codec_id ) ;
}
# if CONFIG_AVFILTER
if ( frame_aspect_ratio > 0 ) {
i = vfilters ? strlen ( vfilters ) : 0 ;
vfilters = av_realloc ( vfilters , i + 100 ) ;
snprintf ( vfilters + i , i + 100 , " %csetdar=%f \n " , i ? ' , ' : ' ' , frame_aspect_ratio ) ;
frame_aspect_ratio = 0 ;
}
ost - > avfilter = vfilters ;
vfilters = NULL ;
# endif
}
avcodec_get_context_defaults3 ( st - > codec , codec ) ;