X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=avconv.c;h=0c6ef6d82df9000b9ed6e31ff7c538a238fdedf2;hb=73da4fd520379adafe858b4e182a3eac0f49080c;hp=a8f3d7033954fedb8ba16966f2751805fd81d87b;hpb=dde545c6970bca308b0b3f91dbb378d46f6808a4;p=ffmpeg diff --git a/avconv.c b/avconv.c index a8f3d703395..0c6ef6d82df 100644 --- a/avconv.c +++ b/avconv.c @@ -88,6 +88,11 @@ #include "libavutil/avassert.h" +#define VSYNC_AUTO -1 +#define VSYNC_PASSTHROUGH 0 +#define VSYNC_CFR 1 +#define VSYNC_VFR 2 + const char program_name[] = "avconv"; const int program_birth_year = 2000; @@ -127,7 +132,7 @@ static int do_hex_dump = 0; static int do_pkt_dump = 0; static int do_pass = 0; static const char *pass_logfilename_prefix; -static int video_sync_method = -1; +static int video_sync_method = VSYNC_AUTO; static int audio_sync_method = 0; static float audio_drift_threshold = 0.1; static int copy_ts = 0; @@ -633,7 +638,6 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost) if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, &inputs, &outputs, NULL)) < 0) return ret; - av_freep(&ost->avfilter); } else { if ((ret = avfilter_link(last_filter, 0, ost->output_video_filter, 0)) < 0) return ret; @@ -762,6 +766,10 @@ void exit_program(int ret) bsfc = next; } output_streams[i].bitstream_filters = NULL; + +#if CONFIG_AVFILTER + av_freep(&output_streams[i].avfilter); +#endif } for (i = 0; i < nb_input_files; i++) { avformat_close_input(&input_files[i].ctx); @@ -1297,6 +1305,7 @@ static void do_subtitle_out(AVFormatContext *s, static int bit_buffer_size = 1024 * 256; static uint8_t *bit_buffer = NULL; +#if !CONFIG_AVFILTER static void do_video_resample(OutputStream *ost, InputStream *ist, AVFrame *in_picture, @@ -1307,26 +1316,27 @@ static void do_video_resample(OutputStream *ost, AVCodecContext *enc = ost->st->codec; *out_picture = in_picture; - resample_changed = ost->resample_width != dec->width || - ost->resample_height != dec->height || - ost->resample_pix_fmt != dec->pix_fmt; + resample_changed = ost->resample_width != in_picture->width || + ost->resample_height != in_picture->height || + ost->resample_pix_fmt != in_picture->format; -#if !CONFIG_AVFILTER if (resample_changed) { av_log(NULL, AV_LOG_INFO, - "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", + "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s / frm size:%dx%d fmt:%s\n", ist->file_index, ist->st->index, ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt), - dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt)); - ost->resample_width = dec->width; - ost->resample_height = dec->height; - ost->resample_pix_fmt = dec->pix_fmt; + dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt), + in_picture->width, in_picture->height, av_get_pix_fmt_name(in_picture->format)); + ost->resample_width = in_picture->width; + ost->resample_height = in_picture->height; + ost->resample_pix_fmt = in_picture->format; } ost->video_resample = dec->width != enc->width || dec->height != enc->height || dec->pix_fmt != enc->pix_fmt; + if (ost->video_resample) { *out_picture = &ost->resample_frame; if (!ost->img_resample_ctx || resample_changed) { @@ -1352,21 +1362,13 @@ static void do_video_resample(OutputStream *ost, sws_scale(ost->img_resample_ctx, in_picture->data, in_picture->linesize, 0, ost->resample_height, (*out_picture)->data, (*out_picture)->linesize); } -#else if (resample_changed) { - avfilter_graph_free(&ost->graph); - if (configure_video_filters(ist, ost)) { - av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); - exit_program(1); - } - } -#endif - if (resample_changed) { - ost->resample_width = dec->width; - ost->resample_height = dec->height; - ost->resample_pix_fmt = dec->pix_fmt; + ost->resample_width = in_picture->width; + ost->resample_height = in_picture->height; + ost->resample_pix_fmt = in_picture->format; } } +#endif static void do_video_out(AVFormatContext *s, @@ -1390,16 +1392,16 @@ static void do_video_out(AVFormatContext *s, *frame_size = 0; format_video_sync = video_sync_method; - if (format_video_sync < 0) - format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 : - (s->oformat->flags & AVFMT_VARIABLE_FPS) ? 2 : 1; + if (format_video_sync == VSYNC_AUTO) + format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : + (s->oformat->flags & AVFMT_VARIABLE_FPS) ? VSYNC_VFR : VSYNC_CFR; - if (format_video_sync) { + if (format_video_sync != VSYNC_PASSTHROUGH) { double vdelta = sync_ipts - ost->sync_opts; // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c if (vdelta < -1.1) nb_frames = 0; - else if (format_video_sync == 2) { + else if (format_video_sync == VSYNC_VFR) { if (vdelta <= -0.6) { nb_frames = 0; } else if (vdelta > 0.6) @@ -1421,7 +1423,11 @@ static void do_video_out(AVFormatContext *s, if (nb_frames <= 0) return; +#if !CONFIG_AVFILTER do_video_resample(ost, ist, in_picture, &final_picture); +#else + final_picture = in_picture; +#endif /* duplicates frame if needed */ for (i = 0; i < nb_frames; i++) { @@ -2007,12 +2013,33 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = &output_streams[i]; - int frame_size; + int frame_size, resample_changed; if (!check_output_constraints(ist, ost) || !ost->encoding_needed) continue; #if CONFIG_AVFILTER + resample_changed = ost->resample_width != decoded_frame->width || + ost->resample_height != decoded_frame->height || + ost->resample_pix_fmt != decoded_frame->format; + if (resample_changed) { + av_log(NULL, AV_LOG_INFO, + "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", + ist->file_index, ist->st->index, + ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt), + decoded_frame->width, decoded_frame->height, av_get_pix_fmt_name(decoded_frame->format)); + + avfilter_graph_free(&ost->graph); + if (configure_video_filters(ist, ost)) { + av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); + exit_program(1); + } + + ost->resample_width = decoded_frame->width; + ost->resample_height = decoded_frame->height; + ost->resample_pix_fmt = decoded_frame->format; + } + if (!decoded_frame->sample_aspect_ratio.num) decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio; decoded_frame->pts = ist->pts; @@ -3731,13 +3758,13 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) ost->top_field_first = -1; MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st); - MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st); - #if CONFIG_AVFILTER MATCH_PER_STREAM_OPT(filters, str, filters, oc, st); if (filters) ost->avfilter = av_strdup(filters); #endif + } else { + MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st); } return ost; @@ -4182,9 +4209,9 @@ static int opt_audio_qscale(OptionsContext *o, const char *opt, const char *arg) static void show_usage(void) { - printf("Hyper fast Audio and Video encoder\n"); - printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name); - printf("\n"); + av_log(NULL, AV_LOG_INFO, "Hyper fast Audio and Video encoder\n"); + av_log(NULL, AV_LOG_INFO, "usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name); + av_log(NULL, AV_LOG_INFO, "\n"); } static int opt_help(const char *opt, const char *arg) @@ -4426,6 +4453,17 @@ static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg return parse_option(o, "filter:v", arg, options); } +static int opt_vsync(const char *opt, const char *arg) +{ + if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR; + else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR; + else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH; + + if (video_sync_method == VSYNC_AUTO) + video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR); + return 0; +} + #define OFFSET(x) offsetof(OptionsContext, x) static const OptionDef options[] = { /* main options */ @@ -4457,7 +4495,7 @@ static const OptionDef options[] = { "when dumping packets, also dump the payload" }, { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(rate_emu)}, "read input at native frame rate", "" }, { "target", HAS_ARG | OPT_FUNC2, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, - { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" }, + { "vsync", HAS_ARG | OPT_EXPERT, {(void*)opt_vsync}, "video sync method", "" }, { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" }, { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" },