Commit c9cc7629 authored by Anton Khirnov's avatar Anton Khirnov

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

This is done by automatically inserting a setpts filter.
parent 4f81a507
...@@ -203,6 +203,7 @@ typedef struct InputStream { ...@@ -203,6 +203,7 @@ typedef struct InputStream {
int is_start; /* is 1 at the start and after a discontinuity */ int is_start; /* is 1 at the start and after a discontinuity */
int showed_multi_packet_warning; int showed_multi_packet_warning;
AVDictionary *opts; AVDictionary *opts;
AVRational framerate; /* framerate forced with -r */
int resample_height; int resample_height;
int resample_width; int resample_width;
...@@ -931,10 +932,15 @@ static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFil ...@@ -931,10 +932,15 @@ static int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFil
static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
AVFilterInOut *in) AVFilterInOut *in)
{ {
AVFilterContext *first_filter = in->filter_ctx;
AVFilter *filter = avfilter_get_by_name("buffer"); AVFilter *filter = avfilter_get_by_name("buffer");
InputStream *ist = ifilter->ist; InputStream *ist = ifilter->ist;
AVRational tb = ist->framerate.num ? (AVRational){ist->framerate.den,
ist->framerate.num} :
ist->st->time_base;
AVRational sar; AVRational sar;
char args[255]; char args[255];
int pad_idx = in->pad_idx;
int ret; int ret;
sar = ist->st->sample_aspect_ratio.num ? sar = ist->st->sample_aspect_ratio.num ?
...@@ -942,13 +948,29 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, ...@@ -942,13 +948,29 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
ist->st->codec->sample_aspect_ratio; ist->st->codec->sample_aspect_ratio;
snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width, 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->codec->height, ist->st->codec->pix_fmt,
ist->st->time_base.num, ist->st->time_base.den, tb.num, tb.den, sar.num, sar.den);
sar.num, sar.den);
if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, in->name, if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter, in->name,
args, NULL, fg->graph)) < 0) args, NULL, fg->graph)) < 0)
return ret; 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 ret;
return 0; return 0;
} }
...@@ -3358,6 +3380,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) ...@@ -3358,6 +3380,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
AVStream *st = ic->streams[i]; AVStream *st = ic->streams[i];
AVCodecContext *dec = st->codec; AVCodecContext *dec = st->codec;
InputStream *ist = av_mallocz(sizeof(*ist)); InputStream *ist = av_mallocz(sizeof(*ist));
char *framerate = NULL;
if (!ist) if (!ist)
exit_program(1); exit_program(1);
...@@ -3382,6 +3405,14 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) ...@@ -3382,6 +3405,14 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
ist->resample_width = dec->width; ist->resample_width = dec->width;
ist->resample_pix_fmt = dec->pix_fmt; 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; break;
case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_AUDIO:
guess_input_channel_layout(ist); guess_input_channel_layout(ist);
...@@ -3503,7 +3534,14 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena ...@@ -3503,7 +3534,14 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
} }
} }
if (o->nb_frame_rates) { 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) { if (o->nb_frame_sizes) {
av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0); av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
......
...@@ -1536,7 +1536,8 @@ avfilter_deps="swscale" ...@@ -1536,7 +1536,8 @@ avfilter_deps="swscale"
avformat_deps="avcodec" avformat_deps="avcodec"
# programs # 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_deps="avcodec avformat swscale sdl"
avplay_select="rdft" avplay_select="rdft"
avprobe_deps="avcodec avformat" avprobe_deps="avcodec avformat"
......
...@@ -257,8 +257,15 @@ attachments. ...@@ -257,8 +257,15 @@ attachments.
@item -vframes @var{number} (@emph{output}) @item -vframes @var{number} (@emph{output})
Set the number of video frames to record. This is an alias for @code{-frames:v}. 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}) @item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream})
Set frame rate (Hz value, fraction or abbreviation), (default = 25). For output Set frame rate (Hz value, fraction or abbreviation).
streams implies @code{-vsync cfr}.
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}) @item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
Set frame size. Set frame size.
......
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