Commit 92f1940e authored by Anton Khirnov's avatar Anton Khirnov

avconv: replace -vcodec/-acodec/-scodec with a better system.

The new option doesn't depend on its placement wrt -new* options (which
don't exist anymore) and works in a similar way as per-stream AVOptions.

-[vas]codec remain as aliases to -codec:[vas]
parent ff884c79
...@@ -110,6 +110,8 @@ static int nb_output_files = 0; ...@@ -110,6 +110,8 @@ static int nb_output_files = 0;
static StreamMap *stream_maps = NULL; static StreamMap *stream_maps = NULL;
static int nb_stream_maps; static int nb_stream_maps;
static AVDictionary *codec_names;
/* first item specifies output metadata, second is input */ /* first item specifies output metadata, second is input */
static MetadataMap (*meta_data_maps)[2] = NULL; static MetadataMap (*meta_data_maps)[2] = NULL;
static int nb_meta_data_maps; static int nb_meta_data_maps;
...@@ -136,7 +138,6 @@ static uint16_t *inter_matrix = NULL; ...@@ -136,7 +138,6 @@ static uint16_t *inter_matrix = NULL;
static const char *video_rc_override_string=NULL; static const char *video_rc_override_string=NULL;
static int video_disable = 0; static int video_disable = 0;
static int video_discard = 0; static int video_discard = 0;
static char *video_codec_name = NULL;
static unsigned int video_codec_tag = 0; static unsigned int video_codec_tag = 0;
static char *video_language = NULL; static char *video_language = NULL;
static int same_quality = 0; static int same_quality = 0;
...@@ -155,17 +156,14 @@ static int audio_sample_rate = 0; ...@@ -155,17 +156,14 @@ static int audio_sample_rate = 0;
static float audio_qscale = QSCALE_NONE; static float audio_qscale = QSCALE_NONE;
static int audio_disable = 0; static int audio_disable = 0;
static int audio_channels = 0; static int audio_channels = 0;
static char *audio_codec_name = NULL;
static unsigned int audio_codec_tag = 0; static unsigned int audio_codec_tag = 0;
static char *audio_language = NULL; static char *audio_language = NULL;
static int subtitle_disable = 0; static int subtitle_disable = 0;
static char *subtitle_codec_name = NULL;
static char *subtitle_language = NULL; static char *subtitle_language = NULL;
static unsigned int subtitle_codec_tag = 0; static unsigned int subtitle_codec_tag = 0;
static int data_disable = 0; static int data_disable = 0;
static char *data_codec_name = NULL;
static unsigned int data_codec_tag = 0; static unsigned int data_codec_tag = 0;
static float mux_preload= 0.5; static float mux_preload= 0.5;
...@@ -182,10 +180,6 @@ static int do_pkt_dump = 0; ...@@ -182,10 +180,6 @@ static int do_pkt_dump = 0;
static int do_psnr = 0; static int do_psnr = 0;
static int do_pass = 0; static int do_pass = 0;
static char *pass_logfilename_prefix = NULL; static char *pass_logfilename_prefix = NULL;
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 video_sync_method= -1;
static int audio_sync_method= 0; static int audio_sync_method= 0;
static float audio_drift_threshold= 0.1; static float audio_drift_threshold= 0.1;
...@@ -470,11 +464,6 @@ static int exit_program(int ret) ...@@ -470,11 +464,6 @@ static int exit_program(int ret)
av_freep(&input_streams); av_freep(&input_streams);
av_freep(&input_files); 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(); uninit_opts();
av_free(audio_buf); av_free(audio_buf);
av_free(audio_out); av_free(audio_out);
...@@ -648,7 +637,59 @@ static void choose_pixel_fmt(AVStream *st, AVCodec *codec) ...@@ -648,7 +637,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; OutputStream *ost;
AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0); AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
...@@ -673,13 +714,14 @@ static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCode ...@@ -673,13 +714,14 @@ static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCode
ost->file_index = file_idx; ost->file_index = file_idx;
ost->index = idx; ost->index = idx;
ost->st = st; ost->st = st;
ost->enc = codec; st->codec->codec_type = type;
if (codec) { ost->enc = choose_codec(oc, st, type, codec_names);
st->codec->codec_type = codec->type; if (ost->enc) {
ost->opts = filter_codec_opts(codec_opts, codec->id, oc, st); ost->opts = filter_codec_opts(codec_opts, ost->enc->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); ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
return ost; return ost;
...@@ -701,7 +743,7 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename) ...@@ -701,7 +743,7 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename)
AVCodec *codec; AVCodec *codec;
codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id); 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; st = ost->st;
// FIXME: a more elegant solution is needed // FIXME: a more elegant solution is needed
...@@ -709,17 +751,10 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename) ...@@ -709,17 +751,10 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename)
st->info = NULL; st->info = NULL;
avcodec_copy_context(st->codec, ic->streams[i]->codec); avcodec_copy_context(st->codec, ic->streams[i]->codec);
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !st->stream_copy)
if (audio_stream_copy) { choose_sample_fmt(st, codec);
st->stream_copy = 1; else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !st->stream_copy)
} else choose_pixel_fmt(st, codec);
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->flags & CODEC_FLAG_BITEXACT) if(st->codec->flags & CODEC_FLAG_BITEXACT)
nopts = 1; nopts = 1;
...@@ -2740,36 +2775,29 @@ static int opt_audio_channels(const char *opt, const char *arg) ...@@ -2740,36 +2775,29 @@ static int opt_audio_channels(const char *opt, const char *arg)
return 0; return 0;
} }
static int opt_codec(int *pstream_copy, char **pcodec_name, static int opt_codec(const char *opt, const char *arg)
int codec_type, const char *arg)
{ {
av_freep(pcodec_name); return av_dict_set(&codec_names, opt, arg, 0);
if (!strcmp(arg, "copy")) {
*pstream_copy = 1;
} else {
*pcodec_name = av_strdup(arg);
}
return 0;
} }
static int opt_audio_codec(const char *opt, const char *arg) 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) 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) 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) 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) static int opt_codec_tag(const char *opt, const char *arg)
...@@ -2954,26 +2982,6 @@ static int opt_input_ts_offset(const char *opt, const char *arg) ...@@ -2954,26 +2982,6 @@ static int opt_input_ts_offset(const char *opt, const char *arg)
return 0; 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) static int opt_input_file(const char *opt, const char *filename)
{ {
...@@ -3024,12 +3032,6 @@ static int opt_input_file(const char *opt, const char *filename) ...@@ -3024,12 +3032,6 @@ static int opt_input_file(const char *opt, const char *filename)
if (frame_pix_fmt != PIX_FMT_NONE) if (frame_pix_fmt != PIX_FMT_NONE)
av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(frame_pix_fmt), 0); 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; ic->flags |= AVFMT_FLAG_NONBLOCK;
/* open the input file with generic libav function */ /* open the input file with generic libav function */
...@@ -3064,6 +3066,10 @@ static int opt_input_file(const char *opt, const char *filename) ...@@ -3064,6 +3066,10 @@ static int opt_input_file(const char *opt, const char *filename)
opt_programid=0; 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 */ /* Set AVCodecContext options for avformat_find_stream_info */
opts = setup_find_stream_info_opts(ic, codec_opts); opts = setup_find_stream_info_opts(ic, codec_opts);
orig_nb_streams = ic->nb_streams; orig_nb_streams = ic->nb_streams;
...@@ -3111,14 +3117,14 @@ static int opt_input_file(const char *opt, const char *filename) ...@@ -3111,14 +3117,14 @@ static int opt_input_file(const char *opt, const char *filename)
if (i < nb_ts_scale) if (i < nb_ts_scale)
ist->ts_scale = ts_scale[i]; ist->ts_scale = ts_scale[i];
ist->dec = choose_codec(ic, st, dec->codec_type, codec_names);
switch (dec->codec_type) { switch (dec->codec_type) {
case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_AUDIO:
ist->dec = avcodec_find_decoder_by_name(audio_codec_name);
if(audio_disable) if(audio_disable)
st->discard= AVDISCARD_ALL; st->discard= AVDISCARD_ALL;
break; break;
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
ist->dec = avcodec_find_decoder_by_name(video_codec_name);
rfps = ic->streams[i]->r_frame_rate.num; rfps = ic->streams[i]->r_frame_rate.num;
rfps_base = ic->streams[i]->r_frame_rate.den; rfps_base = ic->streams[i]->r_frame_rate.den;
if (dec->lowres) { if (dec->lowres) {
...@@ -3146,7 +3152,6 @@ static int opt_input_file(const char *opt, const char *filename) ...@@ -3146,7 +3152,6 @@ static int opt_input_file(const char *opt, const char *filename)
case AVMEDIA_TYPE_DATA: case AVMEDIA_TYPE_DATA:
break; break;
case AVMEDIA_TYPE_SUBTITLE: case AVMEDIA_TYPE_SUBTITLE:
ist->dec = avcodec_find_decoder_by_name(subtitle_codec_name);
if(subtitle_disable) if(subtitle_disable)
st->discard = AVDISCARD_ALL; st->discard = AVDISCARD_ALL;
break; break;
...@@ -3180,9 +3185,7 @@ static int opt_input_file(const char *opt, const char *filename) ...@@ -3180,9 +3185,7 @@ static int opt_input_file(const char *opt, const char *filename)
for (i = 0; i < orig_nb_streams; i++) for (i = 0; i < orig_nb_streams; i++)
av_dict_free(&opts[i]); av_dict_free(&opts[i]);
av_freep(&opts); av_freep(&opts);
av_freep(&video_codec_name); av_dict_free(&codec_names);
av_freep(&audio_codec_name);
av_freep(&subtitle_codec_name);
uninit_opts(); uninit_opts();
init_opts(); init_opts();
return 0; return 0;
...@@ -3193,22 +3196,10 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx) ...@@ -3193,22 +3196,10 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx)
AVStream *st; AVStream *st;
OutputStream *ost; OutputStream *ost;
AVCodecContext *video_enc; AVCodecContext *video_enc;
enum CodecID codec_id = CODEC_ID_NONE;
AVCodec *codec= NULL;
if(!video_stream_copy){ ost = new_output_stream(oc, file_idx, AVMEDIA_TYPE_VIDEO);
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);
st = ost->st; st = ost->st;
if (!video_stream_copy) { if (!st->stream_copy) {
ost->frame_aspect_ratio = frame_aspect_ratio; ost->frame_aspect_ratio = frame_aspect_ratio;
frame_aspect_ratio = 0; frame_aspect_ratio = 0;
#if CONFIG_AVFILTER #if CONFIG_AVFILTER
...@@ -3231,9 +3222,7 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx) ...@@ -3231,9 +3222,7 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx)
video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
} }
video_enc->codec_type = AVMEDIA_TYPE_VIDEO; if (st->stream_copy) {
if (video_stream_copy) {
st->stream_copy = 1;
video_enc->sample_aspect_ratio = video_enc->sample_aspect_ratio =
st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255); st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
} else { } else {
...@@ -3242,7 +3231,6 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx) ...@@ -3242,7 +3231,6 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx)
if (frame_rate.num) if (frame_rate.num)
ost->frame_rate = frame_rate; ost->frame_rate = frame_rate;
video_enc->codec_id = codec_id;
video_enc->width = frame_width; video_enc->width = frame_width;
video_enc->height = frame_height; video_enc->height = frame_height;
...@@ -3313,9 +3301,7 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx) ...@@ -3313,9 +3301,7 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx)
/* reset some key parameters */ /* reset some key parameters */
video_disable = 0; video_disable = 0;
av_freep(&video_codec_name);
av_freep(&forced_key_frames); av_freep(&forced_key_frames);
video_stream_copy = 0;
frame_pix_fmt = PIX_FMT_NONE; frame_pix_fmt = PIX_FMT_NONE;
return ost; return ost;
} }
...@@ -3324,20 +3310,9 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx) ...@@ -3324,20 +3310,9 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx)
{ {
AVStream *st; AVStream *st;
OutputStream *ost; OutputStream *ost;
AVCodec *codec= NULL;
AVCodecContext *audio_enc; AVCodecContext *audio_enc;
enum CodecID codec_id = CODEC_ID_NONE;
if(!audio_stream_copy){ ost = new_output_stream(oc, file_idx, AVMEDIA_TYPE_AUDIO);
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);
st = ost->st; st = ost->st;
ost->bitstream_filters = audio_bitstream_filters; ost->bitstream_filters = audio_bitstream_filters;
...@@ -3354,11 +3329,7 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx) ...@@ -3354,11 +3329,7 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx)
if (oc->oformat->flags & AVFMT_GLOBALHEADER) { if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
} }
if (audio_stream_copy) { if (!st->stream_copy) {
st->stream_copy = 1;
} else {
audio_enc->codec_id = codec_id;
if (audio_qscale > QSCALE_NONE) { if (audio_qscale > QSCALE_NONE) {
audio_enc->flags |= CODEC_FLAG_QSCALE; audio_enc->flags |= CODEC_FLAG_QSCALE;
audio_enc->global_quality = FF_QP2LAMBDA * audio_qscale; audio_enc->global_quality = FF_QP2LAMBDA * audio_qscale;
...@@ -3377,8 +3348,6 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx) ...@@ -3377,8 +3348,6 @@ static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx)
/* reset some key parameters */ /* reset some key parameters */
audio_disable = 0; audio_disable = 0;
av_freep(&audio_codec_name);
audio_stream_copy = 0;
return ost; return ost;
} }
...@@ -3389,29 +3358,22 @@ static OutputStream *new_data_stream(AVFormatContext *oc, int file_idx) ...@@ -3389,29 +3358,22 @@ static OutputStream *new_data_stream(AVFormatContext *oc, int file_idx)
OutputStream *ost; OutputStream *ost;
AVCodecContext *data_enc; AVCodecContext *data_enc;
ost = new_output_stream(oc, file_idx, NULL); ost = new_output_stream(oc, file_idx, AVMEDIA_TYPE_DATA);
st = ost->st; st = ost->st;
data_enc = st->codec; data_enc = st->codec;
if (!data_stream_copy) { if (!st->stream_copy) {
fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n"); fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n");
exit_program(1); exit_program(1);
} }
data_enc->codec_type = AVMEDIA_TYPE_DATA;
if (data_codec_tag) if (data_codec_tag)
data_enc->codec_tag= data_codec_tag; data_enc->codec_tag= data_codec_tag;
if (oc->oformat->flags & AVFMT_GLOBALHEADER) { if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
data_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; data_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
} }
if (data_stream_copy) {
st->stream_copy = 1;
}
data_disable = 0; data_disable = 0;
av_freep(&data_codec_name);
data_stream_copy = 0;
return ost; return ost;
} }
...@@ -3419,20 +3381,9 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx) ...@@ -3419,20 +3381,9 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx)
{ {
AVStream *st; AVStream *st;
OutputStream *ost; OutputStream *ost;
AVCodec *codec=NULL;
AVCodecContext *subtitle_enc; AVCodecContext *subtitle_enc;
enum CodecID codec_id = CODEC_ID_NONE;
if(!subtitle_stream_copy){ ost = new_output_stream(oc, file_idx, AVMEDIA_TYPE_SUBTITLE);
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);
st = ost->st; st = ost->st;
subtitle_enc = st->codec; subtitle_enc = st->codec;
...@@ -3447,11 +3398,6 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx) ...@@ -3447,11 +3398,6 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx)
if (oc->oformat->flags & AVFMT_GLOBALHEADER) { if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
subtitle_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; 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) { if (subtitle_language) {
av_dict_set(&st->metadata, "language", subtitle_language, 0); av_dict_set(&st->metadata, "language", subtitle_language, 0);
...@@ -3459,8 +3405,6 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx) ...@@ -3459,8 +3405,6 @@ static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx)
} }
subtitle_disable = 0; subtitle_disable = 0;
av_freep(&subtitle_codec_name);
subtitle_stream_copy = 0;
return ost; return ost;
} }
...@@ -3742,6 +3686,8 @@ static void opt_output_file(const char *filename) ...@@ -3742,6 +3686,8 @@ static void opt_output_file(const char *filename)
av_freep(&stream_maps); av_freep(&stream_maps);
nb_stream_maps = 0; nb_stream_maps = 0;
av_dict_free(&codec_names);
av_freep(&forced_key_frames); av_freep(&forced_key_frames);
uninit_opts(); uninit_opts();
init_opts(); init_opts();
...@@ -3949,8 +3895,8 @@ static int opt_target(const char *opt, const char *arg) ...@@ -3949,8 +3895,8 @@ static int opt_target(const char *opt, const char *arg)
} }
if(!strcmp(arg, "vcd")) { if(!strcmp(arg, "vcd")) {
opt_video_codec("vcodec", "mpeg1video"); opt_codec("c:v", "mpeg1video");
opt_audio_codec("vcodec", "mp2"); opt_codec("c:a", "mp2");
opt_format("f", "vcd"); opt_format("f", "vcd");
opt_frame_size("s", norm == PAL ? "352x288" : "352x240"); opt_frame_size("s", norm == PAL ? "352x288" : "352x240");
...@@ -3977,8 +3923,8 @@ static int opt_target(const char *opt, const char *arg) ...@@ -3977,8 +3923,8 @@ static int opt_target(const char *opt, const char *arg)
mux_preload= (36000+3*1200) / 90000.0; //0.44 mux_preload= (36000+3*1200) / 90000.0; //0.44
} else if(!strcmp(arg, "svcd")) { } else if(!strcmp(arg, "svcd")) {
opt_video_codec("vcodec", "mpeg2video"); opt_codec("c:v", "mpeg2video");
opt_audio_codec("acodec", "mp2"); opt_codec("c:a", "mp2");
opt_format("f", "svcd"); opt_format("f", "svcd");
opt_frame_size("s", norm == PAL ? "480x576" : "480x480"); opt_frame_size("s", norm == PAL ? "480x576" : "480x480");
...@@ -3999,8 +3945,8 @@ static int opt_target(const char *opt, const char *arg) ...@@ -3999,8 +3945,8 @@ static int opt_target(const char *opt, const char *arg)
} else if(!strcmp(arg, "dvd")) { } else if(!strcmp(arg, "dvd")) {
opt_video_codec("vcodec", "mpeg2video"); opt_codec("c:v", "mpeg2video");
opt_audio_codec("vcodec", "ac3"); opt_codec("c:a", "ac3");
opt_format("f", "dvd"); opt_format("f", "dvd");
opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480"); opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480");
...@@ -4082,6 +4028,8 @@ static const OptionDef options[] = { ...@@ -4082,6 +4028,8 @@ static const OptionDef options[] = {
{ "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
{ "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" }, { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
{ "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, { "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", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
{ "map_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", { "map_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
"outfile[,metadata]:infile[,metadata]" }, "outfile[,metadata]:infile[,metadata]" },
......
...@@ -97,6 +97,34 @@ input file name ...@@ -97,6 +97,34 @@ input file name
@item -y @item -y
Overwrite output files. Overwrite output files.
@item -c[:@var{stream_type}][:@var{stream_index}] @var{codec}
@item -codec[:@var{stream_type}][:@var{stream_index}] @var{codec}
Select an encoder (when used before an output file) or a decoder (when used
before an input file) for one or more streams. @var{codec} is the name of a
decoder/encoder or a special value @code{copy} (output only) to indicate that
the stream is not to be reencoded.
@var{stream_type} may be 'v' for video, 'a' for audio, 's' for subtitle and 'd'
for data streams. @var{stream_index} is a global zero-based stream index if
@var{stream_type} isn't given, otherwise it counts only streams of the given
type. If @var{stream_index} is omitted, this option applies to all streams of
the given type or all streams of any type if @var{stream_type} is missing as
well (note that this only makes sense when all streams are of the same type or
@var{codec} is @code{copy}).
For example
@example
avconv -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
@end example
encodes all video streams with libx264 and copies all audio streams.
For each stream, the last matching @code{c} option is applied, so
@example
avconv -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:137 libvorbis OUTPUT
@end example
will copy all the streams except the second video, which will be encoded with
libx264, and the 138th audio, which will be encoded with libvorbis.
@item -t @var{duration} @item -t @var{duration}
Restrict the transcoded/captured video sequence Restrict the transcoded/captured video sequence
to the duration specified in seconds. to the duration specified in seconds.
...@@ -159,9 +187,6 @@ avconv -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg ...@@ -159,9 +187,6 @@ avconv -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
@item -dframes @var{number} @item -dframes @var{number}
Set the number of data frames to record. Set the number of data frames to record.
@item -scodec @var{codec}
Force subtitle codec ('copy' to copy stream).
@item -slang @var{code} @item -slang @var{code}
Set the ISO 639 language code (3 letters) of the current subtitle stream. Set the ISO 639 language code (3 letters) of the current subtitle stream.
...@@ -282,8 +307,7 @@ It is of little use elsewise. ...@@ -282,8 +307,7 @@ It is of little use elsewise.
@item -bufsize @var{size} @item -bufsize @var{size}
Set video buffer verifier buffer size (in bits). Set video buffer verifier buffer size (in bits).
@item -vcodec @var{codec} @item -vcodec @var{codec}
Force video codec to @var{codec}. Use the @code{copy} special value to Set the video codec. This is an alias for @code{-codec:v}.
tell that the raw codec data must be copied as is.
@item -sameq @item -sameq
Use same quantizer as source (implies VBR). Use same quantizer as source (implies VBR).
...@@ -296,8 +320,8 @@ at the exact requested bitrate. ...@@ -296,8 +320,8 @@ at the exact requested bitrate.
On pass 1, you may just deactivate audio and set output to null, On pass 1, you may just deactivate audio and set output to null,
examples for Windows and Unix: examples for Windows and Unix:
@example @example
avconv -i foo.mov -vcodec libxvid -pass 1 -an -f rawvideo -y NUL avconv -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y NUL
avconv -i foo.mov -vcodec libxvid -pass 1 -an -f rawvideo -y /dev/null avconv -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y /dev/null
@end example @end example
@item -passlogfile @var{prefix} @item -passlogfile @var{prefix}
...@@ -541,7 +565,7 @@ Show QP histogram. ...@@ -541,7 +565,7 @@ Show QP histogram.
@item -vbsf @var{bitstream_filter} @item -vbsf @var{bitstream_filter}
Bitstream filters available are "dump_extra", "remove_extra", "noise", "h264_mp4toannexb", "imxdump", "mjpegadump", "mjpeg2jpeg". Bitstream filters available are "dump_extra", "remove_extra", "noise", "h264_mp4toannexb", "imxdump", "mjpegadump", "mjpeg2jpeg".
@example @example
avconv -i h264.mp4 -vcodec copy -vbsf h264_mp4toannexb -an out.h264 avconv -i h264.mp4 -c:v copy -vbsf h264_mp4toannexb -an out.h264
@end example @end example
@item -force_key_frames @var{time}[,@var{time}...] @item -force_key_frames @var{time}[,@var{time}...]
Force key frames at the specified timestamps, more precisely at the first Force key frames at the specified timestamps, more precisely at the first
...@@ -571,8 +595,7 @@ and is mapped to the corresponding demuxer options. ...@@ -571,8 +595,7 @@ and is mapped to the corresponding demuxer options.
@item -an @item -an
Disable audio recording. Disable audio recording.
@item -acodec @var{codec} @item -acodec @var{codec}
Force audio codec to @var{codec}. Use the @code{copy} special value to Set the audio codec. This is an alias for @code{-codec:a}.
specify that the raw codec data must be copied as is.
@item -alang @var{code} @item -alang @var{code}
Set the ISO 639 language code (3 letters) of the current audio stream. Set the ISO 639 language code (3 letters) of the current audio stream.
@end table @end table
...@@ -612,7 +635,7 @@ Bitstream filters available are "dump_extra", "remove_extra", "noise", "mp3comp" ...@@ -612,7 +635,7 @@ Bitstream filters available are "dump_extra", "remove_extra", "noise", "mp3comp"
@table @option @table @option
@item -scodec @var{codec} @item -scodec @var{codec}
Force subtitle codec ('copy' to copy stream). Set the subtitle codec. This is an alias for @code{-codec:s}.
@item -slang @var{code} @item -slang @var{code}
Set the ISO 639 language code (3 letters) of the current subtitle stream. Set the ISO 639 language code (3 letters) of the current subtitle stream.
@item -sn @item -sn
...@@ -620,7 +643,7 @@ Disable subtitle recording. ...@@ -620,7 +643,7 @@ Disable subtitle recording.
@item -sbsf @var{bitstream_filter} @item -sbsf @var{bitstream_filter}
Bitstream filters available are "mov2textsub", "text2movsub". Bitstream filters available are "mov2textsub", "text2movsub".
@example @example
avconv -i file.mov -an -vn -sbsf mov2textsub -scodec copy -f rawvideo sub.txt avconv -i file.mov -an -vn -sbsf mov2textsub -c:s copy -f rawvideo sub.txt
@end example @end example
@end table @end table
...@@ -677,7 +700,7 @@ For example, to select the stream with index 2 from input file ...@@ -677,7 +700,7 @@ For example, to select the stream with index 2 from input file
index 6 from input @file{b.mov} (specified by the identifier "1:6"), index 6 from input @file{b.mov} (specified by the identifier "1:6"),
and copy them to the output file @file{out.mov}: and copy them to the output file @file{out.mov}:
@example @example
avconv -i a.mov -i b.mov -vcodec copy -acodec copy -map 0:2 -map 1:6 out.mov avconv -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov
@end example @end example
To select all video and the third audio stream from an input file: To select all video and the third audio stream from an input file:
...@@ -945,7 +968,7 @@ stream, in the order of the definition of output streams. ...@@ -945,7 +968,7 @@ stream, in the order of the definition of output streams.
You can transcode decrypted VOBs: You can transcode decrypted VOBs:
@example @example
avconv -i snatch_1.vob -f avi -vcodec mpeg4 -b 800k -g 300 -bf 2 -acodec libmp3lame -ab 128k snatch.avi avconv -i snatch_1.vob -f avi -c:v mpeg4 -b 800k -g 300 -bf 2 -c:a libmp3lame -ab 128k snatch.avi
@end example @end example
This is a typical DVD ripping example; the input is a VOB file, the This is a typical DVD ripping example; the input is a VOB file, the
...@@ -989,7 +1012,7 @@ only formats accepting a normal integer are suitable. ...@@ -989,7 +1012,7 @@ only formats accepting a normal integer are suitable.
You can put many streams of the same type in the output: You can put many streams of the same type in the output:
@example @example
avconv -i test1.avi -i test2.avi -map 0.3 -map 0.2 -map 0.1 -map 0.0 -vcodec copy -acodec copy -vcodec copy -acodec copy test12.nut avconv -i test1.avi -i test2.avi -map 0.3 -map 0.2 -map 0.1 -map 0.0 -c copy test12.nut
@end example @end example
The resulting output file @file{test12.avi} will contain first four streams from The resulting output file @file{test12.avi} will contain first four streams from
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment