diff options
author | Anton Khirnov <anton@khirnov.net> | 2013-04-10 15:02:01 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2013-04-30 11:53:12 +0200 |
commit | a83c0da539fb07260310bc3b34056239d2b138b2 (patch) | |
tree | 39b62e964b8486cb16731f1e255a94371e851873 /avconv_filter.c | |
parent | 3d624420086ed3cd0c74f4510f0285968e21c117 (diff) | |
download | ffmpeg-a83c0da539fb07260310bc3b34056239d2b138b2.tar.gz |
avconv: make -t insert trim/atrim filters.
This makes -t sample-accurate for audio and will allow further
simplication in the future.
Most of the FATE changes are due to audio now being sample accurate. In
some cases a video frame was incorrectly passed with the old code, while
its was over the limit.
Diffstat (limited to 'avconv_filter.c')
-rw-r--r-- | avconv_filter.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/avconv_filter.c b/avconv_filter.c index 7edcbf6e23..0a47c95191 100644 --- a/avconv_filter.c +++ b/avconv_filter.c @@ -173,6 +173,52 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1]; } +static int insert_trim(OutputStream *ost, AVFilterContext **last_filter, int *pad_idx) +{ + OutputFile *of = output_files[ost->file_index]; + AVFilterGraph *graph = (*last_filter)->graph; + AVFilterContext *ctx; + const AVFilter *trim; + const char *name = ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO ? "trim" : "atrim"; + char filter_name[128]; + int ret = 0; + + if (of->recording_time == INT64_MAX) + return 0; + + trim = avfilter_get_by_name(name); + if (!trim) { + av_log(NULL, AV_LOG_ERROR, "%s filter not present, cannot limit " + "recording time.\n", name); + return AVERROR_FILTER_NOT_FOUND; + } + + snprintf(filter_name, sizeof(filter_name), "%s for output stream %d:%d", + name, ost->file_index, ost->index); + ctx = avfilter_graph_alloc_filter(graph, trim, filter_name); + if (!ctx) + return AVERROR(ENOMEM); + + ret = av_opt_set_double(ctx, "duration", (double)of->recording_time / 1e6, + AV_OPT_SEARCH_CHILDREN); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name); + return ret; + } + + ret = avfilter_init_str(ctx, NULL); + if (ret < 0) + return ret; + + ret = avfilter_link(*last_filter, *pad_idx, ctx, 0); + if (ret < 0) + return ret; + + *last_filter = ctx; + *pad_idx = 0; + return 0; +} + static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out) { char *pix_fmts; @@ -247,6 +293,11 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, pad_idx = 0; } + ret = insert_trim(ost, &last_filter, &pad_idx); + if (ret < 0) + return ret; + + if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0) return ret; @@ -313,6 +364,10 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, pad_idx = 0; } + ret = insert_trim(ost, &last_filter, &pad_idx); + if (ret < 0) + return ret; + if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0) return ret; |