Signed-off-by: Paul B Mahol <one...@gmail.com> --- doc/filters.texi | 4 ++++ libavfilter/avfilter.c | 30 ++++++++++++++++++++++++++++++ libavfilter/internal.h | 2 ++ libavfilter/vf_stereo3d.c | 37 ++++++++++++++++++++++++++++++++++--- 4 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi index 4a4efc70c8..e8da5e21a6 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -14057,6 +14057,10 @@ Set stereoscopic image format of input. Available values for input image formats are: @table @samp +@item auto +set input format using frame side data +If such data is not available filter will return unchanged input. + @item sbsl side by side parallel (left eye left, right eye right) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index b98b32bacb..0d4bfd2671 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -378,6 +378,36 @@ int avfilter_config_links(AVFilterContext *filter) return 0; } +static int reset_links(AVFilterContext *filter) +{ + int i, ret; + + if (!filter) + return 0; + + for (i = 0; i < filter->nb_outputs; i++) { + AVFilterLink *link = filter->outputs[i]; + + link->init_state = AVLINK_UNINIT; + link->frame_rate.num = link->frame_rate.den = 0; + link->w = link->h = 0; + + ret = reset_links(link->dst); + if (ret < 0) + return ret; + } + + if (!i) + return avfilter_config_links(filter); + + return 0; +} + +int ff_reconfig_links(AVFilterContext *filter) +{ + return reset_links(filter); +} + void ff_tlog_link(void *ctx, AVFilterLink *link, int end) { if (link->type == AVMEDIA_TYPE_VIDEO) { diff --git a/libavfilter/internal.h b/libavfilter/internal.h index f9679ed1d7..5062bb7296 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -411,4 +411,6 @@ static inline int ff_norm_qscale(int qscale, int type) */ int ff_filter_get_nb_threads(AVFilterContext *ctx); +int ff_reconfig_links(AVFilterContext *ctx); + #endif /* AVFILTER_INTERNAL_H */ diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c index 8b22f880ca..6665a2631b 100644 --- a/libavfilter/vf_stereo3d.c +++ b/libavfilter/vf_stereo3d.c @@ -25,6 +25,7 @@ #include "libavutil/opt.h" #include "libavutil/parseutils.h" #include "libavutil/pixdesc.h" +#include "libavutil/stereo3d.h" #include "avfilter.h" #include "drawutils.h" #include "formats.h" @@ -47,8 +48,8 @@ enum StereoCode { ANAGLYPH_YB_DUBOIS, // anaglyph yellow/blue dubois ANAGLYPH_RB_GRAY, // anaglyph red/blue gray ANAGLYPH_RG_GRAY, // anaglyph red/green gray - MONO_L, // mono output for debugging (left eye only) - MONO_R, // mono output for debugging (right eye only) + MONO_L, // mono output (left eye only) + MONO_R, // mono output (right eye only) INTERLEAVE_ROWS_LR, // row-interleave (left eye has top row) INTERLEAVE_ROWS_RL, // row-interleave (right eye has top row) SIDE_BY_SIDE_LR, // side by side parallel (left eye left, right eye right) @@ -66,7 +67,8 @@ enum StereoCode { INTERLEAVE_COLS_LR, // column-interleave (left eye first, right eye second) INTERLEAVE_COLS_RL, // column-interleave (right eye first, left eye second) HDMI, // HDMI frame pack (left eye first, right eye second) - STEREO_CODE_COUNT // TODO: needs autodetection + AUTO, // guess input format using frame's metadata. + STEREO_CODE_COUNT }; typedef struct StereoComponent { @@ -173,6 +175,7 @@ static const AVOption stereo3d_options[] = { { "irr", "interleave rows right first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_RL}, 0, 0, FLAGS, "in" }, { "icl", "interleave columns left first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_COLS_LR}, 0, 0, FLAGS, "in" }, { "icr", "interleave columns right first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_COLS_RL}, 0, 0, FLAGS, "in" }, + { "auto", "guess using frame metadata", 0, AV_OPT_TYPE_CONST, {.i64=AUTO}, 0, 0, FLAGS, "in" }, { "out", "set output format", OFFSET(out.format), AV_OPT_TYPE_INT, {.i64=ANAGLYPH_RC_DUBOIS}, 0, STEREO_CODE_COUNT-1, FLAGS, "out"}, { "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "out" }, { "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "out" }, @@ -366,6 +369,9 @@ static int config_output(AVFilterLink *outlink) int ret; s->aspect = inlink->sample_aspect_ratio; + if (s->in.format == AUTO || (s->in.format == s->out.format)) + return 0; + switch (s->in.format) { case INTERLEAVE_COLS_LR: case INTERLEAVE_COLS_RL: @@ -670,6 +676,31 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) int out_off_left[4], out_off_right[4]; int i, ret; + if (s->in.format == AUTO) { + AVFrameSideData *sd = av_frame_get_side_data(inpicref, AV_FRAME_DATA_STEREO3D); + AVFilterLink *link; + + if (sd) { + AVStereo3D *s3d = (AVStereo3D *)sd->data; + + switch (s3d->type) { + case AV_STEREO3D_SIDEBYSIDE: s->in.format = SIDE_BY_SIDE_LR; break; + case AV_STEREO3D_SIDEBYSIDE_QUINCUNX: s->in.format = SIDE_BY_SIDE_LR; break; + case AV_STEREO3D_TOPBOTTOM: s->in.format = ABOVE_BELOW_LR; break; + case AV_STEREO3D_CHECKERBOARD: s->in.format = CHECKERBOARD_LR; break; + case AV_STEREO3D_FRAMESEQUENCE: s->in.format = ALTERNATING_LR; break; + case AV_STEREO3D_LINES: s->in.format = INTERLEAVE_ROWS_LR; break; + case AV_STEREO3D_COLUMNS: s->in.format = INTERLEAVE_COLS_LR; break; + default: s->in.format = s->out.format = MONO_L; + }; + } else { + s->in.format = s->out.format = MONO_L; + } + + if ((ret = ff_reconfig_links(ctx)) < 0) + return ret; + } + if (s->in.format == s->out.format) return ff_filter_frame(outlink, inpicref); -- 2.11.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel