From 58b2545797c6d61cb5a200f800835b84dc105cfa Mon Sep 17 00:00:00 2001
From: dsmudhar <ds.mudhar@gmail.com>
Date: Fri, 13 May 2016 23:27:41 +0530
Subject: [PATCH] vf_codecview: improved filter options

---
 doc/filters.texi            | 30 ++++++++++++++++++++++++------
 libavfilter/vf_codecview.c  | 36 ++++++++++++++++++++++++++----------
 tests/fate/filter-video.mak |  2 +-
 3 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 8fca52d..6204b5d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -4715,12 +4715,24 @@ 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 if
+intra-coded frames (I-frames)
 @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 +4743,15 @@ Display quantization parameters using the chroma planes
 
 @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.mpg -vf codecview=mv=fp
+@end example
+
+@item
+Visualize multi-directional MVs of 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..d2c9254 100644
--- a/libavfilter/vf_codecview.c
+++ b/libavfilter/vf_codecview.c
@@ -35,24 +35,32 @@
 #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_I (1<<0)
+#define FRAME_TYPE_P (1<<1)
+#define FRAME_TYPE_B (1<<2)
 
 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=0}, 0, INT_MAX, FLAGS, "frames" },
+        CONST("if", "I-frames", FRAME_TYPE_I, "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 }
 };
@@ -229,15 +237,23 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
         if (sd) {
             int i;
             const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
+            const int is_iframe = (s->frames & FRAME_TYPE_I) && frame->pict_type == AV_PICTURE_TYPE_I;
+            const int is_pframe = (s->frames & FRAME_TYPE_P) && frame->pict_type == AV_PICTURE_TYPE_P;
+            const int is_bframe = (s->frames & 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))
+                const int is_fp = direction == 0 && (s->mv & MV_FOR);
+                const int is_bp = direction == 1 && (s->mv & MV_BACK);
+
+                if ((!s->frames && (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, mv->source > 0);
+                               100, 0, direction);
             }
         }
     }
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index 4b17d59..2be933b 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -32,7 +32,7 @@ fate-filter-mcdeint-medium: CMD = framecrc -flags bitexact -idct simple -i $(TAR
 FATE_FILTER_SAMPLES-$(call ALLYES, MCDEINT_FILTER, MPEGTS_DEMUXER, MPEG2VIDEO_DECODER SNOW_ENCODER) += $(FATE_MCDEINT)
 
 FATE_FILTER_SAMPLES-$(call ALLYES, CODECVIEW_FILTER RM_DEMUXER RV40_DECODER) += fate-filter-codecview-mvs
-fate-filter-codecview-mvs: CMD = framecrc -flags2 +export_mvs -i $(TARGET_SAMPLES)/real/spygames-2MB.rmvb -vf codecview=mv=pf+bf+bb -vframes 60 -an
+fate-filter-codecview-mvs: CMD = framecrc -flags2 +export_mvs -i $(TARGET_SAMPLES)/real/spygames-2MB.rmvb -vf codecview=mv=fp+bp:frames=if+bf+pf -vframes 60 -an
 
 FATE_FILTER_SAMPLES-$(call ALLYES, SHOWPALETTE_FILTER FLIC_DEMUXER FLIC_DECODER) += fate-filter-showpalette
 fate-filter-showpalette: CMD = framecrc -i $(TARGET_SAMPLES)/fli/fli-engines.fli -vf showpalette=3 -pix_fmt bgra
-- 
2.7.4 (Apple Git-66)

