summaryrefslogtreecommitdiffstats
path: root/contrib/ffmpeg
diff options
context:
space:
mode:
authorJohn Stebbins <[email protected]>2015-10-24 14:06:56 -0700
committerJohn Stebbins <[email protected]>2016-01-21 12:38:42 -0700
commit10ea76c71197b302b10088d93680a4bed4bc6b8e (patch)
tree459b46b16256c39ed34fe1f0a4b9476ec3439871 /contrib/ffmpeg
parentef956e695879c716dc22c96f7f8fa24e3fa5d08c (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.patch34
-rw-r--r--contrib/ffmpeg/A11-avfilter-framerate.patch352
-rw-r--r--contrib/ffmpeg/module.defs1
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 \