From 45112cdb8ea812ab2264d65c5c7b3ea5238ce6dd Mon Sep 17 00:00:00 2001
From: dsmudhar <ds.mudhar@gmail.com>
Date: Sat, 7 May 2016 23:52:44 +0530
Subject: [PATCH 1/2] vf_codecview: improved filter options

---
 doc/filters.texi           | 28 ++++++++++++++++++++++------
 libavfilter/vf_codecview.c | 24 +++++++++++++++---------
 2 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 8fca52d..71a4ac4 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -4715,12 +4715,22 @@ Set motion vectors to visualize.
 Available flags for @var{mv} are:
 
 @table @samp
+@item fp
+forward predicted MVs
+@item bp
+backward predicted MVs
+@end table
+
+@item frames
+Set frame types to display motion vectors of.
+
+Available flags for @var{frames} are:
+
+@table @samp
 @item pf
-forward predicted MVs of P-frames
+predicted frames (p-frames)
 @item bf
-forward predicted MVs of B-frames
-@item bb
-backward predicted MVs of B-frames
+bi-directionally predicted frames (b-frames)
 @end table
 
 @item qp
@@ -4731,9 +4741,15 @@ Display quantization parameters using the chroma planes
 
 @itemize
 @item
-Visualizes multi-directionals MVs from P and B-Frames using @command{ffplay}:
+Visualizes forward predicted MVs from all frames using @command{ffplay}:
+@example
+ffplay -flags2 +export_mvs input.mpg -vf codecview=mv=fp
+@end example
+
+@item
+Visualizes multi-directionals MVs from P and B-Frames:
 @example
-ffplay -flags2 +export_mvs input.mpg -vf codecview=mv=pf+bf+bb
+ffplay -flags2 +export_mvs input.mpg -vf codecview=mv=fp+bp:frames=pf+bf
 @end example
 @end itemize
 
diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c
index e70b397..d9ee8b0 100644
--- a/libavfilter/vf_codecview.c
+++ b/libavfilter/vf_codecview.c
@@ -35,24 +35,30 @@
 #include "avfilter.h"
 #include "internal.h"
 
-#define MV_P_FOR  (1<<0)
-#define MV_B_FOR  (1<<1)
-#define MV_B_BACK (1<<2)
+#define MV_FOR  (1<<0)
+#define MV_BACK (1<<1)
+#define FRAME_TYPE_P (1<<0)
+#define FRAME_TYPE_B (1<<1)
 
 typedef struct {
     const AVClass *class;
     unsigned mv;
+    unsigned frames;
     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("fp", "forward predicted MVs",  MV_FOR,  "mv"),
+        CONST("bp", "backward predicted MVs", MV_BACK, "mv"),
+    { "frames", "set frame types to display MVs of", OFFSET(frames), AV_OPT_TYPE_FLAGS, {.i64=3}, 0, INT_MAX, FLAGS, "frames" },
+        CONST("pf", "p-frames", FRAME_TYPE_P, "frames"),
+        CONST("bf", "b-frames", FRAME_TYPE_B, "frames"),
     { "qp", NULL, OFFSET(qp), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS },
     { NULL }
 };
@@ -232,9 +238,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
             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))
+                if ((direction == 0 && (s->mv & MV_FOR)  && (s->frames & FRAME_TYPE_P) && frame->pict_type == AV_PICTURE_TYPE_P) ||
+                    (direction == 0 && (s->mv & MV_FOR)  && (s->frames & FRAME_TYPE_B) && frame->pict_type == AV_PICTURE_TYPE_B) ||
+                    (direction == 1 && (s->mv & MV_BACK) && (s->frames & FRAME_TYPE_B) && 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);
-- 
2.7.4 (Apple Git-66)

