diff options
author | John Stebbins <[email protected]> | 2015-10-24 14:06:56 -0700 |
---|---|---|
committer | John Stebbins <[email protected]> | 2016-01-21 12:38:42 -0700 |
commit | 10ea76c71197b302b10088d93680a4bed4bc6b8e (patch) | |
tree | 459b46b16256c39ed34fe1f0a4b9476ec3439871 /contrib/ffmpeg | |
parent | ef956e695879c716dc22c96f7f8fa24e3fa5d08c (diff) |
libhb: Add libavfilter support and pad filter
New filter types HB_FILTER_AVFILTER and HB_FILTER_PAD.
Settings for HB_FILTER_AVFILTER are the same as you would pass to avconv
from the command line -vf option, except that we do not support
multi-input or multi-output filters.
Settings for HB_FILTER_PAD are "width:height:color:x_offset:y_offset".
width x height is the size of the output frame after padding.
color may be a w3c color name or RGB value (default black).
x_offset, y_offset is the position of the video within the padded area
(default centered).
Any of the values may be omitted or "auto".
Diffstat (limited to 'contrib/ffmpeg')
-rw-r--r-- | contrib/ffmpeg/A10-vf-pad.patch | 34 | ||||
-rw-r--r-- | contrib/ffmpeg/A11-avfilter-framerate.patch | 352 | ||||
-rw-r--r-- | contrib/ffmpeg/module.defs | 1 |
3 files changed, 386 insertions, 1 deletions
diff --git a/contrib/ffmpeg/A10-vf-pad.patch b/contrib/ffmpeg/A10-vf-pad.patch new file mode 100644 index 000000000..85115838f --- /dev/null +++ b/contrib/ffmpeg/A10-vf-pad.patch @@ -0,0 +1,34 @@ +diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c +index 634af4c..cddd2a6 100644 +--- a/libavfilter/vf_pad.c ++++ b/libavfilter/vf_pad.c +@@ -167,12 +167,17 @@ static int config_input(AVFilterLink *inlink) + NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) + goto eval_fail; + s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res; ++ if (!s->h) ++ var_values[VAR_OUT_H] = var_values[VAR_OH] = s->h = inlink->h; ++ + /* evaluate the width again, as it may depend on the evaluated output height */ + if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr), + var_names, var_values, + NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) + goto eval_fail; + s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res; ++ if (!s->w) ++ var_values[VAR_OUT_W] = var_values[VAR_OW] = s->w = inlink->w; + + /* evaluate x and y */ + av_expr_parse_and_eval(&res, (expr = s->x_expr), +@@ -197,11 +202,6 @@ static int config_input(AVFilterLink *inlink) + return AVERROR(EINVAL); + } + +- if (!s->w) +- s->w = inlink->w; +- if (!s->h) +- s->h = inlink->h; +- + s->w &= ~((1 << s->hsub) - 1); + s->h &= ~((1 << s->vsub) - 1); + s->x &= ~((1 << s->hsub) - 1); diff --git a/contrib/ffmpeg/A11-avfilter-framerate.patch b/contrib/ffmpeg/A11-avfilter-framerate.patch new file mode 100644 index 000000000..146e4fc3c --- /dev/null +++ b/contrib/ffmpeg/A11-avfilter-framerate.patch @@ -0,0 +1,352 @@ +diff --git a/doc/filters.texi b/doc/filters.texi +index d9874b6..9804c0e 100644 +--- a/doc/filters.texi ++++ b/doc/filters.texi +@@ -209,6 +209,9 @@ The expression is evaluated through the eval API and can contain the following + constants: + + @table @option ++@item FRAME_RATE ++frame rate, only defined for constant frame-rate video ++ + @item PTS + the presentation timestamp in input + +diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c +index 64b2645..cd98d16 100644 +--- a/libavfilter/avfilter.c ++++ b/libavfilter/avfilter.c +@@ -195,6 +195,8 @@ int avfilter_config_links(AVFilterContext *filter) + link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1}; + + if (link->src->nb_inputs) { ++ if (!link->frame_rate.num && !link->frame_rate.den) ++ link->frame_rate = link->src->inputs[0]->frame_rate; + if (!link->w) + link->w = link->src->inputs[0]->w; + if (!link->h) +diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h +index 9dbfeea..0b670e0 100644 +--- a/libavfilter/avfilter.h ++++ b/libavfilter/avfilter.h +@@ -375,6 +375,18 @@ struct AVFilterLink { + AVLINK_STARTINIT, ///< started, but incomplete + AVLINK_INIT ///< complete + } init_state; ++ ++ /** ++ * Frame rate of the stream on the link, or 1/0 if unknown; ++ * if left to 0/0, will be automatically be copied from the first input ++ * of the source filter if it exists. ++ * ++ * Sources should set it to the best estimation of the real frame rate. ++ * Filters should update it if necessary depending on their function. ++ * Sinks can use it to set a default output frame rate. ++ * It is similar to the r_frae_rate field in AVStream. ++ */ ++ AVRational frame_rate; + }; + + /** +diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c +index a9b893c..ac14d54 100644 +--- a/libavfilter/buffersrc.c ++++ b/libavfilter/buffersrc.c +@@ -44,6 +44,7 @@ typedef struct BufferSourceContext { + const AVClass *class; + AVFifoBuffer *fifo; + AVRational time_base; ///< time_base to set in the output link ++ AVRational frame_rate; ///< frame_rate to set in the output link + + /* video only */ + int h, w; +@@ -191,6 +192,7 @@ static const AVOption video_options[] = { + #endif + { "sar", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V }, + { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V }, ++ { "frame_rate", NULL, OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, V }, + { NULL }, + }; + +@@ -308,6 +310,7 @@ static int config_props(AVFilterLink *link) + } + + link->time_base = c->time_base; ++ link->frame_rate = c->frame_rate; + return 0; + } + +diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c +index 98bafc2..ab3674a 100644 +--- a/libavfilter/setpts.c ++++ b/libavfilter/setpts.c +@@ -41,6 +41,7 @@ + + static const char *const var_names[] = { + "E", ///< Euler number ++ "FRAME_RATE", ///< defined only for constant frame-rate video + "INTERLACED", ///< tell if the current frame is interlaced + "N", ///< frame / sample number (starting at zero) + "PHI", ///< golden ratio +@@ -59,6 +60,7 @@ static const char *const var_names[] = { + + enum var_name { + VAR_E, ++ VAR_FRAME_RATE, + VAR_INTERLACED, + VAR_N, + VAR_PHI, +@@ -115,6 +117,10 @@ static int config_input(AVFilterLink *inlink) + setpts->var_values[VAR_SR] = inlink->sample_rate; + } + ++ setpts->var_values[VAR_FRAME_RATE] = inlink->frame_rate.num && ++ inlink->frame_rate.den ? ++ av_q2d(inlink->frame_rate) : NAN; ++ + av_log(inlink->src, AV_LOG_VERBOSE, "TB:%f\n", setpts->var_values[VAR_TB]); + return 0; + } +diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c +index ea22d37..e20f5a0 100644 +--- a/libavfilter/vf_fps.c ++++ b/libavfilter/vf_fps.c +@@ -117,6 +117,7 @@ static int config_props(AVFilterLink* link) + FPSContext *s = link->src->priv; + + link->time_base = (AVRational){ s->framerate.den, s->framerate.num }; ++ link->frame_rate= s->framerate; + link->w = link->src->inputs[0]->w; + link->h = link->src->inputs[0]->h; + +diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c +index e9806ba..10c4add 100644 +--- a/libavfilter/vf_framepack.c ++++ b/libavfilter/vf_framepack.c +@@ -82,6 +82,7 @@ static int config_output(AVFilterLink *outlink) + int width = ctx->inputs[LEFT]->w; + int height = ctx->inputs[LEFT]->h; + AVRational time_base = ctx->inputs[LEFT]->time_base; ++ AVRational frame_rate = ctx->inputs[LEFT]->frame_rate; + + // check size and fps match on the other input + if (width != ctx->inputs[RIGHT]->w || +@@ -93,11 +94,18 @@ static int config_output(AVFilterLink *outlink) + return AVERROR_INVALIDDATA; + } else if (av_cmp_q(time_base, ctx->inputs[RIGHT]->time_base) != 0) { + av_log(ctx, AV_LOG_ERROR, +- "Left and right framerates differ (%d/%d vs %d/%d).\n", ++ "Left and right time bases differ (%d/%d vs %d/%d).\n", + time_base.num, time_base.den, + ctx->inputs[RIGHT]->time_base.num, + ctx->inputs[RIGHT]->time_base.den); + return AVERROR_INVALIDDATA; ++ } else if (av_cmp_q(frame_rate, ctx->inputs[RIGHT]->frame_rate) != 0) { ++ av_log(ctx, AV_LOG_ERROR, ++ "Left and right framerates differ (%d/%d vs %d/%d).\n", ++ frame_rate.num, frame_rate.den, ++ ctx->inputs[RIGHT]->frame_rate.num, ++ ctx->inputs[RIGHT]->frame_rate.den); ++ return AVERROR_INVALIDDATA; + } + + s->pix_desc = av_pix_fmt_desc_get(outlink->format); +@@ -108,6 +116,8 @@ static int config_output(AVFilterLink *outlink) + switch (s->format) { + case AV_STEREO3D_FRAMESEQUENCE: + time_base.den *= 2; ++ frame_rate.num *= 2; ++ + s->double_pts = AV_NOPTS_VALUE; + break; + case AV_STEREO3D_COLUMNS: +@@ -126,6 +136,7 @@ static int config_output(AVFilterLink *outlink) + outlink->w = width; + outlink->h = height; + outlink->time_base = time_base; ++ outlink->frame_rate= frame_rate; + + return 0; + } +diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c +index 0122b8d..04f74bc 100644 +--- a/libavfilter/vf_frei0r.c ++++ b/libavfilter/vf_frei0r.c +@@ -459,6 +459,7 @@ static int source_config_props(AVFilterLink *outlink) + outlink->w = s->w; + outlink->h = s->h; + outlink->time_base = s->time_base; ++ outlink->frame_rate = av_inv_q(s->time_base); + + if (s->destruct && s->instance) + s->destruct(s->instance); +diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c +index 8ef58e4..939fabc 100644 +--- a/libavfilter/vf_interlace.c ++++ b/libavfilter/vf_interlace.c +@@ -109,8 +109,10 @@ static int config_out_props(AVFilterLink *outlink) + outlink->w = inlink->w; + outlink->h = inlink->h; + outlink->time_base = inlink->time_base; ++ outlink->frame_rate = inlink->frame_rate; + // half framerate + outlink->time_base.num *= 2; ++ outlink->frame_rate.den *= 2; + + + if (s->lowpass) { +diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c +index ede1765..9b60408 100644 +--- a/libavfilter/vf_showinfo.c ++++ b/libavfilter/vf_showinfo.c +@@ -140,12 +140,37 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) + return ff_filter_frame(inlink->dst->outputs[0], frame); + } + ++static int config_props(AVFilterContext *ctx, AVFilterLink *link, int is_out) ++{ ++ ++ av_log(ctx, AV_LOG_INFO, "config %s time_base: %d/%d, frame_rate: %d/%d\n", ++ is_out ? "out" :"in", ++ link->time_base.num, link->time_base.den, ++ link->frame_rate.num, link->frame_rate.den ++ ); ++ ++ return 0; ++} ++ ++static int config_props_in(AVFilterLink *link) ++{ ++ AVFilterContext *ctx = link->dst; ++ return config_props(ctx, link, 0); ++} ++ ++static int config_props_out(AVFilterLink *link) ++{ ++ AVFilterContext *ctx = link->src; ++ return config_props(ctx, link, 1); ++} ++ + static const AVFilterPad avfilter_vf_showinfo_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .get_video_buffer = ff_null_get_video_buffer, + .filter_frame = filter_frame, ++ .config_props = config_props_in, + }, + { NULL } + }; +@@ -153,7 +178,8 @@ static const AVFilterPad avfilter_vf_showinfo_inputs[] = { + static const AVFilterPad avfilter_vf_showinfo_outputs[] = { + { + .name = "default", +- .type = AVMEDIA_TYPE_VIDEO ++ .type = AVMEDIA_TYPE_VIDEO, ++ .config_props = config_props_out, + }, + { NULL } + }; +diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c +index 574eac4..62576f7 100644 +--- a/libavfilter/vf_yadif.c ++++ b/libavfilter/vf_yadif.c +@@ -462,6 +462,9 @@ static int config_props(AVFilterLink *link) + link->w = link->src->inputs[0]->w; + link->h = link->src->inputs[0]->h; + ++ if(s->mode&1) ++ link->frame_rate = av_mul_q(link->src->inputs[0]->frame_rate, (AVRational){2,1}); ++ + s->csp = av_pix_fmt_desc_get(link->format); + if (s->csp->comp[0].depth > 8) { + s->filter_line = filter_line_c_16bit; +diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c +index 3b506ec..644fd8b 100644 +--- a/libavfilter/vsrc_color.c ++++ b/libavfilter/vsrc_color.c +@@ -138,6 +138,7 @@ static int color_config_props(AVFilterLink *inlink) + inlink->w = color->w; + inlink->h = color->h; + inlink->time_base = color->time_base; ++ inlink->frame_rate = av_inv_q(color->time_base); + + return 0; + } +diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c +index e41625e..b6be2ea 100644 +--- a/libavfilter/vsrc_testsrc.c ++++ b/libavfilter/vsrc_testsrc.c +@@ -46,10 +46,10 @@ typedef struct TestSourceContext { + const AVClass *class; + int h, w; + unsigned int nb_frame; +- AVRational time_base; ++ AVRational time_base, frame_rate; + int64_t pts, max_pts; + char *size; ///< video frame size +- char *rate; ///< video frame rate ++ char *frame_rate_str; ///< video frame rate + char *duration; ///< total duration of the generated video + AVRational sar; ///< sample aspect ratio + +@@ -65,8 +65,8 @@ typedef struct TestSourceContext { + static const AVOption testsrc_options[] = { + { "size", "set video size", OFFSET(size), AV_OPT_TYPE_STRING, {.str = "320x240"}, .flags = FLAGS }, + { "s", "set video size", OFFSET(size), AV_OPT_TYPE_STRING, {.str = "320x240"}, .flags = FLAGS }, +- { "rate", "set video rate", OFFSET(rate), AV_OPT_TYPE_STRING, {.str = "25"}, .flags = FLAGS }, +- { "r", "set video rate", OFFSET(rate), AV_OPT_TYPE_STRING, {.str = "25"}, .flags = FLAGS }, ++ { "rate", "set video rate", OFFSET(frame_rate_str), AV_OPT_TYPE_STRING, {.str = "25"}, .flags = FLAGS }, ++ { "r", "set video rate", OFFSET(frame_rate_str), AV_OPT_TYPE_STRING, {.str = "25"}, .flags = FLAGS }, + { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = FLAGS }, + { "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl = 1}, 0, INT_MAX, FLAGS }, + { NULL }, +@@ -75,7 +75,6 @@ static const AVOption testsrc_options[] = { + static av_cold int init_common(AVFilterContext *ctx) + { + TestSourceContext *test = ctx->priv; +- AVRational frame_rate_q; + int64_t duration = -1; + int ret = 0; + +@@ -84,9 +83,9 @@ static av_cold int init_common(AVFilterContext *ctx) + return ret; + } + +- if ((ret = av_parse_video_rate(&frame_rate_q, test->rate)) < 0 || +- frame_rate_q.den <= 0 || frame_rate_q.num <= 0) { +- av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", test->rate); ++ if ((ret = av_parse_video_rate(&test->frame_rate, test->frame_rate_str)) < 0 || ++ test->frame_rate.den <= 0 || test->frame_rate.num <= 0) { ++ av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", test->frame_rate_str); + return ret; + } + +@@ -95,15 +94,14 @@ static av_cold int init_common(AVFilterContext *ctx) + return ret; + } + +- test->time_base.num = frame_rate_q.den; +- test->time_base.den = frame_rate_q.num; ++ test->time_base = av_inv_q(test->frame_rate); + test->max_pts = duration >= 0 ? + av_rescale_q(duration, AV_TIME_BASE_Q, test->time_base) : -1; + test->nb_frame = 0; + test->pts = 0; + + av_log(ctx, AV_LOG_DEBUG, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n", +- test->w, test->h, frame_rate_q.num, frame_rate_q.den, ++ test->w, test->h, test->frame_rate.num, test->frame_rate.den, + duration < 0 ? -1 : test->max_pts * av_q2d(test->time_base), + test->sar.num, test->sar.den); + return 0; +@@ -116,7 +114,8 @@ static int config_props(AVFilterLink *outlink) + outlink->w = test->w; + outlink->h = test->h; + outlink->sample_aspect_ratio = test->sar; +- outlink->time_base = test->time_base; ++ outlink->frame_rate = test->frame_rate; ++ outlink->time_base = test->time_base; + + return 0; + } diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs index 9c9c8d4ac..682ecb575 100644 --- a/contrib/ffmpeg/module.defs +++ b/contrib/ffmpeg/module.defs @@ -22,7 +22,6 @@ FFMPEG.CONFIGURE.extra = \ --disable-avplay \ --disable-avprobe \ --disable-avdevice \ - --disable-avfilter \ --disable-muxers \ --disable-network \ --disable-hwaccels \ |