@ -252,6 +252,8 @@ typedef struct OutputStream {
int stream_copy ;
int stream_copy ;
const char * attachment_filename ;
const char * attachment_filename ;
int copy_initial_nonkeyframes ;
int copy_initial_nonkeyframes ;
enum PixelFormat pix_fmts [ 2 ] ;
} OutputStream ;
} OutputStream ;
@ -543,13 +545,24 @@ static void filter_release_buffer(AVFilterBuffer *fb)
unref_buffer ( buf - > ist , buf ) ;
unref_buffer ( buf - > ist , buf ) ;
}
}
static const enum PixelFormat * choose_pixel_fmts ( OutputStream * ost )
{
if ( ost - > st - > codec - > pix_fmt ! = PIX_FMT_NONE ) {
ost - > pix_fmts [ 0 ] = ost - > st - > codec - > pix_fmt ;
return ost - > pix_fmts ;
} else if ( ost - > enc - > pix_fmts )
return ost - > enc - > pix_fmts ;
else
return NULL ;
}
static int configure_video_filters ( InputStream * ist , OutputStream * ost )
static int configure_video_filters ( InputStream * ist , OutputStream * ost )
{
{
AVFilterContext * last_filter , * filter ;
AVFilterContext * last_filter , * filter ;
/** filter graph containing all filters including input & output */
/** filter graph containing all filters including input & output */
AVCodecContext * codec = ost - > st - > codec ;
AVCodecContext * codec = ost - > st - > codec ;
AVCodecContext * icodec = ist - > st - > codec ;
AVCodecContext * icodec = ist - > st - > codec ;
SinkContext sink_ctx = { . pix_fmt = codec - > pix_fmt } ;
SinkContext sink_ctx = { . pix_fmts = choose_pixel_fmts ( ost ) } ;
AVRational sample_aspect_ratio ;
AVRational sample_aspect_ratio ;
char args [ 255 ] ;
char args [ 255 ] ;
int ret ;
int ret ;
@ -621,6 +634,7 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
ost - > frame_aspect_ratio ? // overridden by the -aspect cli option
ost - > frame_aspect_ratio ? // overridden by the -aspect cli option
av_d2q ( ost - > frame_aspect_ratio * codec - > height / codec - > width , 255 ) :
av_d2q ( ost - > frame_aspect_ratio * codec - > height / codec - > width , 255 ) :
ost - > output_video_filter - > inputs [ 0 ] - > sample_aspect_ratio ;
ost - > output_video_filter - > inputs [ 0 ] - > sample_aspect_ratio ;
codec - > pix_fmt = ost - > output_video_filter - > inputs [ 0 ] - > format ;
return 0 ;
return 0 ;
}
}
@ -833,34 +847,6 @@ static void choose_sample_rate(AVStream *st, AVCodec *codec)
}
}
}
}
static void choose_pixel_fmt ( AVStream * st , AVCodec * codec )
{
if ( codec & & codec - > pix_fmts ) {
const enum PixelFormat * p = codec - > pix_fmts ;
if ( st - > codec - > strict_std_compliance < = FF_COMPLIANCE_UNOFFICIAL ) {
if ( st - > codec - > codec_id = = CODEC_ID_MJPEG ) {
p = ( const enum PixelFormat [ ] ) { PIX_FMT_YUVJ420P , PIX_FMT_YUVJ422P , PIX_FMT_YUV420P , PIX_FMT_YUV422P , PIX_FMT_NONE } ;
} else if ( st - > codec - > codec_id = = CODEC_ID_LJPEG ) {
p = ( const enum PixelFormat [ ] ) { PIX_FMT_YUVJ420P , PIX_FMT_YUVJ422P , PIX_FMT_YUVJ444P , PIX_FMT_YUV420P ,
PIX_FMT_YUV422P , PIX_FMT_YUV444P , PIX_FMT_BGRA , PIX_FMT_NONE } ;
}
}
for ( ; * p ! = PIX_FMT_NONE ; p + + ) {
if ( * p = = st - > codec - > pix_fmt )
break ;
}
if ( * p = = PIX_FMT_NONE ) {
if ( st - > codec - > pix_fmt ! = PIX_FMT_NONE )
av_log ( NULL , AV_LOG_WARNING ,
" Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s' \n " ,
av_pix_fmt_descriptors [ st - > codec - > pix_fmt ] . name ,
codec - > name ,
av_pix_fmt_descriptors [ codec - > pix_fmts [ 0 ] ] . name ) ;
st - > codec - > pix_fmt = codec - > pix_fmts [ 0 ] ;
}
}
}
static double
static double
get_sync_ipts ( const OutputStream * ost , int64_t pts )
get_sync_ipts ( const OutputStream * ost , int64_t pts )
{
{
@ -2401,31 +2387,11 @@ static int transcode_init(void)
ost - > resample_channels = icodec - > channels ;
ost - > resample_channels = icodec - > channels ;
break ;
break ;
case AVMEDIA_TYPE_VIDEO :
case AVMEDIA_TYPE_VIDEO :
if ( codec - > pix_fmt = = PIX_FMT_NONE )
codec - > pix_fmt = icodec - > pix_fmt ;
choose_pixel_fmt ( ost - > st , ost - > enc ) ;
if ( ost - > st - > codec - > pix_fmt = = PIX_FMT_NONE ) {
av_log ( NULL , AV_LOG_FATAL , " Video pixel format is unknown, stream cannot be encoded \n " ) ;
exit_program ( 1 ) ;
}
if ( ! codec - > width | | ! codec - > height ) {
if ( ! codec - > width | | ! codec - > height ) {
codec - > width = icodec - > width ;
codec - > width = icodec - > width ;
codec - > height = icodec - > height ;
codec - > height = icodec - > height ;
}
}
ost - > video_resample = codec - > width ! = icodec - > width | |
codec - > height ! = icodec - > height | |
codec - > pix_fmt ! = icodec - > pix_fmt ;
if ( ost - > video_resample ) {
codec - > bits_per_raw_sample = 0 ;
}
ost - > resample_height = icodec - > height ;
ost - > resample_width = icodec - > width ;
ost - > resample_pix_fmt = icodec - > pix_fmt ;
/*
/*
* We want CFR output if and only if one of those is true :
* We want CFR output if and only if one of those is true :
* 1 ) user specified output framerate with - r
* 1 ) user specified output framerate with - r
@ -2455,6 +2421,18 @@ static int transcode_init(void)
av_log ( NULL , AV_LOG_FATAL , " Error opening filters! \n " ) ;
av_log ( NULL , AV_LOG_FATAL , " Error opening filters! \n " ) ;
exit ( 1 ) ;
exit ( 1 ) ;
}
}
ost - > video_resample = codec - > width ! = icodec - > width | |
codec - > height ! = icodec - > height | |
codec - > pix_fmt ! = icodec - > pix_fmt ;
if ( ost - > video_resample ) {
codec - > bits_per_raw_sample = 0 ;
}
ost - > resample_height = icodec - > height ;
ost - > resample_width = icodec - > width ;
ost - > resample_pix_fmt = icodec - > pix_fmt ;
break ;
break ;
case AVMEDIA_TYPE_SUBTITLE :
case AVMEDIA_TYPE_SUBTITLE :
codec - > time_base = ( AVRational ) { 1 , 1000 } ;
codec - > time_base = ( AVRational ) { 1 , 1000 } ;
@ -3535,6 +3513,9 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
st - > codec - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
st - > codec - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
av_opt_get_int ( sws_opts , " sws_flags " , 0 , & ost - > sws_flags ) ;
av_opt_get_int ( sws_opts , " sws_flags " , 0 , & ost - > sws_flags ) ;
ost - > pix_fmts [ 0 ] = ost - > pix_fmts [ 1 ] = PIX_FMT_NONE ;
return ost ;
return ost ;
}
}