diff --git a/Changelog b/Changelog index b83f9ee898f07428b21ec3331563b194bd7bbd7e..caf9a53cc8713f4ffdc33816d59d1d394df4a8bd 100644 --- a/Changelog +++ b/Changelog @@ -8,6 +8,39 @@ version next: - BWF muxer - Flash Screen Video 2 decoder - lavfi input device added +- added avconv, which is almost the same for now, except +for a few incompatible changes in the options, which will hopefully make them +easier to use. The changes are: + * -newvideo/-newaudio/-newsubtitle are gone, because they were redundant and + worked in a nonstandard way. -map is sufficient to add streams to output + files. + * -map now has slightly different and more powerful syntax. + + it's possible to specify stream type. E.g. -map 0:a:2 means 'third + audio stream'. + + omitting the stream index now maps all the streams of the given + type, not just the first. E.g. -map 0:s maps all the subtitle streams. + + colons (':') are used to separate file index/stream type/stream + index. Comma (',') is used to separate the sync stream. This is done + for consistency with other options. + + since -map can now match multiple streams, negative mappings were + introduced. Negative mappings disable some streams from an already + defined map. E.g. '-map 0 -map -0:a:1' means 'map everything except + for the second audio stream'. + * -vcodec/-acodec/-scodec are replaced by -c (or -codec), which + allows to precisely specify target stream(s) consistently with other + options. E.g. '-c:v libx264' sets the codec for all video streams, + '-c:a:0 libvorbis' sets the codec for the first audio stream and '-c + copy' copies all the streams. + * It is now possible to precisely specify which stream should an AVOption + apply to. See the manual for detailed explanation. + * -map_chapters now takes only an input file index and applies to the next + output file. This is consistent with how all the other options work. + * -map_metadata now takes only an input metadata specifier and applies to + the next output file. Output metadata specifier is now part of the option + name, similarly to the AVOptions/map/codec feature above. + * Presets in avconv are disabled, because only libx264 used them and + presets for libx264 can now be specified using a private option + '-preset '. version 0.8: diff --git a/avconv.c b/avconv.c index f99b8d9f9c0c56a81714978c2f3af861a4cbf90e..34fe1837834cc73260171fbccfc3c184ca798fd1 100644 --- a/avconv.c +++ b/avconv.c @@ -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,10 +151,9 @@ 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_quality = 0; +static int same_quant = 0; static int do_deinterlace = 0; static int top_field_first = -1; static int me_threshold = 0; @@ -168,17 +169,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; @@ -195,10 +193,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; @@ -548,11 +542,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); @@ -689,88 +678,6 @@ static void choose_pixel_fmt(AVStream *st, AVCodec *codec) } } -static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCodec *codec) -{ - OutputStream *ost; - AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0); - int idx = oc->nb_streams - 1; - - if (!st) { - av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n"); - exit_program(1); - } - - output_streams_for_file[file_idx] = - grow_array(output_streams_for_file[file_idx], - sizeof(*output_streams_for_file[file_idx]), - &nb_output_streams_for_file[file_idx], - oc->nb_streams); - ost = output_streams_for_file[file_idx][idx] = - av_mallocz(sizeof(OutputStream)); - if (!ost) { - fprintf(stderr, "Could not alloc output stream\n"); - exit_program(1); - } - ost->file_index = file_idx; - ost->index = idx; - ost->st = st; - ost->enc = codec; - if (codec) { - st->codec->codec_type = codec->type; - ost->opts = filter_codec_opts(codec_opts, codec->id, oc, st); - } - - avcodec_get_context_defaults3(st->codec, codec); - - ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL); - return ost; -} - -static int read_ffserver_streams(AVFormatContext *s, const char *filename) -{ - int i, err; - AVFormatContext *ic = NULL; - int nopts = 0; - - err = avformat_open_input(&ic, filename, NULL, NULL); - if (err < 0) - return err; - /* copy stream format */ - for(i=0;inb_streams;i++) { - AVStream *st; - OutputStream *ost; - AVCodec *codec; - - codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id); - ost = new_output_stream(s, nb_output_files, codec); - st = ost->st; - - // FIXME: a more elegant solution is needed - memcpy(st, ic->streams[i], sizeof(AVStream)); - st->info = av_malloc(sizeof(*st->info)); - 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->flags & CODEC_FLAG_BITEXACT) - nopts = 1; - } - - av_close_input_file(ic); - return 0; -} - static double get_sync_ipts(const OutputStream *ost) { @@ -1310,7 +1217,7 @@ static void do_video_out(AVFormatContext *s, big_picture.top_field_first = top_field_first; } - /* handles sameq here. This is not correct because it may + /* handles same_quant here. This is not correct because it may not be a global option */ big_picture.quality = quality; if(!me_threshold) @@ -1637,7 +1544,7 @@ static int output_packet(InputStream *ist, int ist_index, ret = avcodec_decode_video2(ist->st->codec, &picture, &got_output, &avpkt); - quality = same_quality ? picture.quality : 0; + quality = same_quant ? picture.quality : 0; if (ret < 0) return ret; if (!got_output) { @@ -1764,7 +1671,7 @@ static int output_packet(InputStream *ist, int ist_index, ost->st->codec->sample_aspect_ratio = ost->picref->video->sample_aspect_ratio; #endif do_video_out(os, ost, ist, &picture, &frame_size, - same_quality ? quality : ost->st->codec->global_quality); + same_quant ? quality : ost->st->codec->global_quality); if (vstats_filename && frame_size) do_video_stats(os, ost, frame_size); break; @@ -1958,69 +1865,6 @@ static void print_sdp(AVFormatContext **avc, int n) fflush(stdout); } -static int copy_chapters(int infile, int outfile) -{ - AVFormatContext *is = input_files[infile].ctx; - AVFormatContext *os = output_files[outfile]; - int i; - - for (i = 0; i < is->nb_chapters; i++) { - AVChapter *in_ch = is->chapters[i], *out_ch; - int64_t ts_off = av_rescale_q(start_time - input_files[infile].ts_offset, - AV_TIME_BASE_Q, in_ch->time_base); - int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX : - av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base); - - - if (in_ch->end < ts_off) - continue; - if (rt != INT64_MAX && in_ch->start > rt + ts_off) - break; - - out_ch = av_mallocz(sizeof(AVChapter)); - if (!out_ch) - return AVERROR(ENOMEM); - - out_ch->id = in_ch->id; - out_ch->time_base = in_ch->time_base; - out_ch->start = FFMAX(0, in_ch->start - ts_off); - out_ch->end = FFMIN(rt, in_ch->end - ts_off); - - if (metadata_chapters_autocopy) - av_dict_copy(&out_ch->metadata, in_ch->metadata, 0); - - os->nb_chapters++; - os->chapters = av_realloc(os->chapters, sizeof(AVChapter)*os->nb_chapters); - if (!os->chapters) - return AVERROR(ENOMEM); - os->chapters[os->nb_chapters - 1] = out_ch; - } - return 0; -} - -static void parse_forced_key_frames(char *kf, OutputStream *ost, - AVCodecContext *avctx) -{ - char *p; - int n = 1, i; - int64_t t; - - for (p = kf; *p; p++) - if (*p == ',') - n++; - ost->forced_kf_count = n; - ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n); - if (!ost->forced_kf_pts) { - av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n"); - exit_program(1); - } - for (i = 0; i < n; i++) { - p = i ? strchr(p, ',') + 1 : kf; - t = parse_time_or_die("force_key_frames", p, 1); - ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); - } -} - /* * The following code is the main loop of the file converter */ @@ -2892,20 +2736,27 @@ static int opt_audio_channels(const char *opt, const char *arg) static int opt_codec(const char *opt, const char *arg) { - int *pstream_copy; char **pcodec_name; enum AVMediaType codec_type; + return av_dict_set(&codec_names, opt, arg, 0); +} - if (!strcmp(opt, "acodec")) { pstream_copy = &audio_stream_copy; pcodec_name = &audio_codec_name; codec_type = AVMEDIA_TYPE_AUDIO; } - else if (!strcmp(opt, "vcodec")) { pstream_copy = &video_stream_copy; pcodec_name = &video_codec_name; codec_type = AVMEDIA_TYPE_VIDEO; } - else if (!strcmp(opt, "scodec")) { pstream_copy = &subtitle_stream_copy; pcodec_name = &subtitle_codec_name; codec_type = AVMEDIA_TYPE_SUBTITLE; } - else if (!strcmp(opt, "dcodec")) { pstream_copy = &data_stream_copy; pcodec_name = &data_codec_name; codec_type = AVMEDIA_TYPE_DATA; } +static int opt_audio_codec(const char *opt, const char *arg) +{ + return opt_codec("codec:a", arg); +} - av_freep(pcodec_name); - if (!strcmp(arg, "copy")) { - *pstream_copy = 1; - } else { - *pcodec_name = av_strdup(arg); - } - return 0; +static int opt_video_codec(const char *opt, const char *arg) +{ + return opt_codec("codec:v", arg); +} + +static int opt_subtitle_codec(const char *opt, const char *arg) +{ + return opt_codec("codec:s", arg); +} + +static int opt_data_codec(const char *opt, const char *arg) +{ + return opt_codec("codec:d", arg); } static int opt_codec_tag(const char *opt, const char *arg) @@ -3093,7 +2944,7 @@ 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) +static enum CodecID find_codec_or_die(const char *name, enum AVMediaType type, int encoder) { const char *codec_string = encoder ? "encoder" : "decoder"; AVCodec *codec; @@ -3104,16 +2955,47 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder) avcodec_find_encoder_by_name(name) : avcodec_find_decoder_by_name(name); if(!codec) { - fprintf(stderr, "Unknown %s '%s'\n", codec_string, name); + av_log(NULL, AV_LOG_ERROR, "Unknown %s '%s'\n", codec_string, name); exit_program(1); } if(codec->type != type) { - fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name); + 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 int opt_input_file(const char *opt, const char *filename) { AVFormatContext *ic; @@ -3163,12 +3045,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; /* open the input file with generic libav function */ @@ -3203,6 +3079,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; @@ -3250,16 +3130,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; @@ -3287,7 +3167,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) @@ -3325,35 +3204,82 @@ 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; } -static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx) +static void parse_forced_key_frames(char *kf, OutputStream *ost, + AVCodecContext *avctx) +{ + char *p; + int n = 1, i; + int64_t t; + + for (p = kf; *p; p++) + if (*p == ',') + n++; + ost->forced_kf_count = n; + ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n); + if (!ost->forced_kf_pts) { + av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n"); + exit_program(1); + } + for (i = 0; i < n; i++) { + p = i ? strchr(p, ',') + 1 : kf; + t = parse_time_or_die("force_key_frames", p, 1); + ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); + } +} + +static OutputStream *new_output_stream(AVFormatContext *oc, enum AVMediaType type) { - AVStream *st; OutputStream *ost; - AVCodecContext *video_enc; - enum CodecID codec_id = CODEC_ID_NONE; - AVCodec *codec= NULL; + AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0); + int idx = oc->nb_streams - 1; - 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); - } + if (!st) { + av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n"); + exit_program(1); + } + + output_streams_for_file[nb_output_files] = + grow_array(output_streams_for_file[nb_output_files], + sizeof(*output_streams_for_file[nb_output_files]), + &nb_output_streams_for_file[nb_output_files], + oc->nb_streams); + ost = output_streams_for_file[nb_output_files][idx] = + av_mallocz(sizeof(OutputStream)); + if (!ost) { + fprintf(stderr, "Could not alloc output stream\n"); + exit_program(1); + } + ost->file_index = nb_output_files; + ost->index = idx; + ost->st = 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->enc->id, oc, st); } - ost = new_output_stream(oc, file_idx, 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; +} + +static OutputStream *new_video_stream(AVFormatContext *oc) +{ + AVStream *st; + OutputStream *ost; + AVCodecContext *video_enc; + + ost = new_output_stream(oc, 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 @@ -3376,9 +3302,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 { @@ -3387,7 +3311,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; @@ -3397,7 +3320,7 @@ static OutputStream *new_video_stream(AVFormatContext *oc, int file_idx) if (intra_only) video_enc->gop_size = 0; - if (video_qscale || same_quality) { + if (video_qscale || same_quant) { video_enc->flags |= CODEC_FLAG_QSCALE; video_enc->global_quality = FF_QP2LAMBDA * video_qscale; } @@ -3459,31 +3382,18 @@ 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; } -static OutputStream *new_audio_stream(AVFormatContext *oc, int file_idx) +static OutputStream *new_audio_stream(AVFormatContext *oc) { 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, AVMEDIA_TYPE_AUDIO); st = ost->st; ost->bitstream_filters = audio_bitstream_filters; @@ -3500,11 +3410,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; @@ -3523,62 +3429,42 @@ 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; } -static OutputStream *new_data_stream(AVFormatContext *oc, int file_idx) +static OutputStream *new_data_stream(AVFormatContext *oc) { AVStream *st; OutputStream *ost; AVCodecContext *data_enc; - ost = new_output_stream(oc, file_idx, NULL); + ost = new_output_stream(oc, 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; } -static OutputStream *new_subtitle_stream(AVFormatContext *oc, int file_idx) +static OutputStream *new_subtitle_stream(AVFormatContext *oc) { 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, AVMEDIA_TYPE_SUBTITLE); st = ost->st; subtitle_enc = st->codec; @@ -3593,11 +3479,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); @@ -3605,8 +3486,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; } @@ -3632,6 +3511,80 @@ static int opt_streamid(const char *opt, const char *arg) return 0; } +static int copy_chapters(int infile, int outfile) +{ + AVFormatContext *is = input_files[infile].ctx; + AVFormatContext *os = output_files[outfile]; + int i; + + for (i = 0; i < is->nb_chapters; i++) { + AVChapter *in_ch = is->chapters[i], *out_ch; + int64_t ts_off = av_rescale_q(start_time - input_files[infile].ts_offset, + AV_TIME_BASE_Q, in_ch->time_base); + int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX : + av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base); + + + if (in_ch->end < ts_off) + continue; + if (rt != INT64_MAX && in_ch->start > rt + ts_off) + break; + + out_ch = av_mallocz(sizeof(AVChapter)); + if (!out_ch) + return AVERROR(ENOMEM); + + out_ch->id = in_ch->id; + out_ch->time_base = in_ch->time_base; + out_ch->start = FFMAX(0, in_ch->start - ts_off); + out_ch->end = FFMIN(rt, in_ch->end - ts_off); + + if (metadata_chapters_autocopy) + av_dict_copy(&out_ch->metadata, in_ch->metadata, 0); + + os->nb_chapters++; + os->chapters = av_realloc(os->chapters, sizeof(AVChapter)*os->nb_chapters); + if (!os->chapters) + return AVERROR(ENOMEM); + os->chapters[os->nb_chapters - 1] = out_ch; + } + return 0; +} + +static int read_ffserver_streams(AVFormatContext *s, const char *filename) +{ + int i, err; + AVFormatContext *ic = NULL; + + err = avformat_open_input(&ic, filename, NULL, NULL); + if (err < 0) + return err; + /* copy stream format */ + for(i=0;inb_streams;i++) { + AVStream *st; + OutputStream *ost; + AVCodec *codec; + + codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id); + ost = new_output_stream(s, codec->type); + st = ost->st; + + // FIXME: a more elegant solution is needed + memcpy(st, ic->streams[i], sizeof(AVStream)); + st->info = av_malloc(sizeof(*st->info)); + 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 && !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); + return 0; +} + static int opt_output_file(const char *opt, const char *filename) { AVFormatContext *oc; @@ -3670,7 +3623,7 @@ static int opt_output_file(const char *opt, const char *filename) /* pick the "best" stream of each type */ #define NEW_STREAM(type, index)\ if (index >= 0) {\ - ost = new_ ## type ## _stream(oc, nb_output_files);\ + ost = new_ ## type ## _stream(oc);\ ost->source_index = index;\ ost->sync_ist = &input_streams[index];\ input_streams[index].discard = 0;\ @@ -3722,10 +3675,10 @@ static int opt_output_file(const char *opt, const char *filename) ist = &input_streams[input_files[map->file_index].ist_index + map->stream_index]; switch (ist->st->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(oc, nb_output_files); break; - case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(oc, nb_output_files); break; - case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(oc, nb_output_files); break; - case AVMEDIA_TYPE_DATA: ost = new_data_stream(oc, nb_output_files); break; + case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(oc); break; + case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(oc); break; + case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(oc); break; + case AVMEDIA_TYPE_DATA: ost = new_data_stream(oc); break; default: av_log(NULL, AV_LOG_ERROR, "Cannot map stream #%d.%d - unsupported type.\n", map->file_index, map->stream_index); @@ -3876,6 +3829,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(); @@ -4087,8 +4042,8 @@ static int opt_target(const char *opt, const char *arg) } if(!strcmp(arg, "vcd")) { - opt_codec("vcodec", "mpeg1video"); - opt_codec("acodec", "mp2"); + opt_codec("c:v", "mpeg1video"); + opt_codec("c:a", "mp2"); opt_format("f", "vcd"); opt_frame_size("s", norm == PAL ? "352x288" : "352x240"); @@ -4100,7 +4055,7 @@ static int opt_target(const char *opt, const char *arg) opt_default("minrate", "1150000"); opt_default("bufsize", "327680"); // 40*1024*8; - opt_default("ab", "224000"); + opt_default("b:a", "224000"); audio_sample_rate = 44100; audio_channels = 2; @@ -4115,8 +4070,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_codec("vcodec", "mpeg2video"); - opt_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"); @@ -4131,15 +4086,15 @@ static int opt_target(const char *opt, const char *arg) opt_default("flags", "+scan_offset"); - opt_default("ab", "224000"); + opt_default("b:a", "224000"); audio_sample_rate = 44100; opt_default("packetsize", "2324"); } else if(!strcmp(arg, "dvd")) { - opt_codec("vcodec", "mpeg2video"); - opt_codec("acodec", "ac3"); + opt_codec("c:v", "mpeg2video"); + opt_codec("c:a", "ac3"); opt_format("f", "dvd"); opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480"); @@ -4155,7 +4110,7 @@ static int opt_target(const char *opt, const char *arg) opt_default("packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack. opt_default("muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8 - opt_default("ab", "448000"); + opt_default("b:a", "448000"); audio_sample_rate = 48000; } else if(!strncmp(arg, "dv", 2)) { @@ -4216,44 +4171,6 @@ static int opt_bsf(const char *opt, const char *arg) return 0; } -static int opt_preset(const char *opt, const char *arg) -{ - FILE *f=NULL; - char filename[1000], tmp[1000], tmp2[1000], line[1000]; - char *codec_name = *opt == 'v' ? video_codec_name : - *opt == 'a' ? audio_codec_name : - subtitle_codec_name; - - if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) { - fprintf(stderr, "File for preset '%s' not found\n", arg); - exit_program(1); - } - - while(!feof(f)){ - int e= fscanf(f, "%999[^\n]\n", line) - 1; - if(line[0] == '#' && !e) - continue; - e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2; - if(e){ - fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line); - exit_program(1); - } - if (!strcmp(tmp, "acodec") || - !strcmp(tmp, "vcodec") || - !strcmp(tmp, "scodec") || - !strcmp(tmp, "dcodec")) { - opt_codec(tmp, tmp2); - }else if(opt_default(tmp, tmp2) < 0){ - fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2); - exit_program(1); - } - } - - fclose(f); - - return 0; -} - static void log_callback_null(void* ptr, int level, const char* fmt, va_list vl) { } @@ -4274,6 +4191,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_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", "outfile[,metadata]:infile[,metadata]" }, @@ -4328,9 +4247,9 @@ static const OptionDef options[] = { { "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" }, { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" }, { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" }, - { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_codec}, "force video codec ('copy' to copy stream)", "codec" }, + { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" }, { "me_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "threshold" }, - { "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, + { "same_quant", OPT_BOOL | OPT_VIDEO, {(void*)&same_quant}, "use same quantizer as source (implies VBR)" }, { "pass", HAS_ARG | OPT_VIDEO, {(void*)opt_pass}, "select the pass number (1 or 2)", "n" }, { "passlogfile", HAS_ARG | OPT_VIDEO, {(void*)&opt_passlogfile}, "select two pass log file name prefix", "prefix" }, @@ -4359,7 +4278,7 @@ static const OptionDef options[] = { { "ar", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_rate}, "set audio sampling rate (in Hz)", "rate" }, { "ac", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_channels}, "set number of audio channels", "channels" }, { "an", OPT_BOOL | OPT_AUDIO, {(void*)&audio_disable}, "disable audio" }, - { "acodec", HAS_ARG | OPT_AUDIO, {(void*)opt_codec}, "force audio codec ('copy' to copy stream)", "codec" }, + { "acodec", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" }, { "atag", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_codec_tag}, "force audio tag/fourcc", "fourcc/tag" }, { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, // { "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" }, @@ -4367,7 +4286,7 @@ static const OptionDef options[] = { /* subtitle options */ { "sn", OPT_BOOL | OPT_SUBTITLE, {(void*)&subtitle_disable}, "disable subtitle" }, - { "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_codec}, "force subtitle codec ('copy' to copy stream)", "codec" }, + { "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" }, { "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" }, { "stag", HAS_ARG | OPT_EXPERT | OPT_SUBTITLE, {(void*)opt_codec_tag}, "force subtitle tag/fourcc", "fourcc/tag" }, @@ -4382,12 +4301,8 @@ static const OptionDef options[] = { { "vbsf", HAS_ARG | OPT_VIDEO | OPT_EXPERT, {(void*)opt_bsf}, "", "bitstream_filter" }, { "sbsf", HAS_ARG | OPT_SUBTITLE | OPT_EXPERT, {(void*)opt_bsf}, "", "bitstream_filter" }, - { "apre", HAS_ARG | OPT_AUDIO | OPT_EXPERT, {(void*)opt_preset}, "set the audio options to the indicated preset", "preset" }, - { "vpre", HAS_ARG | OPT_VIDEO | OPT_EXPERT, {(void*)opt_preset}, "set the video options to the indicated preset", "preset" }, - { "spre", HAS_ARG | OPT_SUBTITLE | OPT_EXPERT, {(void*)opt_preset}, "set the subtitle options to the indicated preset", "preset" }, - { "fpre", HAS_ARG | OPT_EXPERT, {(void*)opt_preset}, "set options from indicated preset file", "filename" }, /* data codec support */ - { "dcodec", HAS_ARG | OPT_DATA, {(void*)opt_codec}, "force data codec ('copy' to copy stream)", "codec" }, + { "dcodec", HAS_ARG | OPT_DATA, {(void*)opt_data_codec}, "force data codec ('copy' to copy stream)", "codec" }, { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" }, { NULL, }, diff --git a/doc/avconv.texi b/doc/avconv.texi index 3b7fd6b347dd1af79bd67cbdce801bb3be3e6e04..472ba1f0c3d2482fc5ec0838cc626f639ee43b58 100644 --- a/doc/avconv.texi +++ b/doc/avconv.texi @@ -97,6 +97,34 @@ input file name @item -y 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} Restrict the transcoded/captured video sequence to the duration specified in seconds. @@ -159,9 +187,6 @@ avconv -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg @item -dframes @var{number} Set the number of data frames to record. -@item -scodec @var{codec} -Force subtitle codec ('copy' to copy stream). - @item -slang @var{code} Set the ISO 639 language code (3 letters) of the current subtitle stream. @@ -282,11 +307,13 @@ It is of little use elsewise. @item -bufsize @var{size} Set video buffer verifier buffer size (in bits). @item -vcodec @var{codec} -Force video codec to @var{codec}. Use the @code{copy} special value to -tell that the raw codec data must be copied as is. -@item -sameq +Set the video codec. This is an alias for @code{-codec:v}. +@item -same_quant Use same quantizer as source (implies VBR). +Note that this is NOT SAME QUALITY. Do not use this option unless you know you +need it. + @item -pass @var{n} Select the pass number (1 or 2). It is used to do two-pass video encoding. The statistics of the video are recorded in the first @@ -296,8 +323,8 @@ at the exact requested bitrate. On pass 1, you may just deactivate audio and set output to null, examples for Windows and Unix: @example -avconv -i foo.mov -vcodec 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 NUL +avconv -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y /dev/null @end example @item -passlogfile @var{prefix} @@ -541,7 +568,7 @@ Show QP histogram. @item -vbsf @var{bitstream_filter} Bitstream filters available are "dump_extra", "remove_extra", "noise", "h264_mp4toannexb", "imxdump", "mjpegadump", "mjpeg2jpeg". @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 @item -force_key_frames @var{time}[,@var{time}...] Force key frames at the specified timestamps, more precisely at the first @@ -571,8 +598,7 @@ and is mapped to the corresponding demuxer options. @item -an Disable audio recording. @item -acodec @var{codec} -Force audio codec to @var{codec}. Use the @code{copy} special value to -specify that the raw codec data must be copied as is. +Set the audio codec. This is an alias for @code{-codec:a}. @item -alang @var{code} Set the ISO 639 language code (3 letters) of the current audio stream. @end table @@ -612,7 +638,7 @@ Bitstream filters available are "dump_extra", "remove_extra", "noise", "mp3comp" @table @option @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} Set the ISO 639 language code (3 letters) of the current subtitle stream. @item -sn @@ -620,7 +646,7 @@ Disable subtitle recording. @item -sbsf @var{bitstream_filter} Bitstream filters available are "mov2textsub", "text2movsub". @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 table @@ -677,7 +703,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"), and copy them to the output file @file{out.mov}: @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 To select all video and the third audio stream from an input file: @@ -785,40 +811,7 @@ an output mpegts file: avconv -i infile -streamid 0:33 -streamid 1:36 out.ts @end example @end table - -@section Preset files - -A preset file contains a sequence of @var{option}=@var{value} pairs, -one for each line, specifying a sequence of options which would be -awkward to specify on the command line. Lines starting with the hash -('#') character are ignored and are used to provide comments. Check -the @file{ffpresets} directory in the Libav source tree for examples. - -Preset files are specified with the @code{vpre}, @code{apre}, -@code{spre}, and @code{fpre} options. The @code{fpre} option takes the -filename of the preset instead of a preset name as input and can be -used for any kind of codec. For the @code{vpre}, @code{apre}, and -@code{spre} options, the options specified in a preset file are -applied to the currently selected codec of the same type as the preset -option. - -The argument passed to the @code{vpre}, @code{apre}, and @code{spre} -preset options identifies the preset file to use according to the -following rules: - -First avconv searches for a file named @var{arg}.ffpreset in the -directories @file{$av_DATADIR} (if set), and @file{$HOME/.avconv}, and in -the datadir defined at configuration time (usually @file{PREFIX/share/avconv}) -in that order. For example, if the argument is @code{libx264-max}, it will -search for the file @file{libx264-max.ffpreset}. - -If no such file is found, then avconv will search for a file named -@var{codec_name}-@var{arg}.ffpreset in the above-mentioned -directories, where @var{codec_name} is the name of the codec to which -the preset file options will be applied. For example, if you select -the video codec with @code{-vcodec libx264} and use @code{-vpre max}, -then it will search for the file @file{libx264-max.ffpreset}. -@c man end +@c man end OPTIONS @chapter Tips @c man begin TIPS @@ -858,11 +851,6 @@ To have a constant quality (but a variable bitrate), use the option '-qscale n' when 'n' is between 1 (excellent quality) and 31 (worst quality). -@item -When converting video files, you can use the '-sameq' option which -uses the same quality factor in the encoder as in the decoder. -It allows almost lossless encoding. - @end itemize @c man end TIPS @@ -968,7 +956,7 @@ You can encode to several formats at the same time and define a mapping from input stream to output streams: @example -avconv -i /tmp/a.wav -map 0:a -ab 64k /tmp/a.mp2 -map 0:a -ab 128k /tmp/b.mp2 +avconv -i /tmp/a.wav -map 0:a -b 64k /tmp/a.mp2 -map 0:a -b 128k /tmp/b.mp2 @end example Converts a.wav to a.mp2 at 64 kbits and to b.mp2 at 128 kbits. '-map @@ -979,7 +967,7 @@ stream, in the order of the definition of output streams. You can transcode decrypted VOBs: @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:v 800k -g 300 -bf 2 -c:a libmp3lame -b:a 128k snatch.avi @end example This is a typical DVD ripping example; the input is a VOB file, the @@ -1023,7 +1011,7 @@ only formats accepting a normal integer are suitable. You can put many streams of the same type in the output: @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 The resulting output file @file{test12.avi} will contain first four streams from diff --git a/ffmpeg.c b/ffmpeg.c index ad592881f542a1b5279526d4a5fc77637677dbcc..e895b787aa55bacec3e8cecb6493d01af9a50e87 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -4451,8 +4451,8 @@ static const OptionDef options[] = { { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" }, { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_codec}, "force video codec ('copy' to copy stream)", "codec" }, { "me_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "threshold" }, - { "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, - "use same quantizer as source (implies VBR)" }, + { "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, "use same quantizer as source (implies VBR)" }, + { "same_quant", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, "use same quantizer as source (implies VBR)" }, { "pass", HAS_ARG | OPT_VIDEO, {(void*)opt_pass}, "select the pass number (1 or 2)", "n" }, { "passlogfile", HAS_ARG | OPT_VIDEO, {(void*)&opt_passlogfile}, "select two pass log file name prefix", "prefix" }, { "deinterlace", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_deinterlace}, diff --git a/libavcodec/options.c b/libavcodec/options.c index 78c2f726a2c73546dd9dcd7f2b21d9224dc65c8e..cb2cd7decba7186a5f3fe2dc424183e0d5d210ce 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -70,7 +70,7 @@ static const AVOption *opt_find(void *obj, const char *name, const char *unit, i #define AV_CODEC_DEFAULT_BITRATE 200*1000 static const AVOption options[]={ -{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, V|E}, +{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, A|V|E}, {"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, {.dbl = 64*1000 }, INT_MIN, INT_MAX, A|E}, {"bt", "set video bitrate tolerance (in bits/s)", OFFSET(bit_rate_tolerance), FF_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, {"flags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, UINT_MAX, V|A|E|D, "flags"}, diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 54c1231511aa16308ed508000679551ba221d638..82aaedc74b7f161fc48eebf4a5be5aecafb53a4e 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -927,7 +927,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) h->b_stride = 4*s->mb_width; - ff_h264_alloc_tables(h); + if (ff_h264_alloc_tables(h) < 0) { + av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n"); + return AVERROR(ENOMEM); + } } return 0; diff --git a/libavformat/movenc.c b/libavformat/movenc.c index bf429c0f48a5490cbc76d3e938f0a4f133146a02..5d676f77410f86c12d4675c365d7bc397b98a2f0 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -720,7 +720,7 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) if (!tag) { // if no mac fcc found, try with Microsoft tags tag = ff_codec_get_tag(ff_codec_bmp_tags, track->enc->codec_id); if (tag) - av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, " + av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, " "the file may be unplayable!\n"); } } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -729,7 +729,7 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id); if (ms_tag) { tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff)); - av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, " + av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, " "the file may be unplayable!\n"); } } diff --git a/tests/codec-regression.sh b/tests/codec-regression.sh index 36461597f584366f79c46b16e0cfe9c640098437..f7c9d43ee82d1abc4b0f599536c091094c1f2394 100755 --- a/tests/codec-regression.sh +++ b/tests/codec-regression.sh @@ -16,7 +16,7 @@ if [ -n "$do_vref" ]; then do_avconv $raw_ref -f image2 -vcodec pgmyuv -i $raw_src -an -f rawvideo fi if [ -n "$do_aref" ]; then -do_avconv $pcm_ref -ab 128k -ac 2 -ar 44100 -f s16le -i $pcm_src -f wav +do_avconv $pcm_ref -b 128k -ac 2 -ar 44100 -f s16le -i $pcm_src -f wav fi if [ -n "$do_mpeg" ] ; then @@ -58,7 +58,7 @@ do_video_decoding # mpeg2 encoding interlaced file=${outfile}mpeg2reuse.mpg -do_avconv $file $DEC_OPTS -me_threshold 256 -i ${target_path}/${outfile}mpeg2thread.mpg $ENC_OPTS -sameq -me_threshold 256 -mb_threshold 1024 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -threads 4 +do_avconv $file $DEC_OPTS -me_threshold 256 -i ${target_path}/${outfile}mpeg2thread.mpg $ENC_OPTS -same_quant -me_threshold 256 -mb_threshold 1024 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -threads 4 do_video_decoding fi @@ -294,7 +294,7 @@ do_audio_encoding ac3.rm "-vn -acodec ac3_fixed" fi if [ -n "$do_g726" ] ; then -do_audio_encoding g726.wav "-ab 32k -ac 1 -ar 8000 -acodec g726" +do_audio_encoding g726.wav "-b 32k -ac 1 -ar 8000 -acodec g726" do_audio_decoding fi diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index 0c6a6ba547fffb0fe9fa038331919fee56b51c98..bb34a2c2d79d3b5570c55ec6ca90ef97d496633b 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -14,7 +14,7 @@ eval do_$test=y do_lavf() { file=${outfile}lavf.$1 - do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -ab 64k -t 1 -qscale 10 $2 + do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -b:a 64k -t 1 -qscale 10 $2 do_avconv_crc $file $DEC_OPTS -i $target_path/$file $3 } @@ -53,7 +53,7 @@ fi if [ -n "$do_rm" ] ; then file=${outfile}lavf.rm -do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 -acodec ac3_fixed -ab 64k +do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 -acodec ac3_fixed -b:a 64k # broken #do_avconv_crc $file -i $target_path/$file fi