[libav-commits] avconv: extend -r to work on any input stream.

Anton Khirnov git at libav.org
Tue May 29 19:22:13 CEST 2012


Module: libav
Branch: master
Commit: c9cc76290f8139a012a12efe7e581276b8bd8dff

Author:    Anton Khirnov <anton at khirnov.net>
Committer: Anton Khirnov <anton at khirnov.net>
Date:      Sat May 26 16:52:58 2012 +0200

avconv: extend -r to work on any input stream.

This is done by automatically inserting a setpts filter.

---

 avconv.c        |   46 ++++++++++++++++++++++++++++++++++++++++++----
 configure       |    3 ++-
 doc/avconv.texi |   11 +++++++++--
 3 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/avconv.c b/avconv.c
index e13b2aa..cbf66c4 100644
--- a/avconv.c
+++ b/avconv.c
@@ -203,6 +203,7 @@ typedef struct InputStream {
     int is_start;            /* is 1 at the start and after a discontinuity */
     int showed_multi_packet_warning;
     AVDictionary *opts;
+    AVRational framerate;               /* framerate forced with -r */
 
     int resample_height;
     int resample_width;
@@ -931,10 +932,15 @@ static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFil
 static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
                                         AVFilterInOut *in)
 {
+    AVFilterContext *first_filter = in->filter_ctx;
     AVFilter *filter = avfilter_get_by_name("buffer");
     InputStream *ist = ifilter->ist;
+    AVRational tb = ist->framerate.num ? (AVRational){ist->framerate.den,
+                                                      ist->framerate.num} :
+                                         ist->st->time_base;
     AVRational sar;
     char args[255];
+    int pad_idx = in->pad_idx;
     int ret;
 
     sar = ist->st->sample_aspect_ratio.num ?
@@ -942,13 +948,29 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
           ist->st->codec->sample_aspect_ratio;
     snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
              ist->st->codec->height, ist->st->codec->pix_fmt,
-             ist->st->time_base.num, ist->st->time_base.den,
-             sar.num, sar.den);
+             tb.num, tb.den, sar.num, sar.den);
 
     if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, in->name,
                                             args, NULL, fg->graph)) < 0)
         return ret;
-    if ((ret = avfilter_link(ifilter->filter, 0, in->filter_ctx, in->pad_idx)) < 0)
+
+    if (ist->framerate.num) {
+        AVFilterContext *setpts;
+
+        if ((ret = avfilter_graph_create_filter(&setpts,
+                                                avfilter_get_by_name("setpts"),
+                                                "setpts", "N", NULL,
+                                                fg->graph)) < 0)
+            return ret;
+
+        if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0)
+            return ret;
+
+        first_filter = setpts;
+        pad_idx = 0;
+    }
+
+    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
         return ret;
     return 0;
 }
@@ -3358,6 +3380,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
         AVStream *st = ic->streams[i];
         AVCodecContext *dec = st->codec;
         InputStream *ist = av_mallocz(sizeof(*ist));
+        char *framerate = NULL;
 
         if (!ist)
             exit_program(1);
@@ -3382,6 +3405,14 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
             ist->resample_width   = dec->width;
             ist->resample_pix_fmt = dec->pix_fmt;
 
+            MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
+            if (framerate && av_parse_video_rate(&ist->framerate,
+                                                 framerate) < 0) {
+                av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
+                       framerate);
+                exit_program(1);
+            }
+
             break;
         case AVMEDIA_TYPE_AUDIO:
             guess_input_channel_layout(ist);
@@ -3503,7 +3534,14 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
         }
     }
     if (o->nb_frame_rates) {
-        av_dict_set(&format_opts, "framerate", o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
+        /* set the format-level framerate option;
+         * this is important for video grabbers, e.g. x11 */
+        if (file_iformat && file_iformat->priv_class &&
+            av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
+                        AV_OPT_SEARCH_FAKE_OBJ)) {
+            av_dict_set(&format_opts, "framerate",
+                        o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
+        }
     }
     if (o->nb_frame_sizes) {
         av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
diff --git a/configure b/configure
index c3edc93..67371c8 100755
--- a/configure
+++ b/configure
@@ -1536,7 +1536,8 @@ avfilter_deps="swscale"
 avformat_deps="avcodec"
 
 # programs
-avconv_deps="avcodec avfilter avformat avresample swscale format_filter"
+avconv_deps="avcodec avfilter avformat avresample swscale format_filter
+             setpts_filter"
 avplay_deps="avcodec avformat swscale sdl"
 avplay_select="rdft"
 avprobe_deps="avcodec avformat"
diff --git a/doc/avconv.texi b/doc/avconv.texi
index 693c45e..2ebfe9f 100644
--- a/doc/avconv.texi
+++ b/doc/avconv.texi
@@ -257,8 +257,15 @@ attachments.
 @item -vframes @var{number} (@emph{output})
 Set the number of video frames to record. This is an alias for @code{-frames:v}.
 @item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream})
-Set frame rate (Hz value, fraction or abbreviation), (default = 25). For output
-streams implies @code{-vsync cfr}.
+Set frame rate (Hz value, fraction or abbreviation).
+
+As an input option, ignore any timestamps stored in the file and instead
+generate timestamps assuming constant frame rate @var{fps}.
+
+As an output option, duplicate or drop input frames to achieve constant output
+frame rate @var{fps} (note that this actually causes the @code{fps} filter to be
+inserted to the end of the corresponding filtergraph).
+
 @item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
 Set frame size.
 



More information about the libav-commits mailing list