@ -122,6 +122,8 @@ static int nb_output_files = 0;
static StreamMap * stream_maps = NULL ;
static int nb_stream_maps ;
static AVDictionary * codec_names ;
/* first item specifies output metadata, second is input */
static MetadataMap ( * meta_data_maps ) [ 2 ] = NULL ;
static int nb_meta_data_maps ;
@ -149,7 +151,6 @@ static uint16_t *inter_matrix = NULL;
static const char * video_rc_override_string = NULL ;
static int video_disable = 0 ;
static int video_discard = 0 ;
static char * video_codec_name = NULL ;
static unsigned int video_codec_tag = 0 ;
static char * video_language = NULL ;
static int same_quant = 0 ;
@ -170,17 +171,14 @@ static int audio_sample_rate = 0;
static float audio_qscale = QSCALE_NONE ;
static int audio_disable = 0 ;
static int audio_channels = 0 ;
static char * audio_codec_name = NULL ;
static unsigned int audio_codec_tag = 0 ;
static char * audio_language = NULL ;
static int subtitle_disable = 0 ;
static char * subtitle_codec_name = NULL ;
static char * subtitle_language = NULL ;
static unsigned int subtitle_codec_tag = 0 ;
static int data_disable = 0 ;
static char * data_codec_name = NULL ;
static unsigned int data_codec_tag = 0 ;
static float mux_preload = 0.5 ;
@ -197,10 +195,6 @@ static int do_pkt_dump = 0;
static int do_psnr = 0 ;
static int do_pass = 0 ;
static const char * pass_logfilename_prefix ;
static int audio_stream_copy = 0 ;
static int video_stream_copy = 0 ;
static int subtitle_stream_copy = 0 ;
static int data_stream_copy = 0 ;
static int video_sync_method = - 1 ;
static int audio_sync_method = 0 ;
static float audio_drift_threshold = 0.1 ;
@ -550,11 +544,6 @@ static int exit_program(int ret)
av_freep ( & input_streams ) ;
av_freep ( & input_files ) ;
av_free ( video_codec_name ) ;
av_free ( audio_codec_name ) ;
av_free ( subtitle_codec_name ) ;
av_free ( data_codec_name ) ;
uninit_opts ( ) ;
av_free ( audio_buf ) ;
av_free ( audio_out ) ;
@ -691,7 +680,59 @@ static void choose_pixel_fmt(AVStream *st, AVCodec *codec)
}
}
static OutputStream * new_output_stream ( AVFormatContext * oc , int file_idx , AVCodec * codec )
static enum CodecID find_codec_or_die ( const char * name , enum AVMediaType type , int encoder )
{
const char * codec_string = encoder ? " encoder " : " decoder " ;
AVCodec * codec ;
if ( ! name )
return CODEC_ID_NONE ;
codec = encoder ?
avcodec_find_encoder_by_name ( name ) :
avcodec_find_decoder_by_name ( name ) ;
if ( ! codec ) {
av_log ( NULL , AV_LOG_ERROR , " Unknown %s '%s' \n " , codec_string , name ) ;
exit_program ( 1 ) ;
}
if ( codec - > type ! = type ) {
av_log ( NULL , AV_LOG_ERROR , " Invalid %s type '%s' \n " , codec_string , name ) ;
exit_program ( 1 ) ;
}
return codec - > id ;
}
static AVCodec * choose_codec ( AVFormatContext * s , AVStream * st , enum AVMediaType type , AVDictionary * codec_names )
{
AVDictionaryEntry * e = NULL ;
char * codec_name = NULL ;
int ret ;
while ( e = av_dict_get ( codec_names , " " , e , AV_DICT_IGNORE_SUFFIX ) ) {
char * p = strchr ( e - > key , ' : ' ) ;
if ( ( ret = check_stream_specifier ( s , st , p ? p + 1 : " " ) ) > 0 )
codec_name = e - > value ;
else if ( ret < 0 )
exit_program ( 1 ) ;
}
if ( ! codec_name ) {
if ( s - > oformat ) {
st - > codec - > codec_id = av_guess_codec ( s - > oformat , NULL , s - > filename , NULL , type ) ;
return avcodec_find_encoder ( st - > codec - > codec_id ) ;
}
} else if ( ! strcmp ( codec_name , " copy " ) )
st - > stream_copy = 1 ;
else {
st - > codec - > codec_id = find_codec_or_die ( codec_name , type , s - > iformat = = NULL ) ;
return s - > oformat ? avcodec_find_encoder_by_name ( codec_name ) :
avcodec_find_decoder_by_name ( codec_name ) ;
}
return NULL ;
}
static OutputStream * new_output_stream ( AVFormatContext * oc , int file_idx , enum AVMediaType type )
{
OutputStream * ost ;
AVStream * st = av_new_stream ( oc , oc - > nb_streams < nb_streamid_map ? streamid_map [ oc - > nb_streams ] : 0 ) ;
@ -716,13 +757,14 @@ static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCode
ost - > file_index = file_idx ;
ost - > index = idx ;
ost - > st = st ;
o st- > enc = codec ;
if ( codec ) {
st - > codec - > codec_type = codec - > type ;
ost - > opts = filter_codec_opts ( codec_opts , code c- > id , oc , st ) ;
st - > codec - > codec_type = type ;
ost - > enc = choose_codec ( oc , st , type , codec_names ) ;
if ( ost - > enc ) {
ost - > opts = filter_codec_opts ( codec_opts , ost - > en c- > id , oc , st ) ;
}
avcodec_get_context_defaults3 ( st - > codec , codec ) ;
avcodec_get_context_defaults3 ( st - > codec , ost - > enc ) ;
st - > codec - > codec_type = type ; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
ost - > sws_flags = av_get_int ( sws_opts , " sws_flags " , NULL ) ;
return ost ;
@ -743,7 +785,7 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename)
AVCodec * codec ;
codec = avcodec_find_encoder ( ic - > streams [ i ] - > codec - > codec_id ) ;
ost = new_output_stream ( s , nb_output_files , codec ) ;
ost = new_output_stream ( s , nb_output_files , codec - > type ) ;
st = ost - > st ;
// FIXME: a more elegant solution is needed
@ -752,17 +794,10 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename)
memcpy ( st - > info , ic - > streams [ i ] - > info , sizeof ( * st - > info ) ) ;
avcodec_copy_context ( st - > codec , ic - > streams [ i ] - > codec ) ;
if ( st - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO ) {
if ( audio_stream_copy ) {
st - > stream_copy = 1 ;
} else
choose_sample_fmt ( st , codec ) ;
} else if ( st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO ) {
if ( video_stream_copy ) {
st - > stream_copy = 1 ;
} else
choose_pixel_fmt ( st , codec ) ;
}
if ( st - > codec - > codec_type = = AVMEDIA_TYPE_AUDIO & & ! st - > stream_copy )
choose_sample_fmt ( st , codec ) ;
else if ( st - > codec - > codec_type = = AVMEDIA_TYPE_VIDEO & & ! st - > stream_copy )
choose_pixel_fmt ( st , codec ) ;
}
av_close_input_file ( ic ) ;
@ -2916,36 +2951,29 @@ static int opt_video_standard(const char *opt, const char *arg)
return opt_default ( " standard " , arg ) ;
}
static int opt_codec ( int * pstream_copy , char * * pcodec_name ,
int codec_type , const char * arg )
static int opt_codec ( const char * opt , const char * arg )
{
av_freep ( pcodec_name ) ;
if ( ! strcmp ( arg , " copy " ) ) {
* pstream_copy = 1 ;
} else {
* pcodec_name = av_strdup ( arg ) ;
}
return 0 ;
return av_dict_set ( & codec_names , opt , arg , 0 ) ;
}
static int opt_audio_codec ( const char * opt , const char * arg )
{
return opt_codec ( & audio_stream_copy , & audio_codec_name , AVMEDIA_TYPE_AUDIO , arg ) ;
return opt_codec ( " codec:a " , arg ) ;
}
static int opt_video_codec ( const char * opt , const char * arg )
{
return opt_codec ( & video_stream_copy , & video_codec_name , AVMEDIA_TYPE_VIDEO , arg ) ;
return opt_codec ( " codec:v " , arg ) ;
}
static int opt_subtitle_codec ( const char * opt , const char * arg )
{
return opt_codec ( & subtitle_stream_copy , & subtitle_codec_name , AVMEDIA_TYPE_SUBTITLE , arg ) ;
return opt_codec ( " codec:s " , arg ) ;
}
static int opt_data_codec ( const char * opt , const char * arg )
{
return opt_codec ( & data_stream_copy , & data_codec_name , AVMEDIA_TYPE_DATA , arg ) ;
return opt_codec ( " codec:d " , arg ) ;
}
static int opt_codec_tag ( const char * opt , const char * arg )
@ -3153,26 +3181,6 @@ static int opt_input_ts_offset(const char *opt, const char *arg)
return 0 ;
}
static enum CodecID find_codec_or_die ( const char * name , int type , int encoder )
{
const char * codec_string = encoder ? " encoder " : " decoder " ;
AVCodec * codec ;
if ( ! name )
return CODEC_ID_NONE ;
codec = encoder ?
avcodec_find_encoder_by_name ( name ) :
avcodec_find_decoder_by_name ( name ) ;
if ( ! codec ) {
fprintf ( stderr , " Unknown %s '%s' \n " , codec_string , name ) ;
exit_program ( 1 ) ;
}
if ( codec - > type ! = type ) {
fprintf ( stderr , " Invalid %s type '%s' \n " , codec_string , name ) ;
exit_program ( 1 ) ;
}
return codec - > id ;
}
static int opt_input_file ( const char * opt , const char * filename )
{
@ -3223,12 +3231,6 @@ static int opt_input_file(const char *opt, const char *filename)
if ( frame_pix_fmt ! = PIX_FMT_NONE )
av_dict_set ( & format_opts , " pixel_format " , av_get_pix_fmt_name ( frame_pix_fmt ) , 0 ) ;
ic - > video_codec_id =
find_codec_or_die ( video_codec_name , AVMEDIA_TYPE_VIDEO , 0 ) ;
ic - > audio_codec_id =
find_codec_or_die ( audio_codec_name , AVMEDIA_TYPE_AUDIO , 0 ) ;
ic - > subtitle_codec_id =
find_codec_or_die ( subtitle_codec_name , AVMEDIA_TYPE_SUBTITLE , 0 ) ;
ic - > flags | = AVFMT_FLAG_NONBLOCK ;
if ( loop_input ) {
@ -3268,6 +3270,10 @@ static int opt_input_file(const char *opt, const char *filename)
opt_programid = 0 ;
}
/* apply forced codec ids */
for ( i = 0 ; i < ic - > nb_streams ; i + + )
choose_codec ( ic , ic - > streams [ i ] , ic - > streams [ i ] - > codec - > codec_type , codec_names ) ;
/* Set AVCodecContext options for avformat_find_stream_info */
opts = setup_find_stream_info_opts ( ic , codec_opts ) ;
orig_nb_streams = ic - > nb_streams ;
@ -3315,16 +3321,16 @@ static int opt_input_file(const char *opt, const char *filename)
if ( i < nb_ts_scale )
ist - > ts_scale = ts_scale [ i ] ;
ist - > dec = choose_codec ( ic , st , dec - > codec_type , codec_names ) ;
switch ( dec - > codec_type ) {
case AVMEDIA_TYPE_AUDIO :
ist - > dec = avcodec_find_decoder_by_name ( audio_codec_name ) ;
if ( ! ist - > dec )
ist - > dec = avcodec_find_decoder ( dec - > codec_id ) ;
if ( audio_disable )
st - > discard = AVDISCARD_ALL ;
break ;
case AVMEDIA_TYPE_VIDEO :
ist - > dec = avcodec_find_decoder_by_name ( video_codec_name ) ;
if ( ! ist - > dec )
ist - > dec = avcodec_find_decoder ( dec - > codec_id ) ;
rfps = ic - > streams [ i ] - > r_frame_rate . num ;
@ -3352,7 +3358,6 @@ static int opt_input_file(const char *opt, const char *filename)
case AVMEDIA_TYPE_DATA :
break ;
case AVMEDIA_TYPE_SUBTITLE :
ist - > dec = avcodec_find_decoder_by_name ( subtitle_codec_name ) ;
if ( ! ist - > dec )
ist - > dec = avcodec_find_decoder ( dec - > codec_id ) ;
if ( subtitle_disable )
@ -3390,9 +3395,7 @@ static int opt_input_file(const char *opt, const char *filename)
for ( i = 0 ; i < orig_nb_streams ; i + + )
av_dict_free ( & opts [ i ] ) ;
av_freep ( & opts ) ;
av_freep ( & video_codec_name ) ;
av_freep ( & audio_codec_name ) ;
av_freep ( & subtitle_codec_name ) ;
av_dict_free ( & codec_names ) ;
uninit_opts ( ) ;
init_opts ( ) ;
return 0 ;
@ -3403,22 +3406,10 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx)
AVStream * st ;
OutputStream * ost ;
AVCodecContext * video_enc ;
enum CodecID codec_id = CODEC_ID_NONE ;
AVCodec * codec = NULL ;
if ( ! video_stream_copy ) {
if ( video_codec_name ) {
codec_id = find_codec_or_die ( video_codec_name , AVMEDIA_TYPE_VIDEO , 1 ) ;
codec = avcodec_find_encoder_by_name ( video_codec_name ) ;
} else {
codec_id = av_guess_codec ( oc - > oformat , NULL , oc - > filename , NULL , AVMEDIA_TYPE_VIDEO ) ;
codec = avcodec_find_encoder ( codec_id ) ;
}
}
ost = new_output_stream ( oc , file_idx , codec ) ;
ost = new_output_stream ( oc , file_idx , AVMEDIA_TYPE_VIDEO ) ;
st = ost - > st ;
if ( ! video_ stream_copy) {
if ( ! st - > stream_copy ) {
ost - > frame_aspect_ratio = frame_aspect_ratio ;
frame_aspect_ratio = 0 ;
# if CONFIG_AVFILTER
@ -3441,9 +3432,7 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx)
video_enc - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
}
video_enc - > codec_type = AVMEDIA_TYPE_VIDEO ;
if ( video_stream_copy ) {
st - > stream_copy = 1 ;
if ( st - > stream_copy ) {
video_enc - > sample_aspect_ratio =
st - > sample_aspect_ratio = av_d2q ( frame_aspect_ratio * frame_height / frame_width , 255 ) ;
} else {
@ -3452,7 +3441,6 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx)
if ( frame_rate . num )
ost - > frame_rate = frame_rate ;
video_enc - > codec_id = codec_id ;
video_enc - > width = frame_width ;
video_enc - > height = frame_height ;
@ -3524,9 +3512,7 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx)
/* reset some key parameters */
video_disable = 0 ;
av_freep ( & video_codec_name ) ;
av_freep ( & forced_key_frames ) ;
video_stream_copy = 0 ;
frame_pix_fmt = PIX_FMT_NONE ;
return ost ;
}
@ -3535,20 +3521,9 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx)
{
AVStream * st ;
OutputStream * ost ;
AVCodec * codec = NULL ;
AVCodecContext * audio_enc ;
enum CodecID codec_id = CODEC_ID_NONE ;
if ( ! audio_stream_copy ) {
if ( audio_codec_name ) {
codec_id = find_codec_or_die ( audio_codec_name , AVMEDIA_TYPE_AUDIO , 1 ) ;
codec = avcodec_find_encoder_by_name ( audio_codec_name ) ;
} else {
codec_id = av_guess_codec ( oc - > oformat , NULL , oc - > filename , NULL , AVMEDIA_TYPE_AUDIO ) ;
codec = avcodec_find_encoder ( codec_id ) ;
}
}
ost = new_output_stream ( oc , file_idx , codec ) ;
ost = new_output_stream ( oc , file_idx , AVMEDIA_TYPE_AUDIO ) ;
st = ost - > st ;
ost - > bitstream_filters = audio_bitstream_filters ;
@ -3565,11 +3540,7 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx)
if ( oc - > oformat - > flags & AVFMT_GLOBALHEADER ) {
audio_enc - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
}
if ( audio_stream_copy ) {
st - > stream_copy = 1 ;
} else {
audio_enc - > codec_id = codec_id ;
if ( ! st - > stream_copy ) {
if ( audio_qscale > QSCALE_NONE ) {
audio_enc - > flags | = CODEC_FLAG_QSCALE ;
audio_enc - > global_quality = FF_QP2LAMBDA * audio_qscale ;
@ -3588,8 +3559,6 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx)
/* reset some key parameters */
audio_disable = 0 ;
av_freep ( & audio_codec_name ) ;
audio_stream_copy = 0 ;
return ost ;
}
@ -3600,29 +3569,22 @@ static OutputStream *new_data_stream(AVFormatContext *oc, int file_idx)
OutputStream * ost ;
AVCodecContext * data_enc ;
ost = new_output_stream ( oc , file_idx , NULL ) ;
ost = new_output_stream ( oc , file_idx , AVMEDIA_TYPE_DATA ) ;
st = ost - > st ;
data_enc = st - > codec ;
if ( ! data_ stream_copy) {
if ( ! st - > stream_copy ) {
fprintf ( stderr , " Data stream encoding not supported yet (only streamcopy) \n " ) ;
exit_program ( 1 ) ;
}
data_enc - > codec_type = AVMEDIA_TYPE_DATA ;
if ( data_codec_tag )
data_enc - > codec_tag = data_codec_tag ;
if ( oc - > oformat - > flags & AVFMT_GLOBALHEADER ) {
data_enc - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
}
if ( data_stream_copy ) {
st - > stream_copy = 1 ;
}
data_disable = 0 ;
av_freep ( & data_codec_name ) ;
data_stream_copy = 0 ;
return ost ;
}
@ -3630,20 +3592,9 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx)
{
AVStream * st ;
OutputStream * ost ;
AVCodec * codec = NULL ;
AVCodecContext * subtitle_enc ;
enum CodecID codec_id = CODEC_ID_NONE ;
if ( ! subtitle_stream_copy ) {
if ( subtitle_codec_name ) {
codec_id = find_codec_or_die ( subtitle_codec_name , AVMEDIA_TYPE_SUBTITLE , 1 ) ;
codec = avcodec_find_encoder_by_name ( subtitle_codec_name ) ;
} else {
codec_id = av_guess_codec ( oc - > oformat , NULL , oc - > filename , NULL , AVMEDIA_TYPE_SUBTITLE ) ;
codec = avcodec_find_encoder ( codec_id ) ;
}
}
ost = new_output_stream ( oc , file_idx , codec ) ;
ost = new_output_stream ( oc , file_idx , AVMEDIA_TYPE_SUBTITLE ) ;
st = ost - > st ;
subtitle_enc = st - > codec ;
@ -3658,11 +3609,6 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx)
if ( oc - > oformat - > flags & AVFMT_GLOBALHEADER ) {
subtitle_enc - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
}
if ( subtitle_stream_copy ) {
st - > stream_copy = 1 ;
} else {
subtitle_enc - > codec_id = codec_id ;
}
if ( subtitle_language ) {
av_dict_set ( & st - > metadata , " language " , subtitle_language , 0 ) ;
@ -3670,8 +3616,6 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx)
}
subtitle_disable = 0 ;
av_freep ( & subtitle_codec_name ) ;
subtitle_stream_copy = 0 ;
return ost ;
}
@ -3945,6 +3889,8 @@ static int opt_output_file(const char *opt, const char *filename)
av_freep ( & stream_maps ) ;
nb_stream_maps = 0 ;
av_dict_free ( & codec_names ) ;
av_freep ( & forced_key_frames ) ;
uninit_opts ( ) ;
init_opts ( ) ;
@ -4156,8 +4102,8 @@ static int opt_target(const char *opt, const char *arg)
}
if ( ! strcmp ( arg , " vcd " ) ) {
opt_video_ codec ( " vcodec " , " mpeg1video " ) ;
opt_audio_ codec ( " vcodec " , " mp2 " ) ;
opt_codec ( " c:v " , " mpeg1video " ) ;
opt_codec ( " c:a " , " mp2 " ) ;
opt_format ( " f " , " vcd " ) ;
opt_frame_size ( " s " , norm = = PAL ? " 352x288 " : " 352x240 " ) ;
@ -4184,8 +4130,8 @@ static int opt_target(const char *opt, const char *arg)
mux_preload = ( 36000 + 3 * 1200 ) / 90000.0 ; //0.44
} else if ( ! strcmp ( arg , " svcd " ) ) {
opt_video_ codec ( " vcodec " , " mpeg2video " ) ;
opt_audio_ codec ( " acodec " , " mp2 " ) ;
opt_codec ( " c:v " , " mpeg2video " ) ;
opt_codec ( " c:a " , " mp2 " ) ;
opt_format ( " f " , " svcd " ) ;
opt_frame_size ( " s " , norm = = PAL ? " 480x576 " : " 480x480 " ) ;
@ -4207,8 +4153,8 @@ static int opt_target(const char *opt, const char *arg)
} else if ( ! strcmp ( arg , " dvd " ) ) {
opt_video_ codec ( " vcodec " , " mpeg2video " ) ;
opt_audio_ codec ( " vcodec " , " ac3 " ) ;
opt_codec ( " c:v " , " mpeg2video " ) ;
opt_codec ( " c:a " , " ac3 " ) ;
opt_format ( " f " , " dvd " ) ;
opt_frame_size ( " vcodec " , norm = = PAL ? " 720x576 " : " 720x480 " ) ;
@ -4305,6 +4251,8 @@ static const OptionDef options[] = {
{ " f " , HAS_ARG , { ( void * ) opt_format } , " force format " , " fmt " } ,
{ " i " , HAS_ARG , { ( void * ) opt_input_file } , " input file name " , " filename " } ,
{ " y " , OPT_BOOL , { ( void * ) & file_overwrite } , " overwrite output files " } ,
{ " c " , HAS_ARG , { ( void * ) opt_codec } , " codec name " , " codec " } ,
{ " codec " , HAS_ARG , { ( void * ) opt_codec } , " codec name " , " codec " } ,
{ " map " , HAS_ARG | OPT_EXPERT , { ( void * ) opt_map } , " set input stream mapping " , " file.stream[:syncfile.syncstream] " } ,
{ " map_meta_data " , HAS_ARG | OPT_EXPERT , { ( void * ) opt_map_meta_data } , " DEPRECATED set meta data information of outfile from infile " ,
" outfile[,metadata]:infile[,metadata] " } ,