From 7a2b9dd060b6f057758a1ac7820b66d6c1ad1e49 Mon Sep 17 00:00:00 2001 From: dsmudhar Date: Thu, 9 Jun 2016 18:42:33 +0530 Subject: [PATCH] vf_codecview: added new options Signed-off-by: Michael Niedermayer --- doc/filters.texi | 38 +++++++++++++++++++++++++++++--- libavfilter/vf_codecview.c | 55 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 22347346b0..605f67066c 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -4790,16 +4790,48 @@ backward predicted MVs of B-frames @end table @item qp -Display quantization parameters using the chroma planes +Display quantization parameters using the chroma planes. + +@item mv_type, mvt +Set motion vectors type to visualize. Includes MVs from all frames unless specified by @var{frame_type} option. + +Available flags for @var{mv_type} are: + +@table @samp +@item fp +forward predicted MVs +@item bp +backward predicted MVs +@end table + +@item frame_type, ft +Set frame type to visualize motion vectors of. + +Available flags for @var{frame_type} are: + +@table @samp +@item if +intra-coded frames (I-frames) +@item pf +predicted frames (P-frames) +@item bf +bi-directionally predicted frames (B-frames) +@end table @end table @subsection Examples @itemize @item -Visualizes multi-directionals MVs from P and B-Frames using @command{ffplay}: +Visualize forward predicted MVs of all frames using @command{ffplay}: +@example +ffplay -flags2 +export_mvs input.mp4 -vf codecview=mv_type=fp +@end example + +@item +Visualize multi-directionals MVs of P and B-Frames using @command{ffplay}: @example -ffplay -flags2 +export_mvs input.mpg -vf codecview=mv=pf+bf+bb +ffplay -flags2 +export_mvs input.mp4 -vf codecview=mv=pf+bf+bb @end example @end itemize diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c index e70b397ee3..dc3397316d 100644 --- a/libavfilter/vf_codecview.c +++ b/libavfilter/vf_codecview.c @@ -38,22 +38,40 @@ #define MV_P_FOR (1<<0) #define MV_B_FOR (1<<1) #define MV_B_BACK (1<<2) +#define MV_TYPE_FOR (1<<0) +#define MV_TYPE_BACK (1<<1) +#define FRAME_TYPE_I (1<<0) +#define FRAME_TYPE_P (1<<1) +#define FRAME_TYPE_B (1<<2) typedef struct { const AVClass *class; unsigned mv; + unsigned frame_type; + unsigned mv_type; int hsub, vsub; int qp; } CodecViewContext; #define OFFSET(x) offsetof(CodecViewContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM +#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, 0, 0, FLAGS, unit } + static const AVOption codecview_options[] = { { "mv", "set motion vectors to visualize", OFFSET(mv), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "mv" }, - {"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = MV_P_FOR }, INT_MIN, INT_MAX, FLAGS, "mv"}, - {"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = MV_B_FOR }, INT_MIN, INT_MAX, FLAGS, "mv"}, - {"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = MV_B_BACK }, INT_MIN, INT_MAX, FLAGS, "mv"}, + CONST("pf", "forward predicted MVs of P-frames", MV_P_FOR, "mv"), + CONST("bf", "forward predicted MVs of B-frames", MV_B_FOR, "mv"), + CONST("bb", "backward predicted MVs of B-frames", MV_B_BACK, "mv"), { "qp", NULL, OFFSET(qp), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS }, + { "mv_type", "set motion vectors type", OFFSET(mv_type), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "mv_type" }, + { "mvt", "set motion vectors type", OFFSET(mv_type), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "mv_type" }, + CONST("fp", "forward predicted MVs", MV_TYPE_FOR, "mv_type"), + CONST("bp", "backward predicted MVs", MV_TYPE_BACK, "mv_type"), + { "frame_type", "set frame types to visualize motion vectors of", OFFSET(frame_type), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "frame_type" }, + { "ft", "set frame types to visualize motion vectors of", OFFSET(frame_type), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, INT_MAX, FLAGS, "frame_type" }, + CONST("if", "I-frames", FRAME_TYPE_I, "frame_type"), + CONST("pf", "P-frames", FRAME_TYPE_P, "frame_type"), + CONST("bf", "B-frames", FRAME_TYPE_B, "frame_type"), { NULL } }; @@ -224,20 +242,37 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) } } - if (s->mv) { + if (s->mv || s->mv_type) { AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS); if (sd) { int i; const AVMotionVector *mvs = (const AVMotionVector *)sd->data; + const int is_iframe = (s->frame_type & FRAME_TYPE_I) && frame->pict_type == AV_PICTURE_TYPE_I; + const int is_pframe = (s->frame_type & FRAME_TYPE_P) && frame->pict_type == AV_PICTURE_TYPE_P; + const int is_bframe = (s->frame_type & FRAME_TYPE_B) && frame->pict_type == AV_PICTURE_TYPE_B; + for (i = 0; i < sd->size / sizeof(*mvs); i++) { const AVMotionVector *mv = &mvs[i]; const int direction = mv->source > 0; - if ((direction == 0 && (s->mv & MV_P_FOR) && frame->pict_type == AV_PICTURE_TYPE_P) || - (direction == 0 && (s->mv & MV_B_FOR) && frame->pict_type == AV_PICTURE_TYPE_B) || - (direction == 1 && (s->mv & MV_B_BACK) && frame->pict_type == AV_PICTURE_TYPE_B)) - draw_arrow(frame->data[0], mv->dst_x, mv->dst_y, mv->src_x, mv->src_y, - frame->width, frame->height, frame->linesize[0], - 100, 0, mv->source > 0); + + if (s->mv_type) { + const int is_fp = direction == 0 && (s->mv_type & MV_TYPE_FOR); + const int is_bp = direction == 1 && (s->mv_type & MV_TYPE_BACK); + + if ((!s->frame_type && (is_fp || is_bp)) || + is_iframe && is_fp || is_iframe && is_bp || + is_pframe && is_fp || + is_bframe && is_fp || is_bframe && is_bp) + draw_arrow(frame->data[0], mv->dst_x, mv->dst_y, mv->src_x, mv->src_y, + frame->width, frame->height, frame->linesize[0], + 100, 0, direction); + } else if (s->mv) + if ((direction == 0 && (s->mv & MV_P_FOR) && frame->pict_type == AV_PICTURE_TYPE_P) || + (direction == 0 && (s->mv & MV_B_FOR) && frame->pict_type == AV_PICTURE_TYPE_B) || + (direction == 1 && (s->mv & MV_B_BACK) && frame->pict_type == AV_PICTURE_TYPE_B)) + draw_arrow(frame->data[0], mv->dst_x, mv->dst_y, mv->src_x, mv->src_y, + frame->width, frame->height, frame->linesize[0], + 100, 0, direction); } } } -- 2.11.0