diff --git a/avconv.c b/avconv.c index 096623e7dc..16f22f4039 100644 --- a/avconv.c +++ b/avconv.c @@ -76,6 +76,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; @@ -111,7 +116,7 @@ static int do_hex_dump = 0; static int do_pkt_dump = 0; static int do_pass = 0; static char *pass_logfilename_prefix = NULL; -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; @@ -1330,16 +1335,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) @@ -4309,6 +4314,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 */ @@ -4339,7 +4355,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" }, diff --git a/doc/avconv.texi b/doc/avconv.texi index 157e233cc6..0a83326379 100644 --- a/doc/avconv.texi +++ b/doc/avconv.texi @@ -746,15 +746,15 @@ Thread count. Video sync method. @table @option -@item 0 +@item passthrough Each frame is passed with its timestamp from the demuxer to the muxer. -@item 1 +@item cfr Frames will be duplicated and dropped to achieve exactly the requested constant framerate. -@item 2 +@item vfr Frames are passed through with their timestamp or dropped so as to prevent 2 frames from having the same timestamp. -@item -1 +@item auto Chooses between 1 and 2 depending on muxer capabilities. This is the default method. @end table