From 33b5ad805cccd7b48a6b0d643c39e8dd26f0e98b Mon Sep 17 00:00:00 2001
From: dsmudhar <ds.mudhar@gmail.com>
Date: Fri, 6 May 2016 15:07:03 +0530
Subject: [PATCH] set exact ref frame in AVMotionVector

---
 libavcodec/mpegvideo.c     |  2 +-
 libavcodec/snowdec.c       |  2 +-
 libavfilter/vf_codecview.c | 13 ++++++-------
 libavutil/motion_vector.h  | 15 ++++++++++-----
 4 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index bc78039..8e851d1 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -1569,7 +1569,7 @@ static int add_mb(AVMotionVector *mb, uint32_t mb_type,
     mb->dst_y = dst_y;
     mb->src_x = dst_x + motion_x / motion_scale;
     mb->src_y = dst_y + motion_y / motion_scale;
-    mb->source = direction ? 1 : -1;
+    mb->ref = direction ? AV_MV_REF_FRAME_NEXT : AV_MV_REF_FRAME_PREVIOUS;
     mb->flags = 0; // XXX: does mb_type contain extra information that could be exported here?
     return 1;
 }
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
index 042aecb..f1ccc94 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -109,7 +109,7 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer
             avmv->motion_y = bn->my * s->mv_scale;
             avmv->src_x = avmv->dst_x + avmv->motion_x / 8;
             avmv->src_y = avmv->dst_y + avmv->motion_y / 8;
-            avmv->source= -1 - bn->ref;
+            avmv->ref = AV_MV_REF_FRAME_PREVIOUS;
             avmv->flags = 0;
         }
 }
diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c
index e70b397..0a50fb1 100644
--- a/libavfilter/vf_codecview.c
+++ b/libavfilter/vf_codecview.c
@@ -157,11 +157,11 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey,
  * @param color color of the arrow
  */
 static void draw_arrow(uint8_t *buf, int sx, int sy, int ex,
-                       int ey, int w, int h, int stride, int color, int tail, int direction)
+                       int ey, int w, int h, int stride, int color, int tail, int ref)
 {
     int dx,dy;
 
-    if (direction) {
+    if (ref == AV_MV_REF_FRAME_NEXT) {
         FFSWAP(int, sx, ex);
         FFSWAP(int, sy, ey);
     }
@@ -231,13 +231,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
             const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
             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 ((mv->ref == AV_MV_REF_FRAME_PREVIOUS && (s->mv & MV_P_FOR)  && frame->pict_type == AV_PICTURE_TYPE_P) ||
+                    (mv->ref == AV_MV_REF_FRAME_PREVIOUS && (s->mv & MV_B_FOR)  && frame->pict_type == AV_PICTURE_TYPE_B) ||
+                    (mv->ref == AV_MV_REF_FRAME_NEXT && (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);
+                               100, 0, mv->ref);
             }
         }
     }
diff --git a/libavutil/motion_vector.h b/libavutil/motion_vector.h
index ec29556..40d1f85 100644
--- a/libavutil/motion_vector.h
+++ b/libavutil/motion_vector.h
@@ -21,23 +21,28 @@
 
 #include <stdint.h>
 
+#define AV_MV_REF_FRAME_PREVIOUS    -1
+#define AV_MV_REF_FRAME_NEXT         1
+
 typedef struct AVMotionVector {
     /**
-     * Where the current macroblock comes from; negative value when it comes
-     * from the past, positive value when it comes from the future.
-     * XXX: set exact relative ref frame reference instead of a +/- 1 "direction".
+     * Frame used as reference to estimate motion vector of current macroblock.
+     * AV_MV_REF_FRAME_PREVIOUS if past frame or
+     * AV_MV_REF_FRAME_NEXT if future frame is used.
      */
-    int32_t source;
+    int32_t ref;
     /**
-     * Width and height of the block.
+     * Width and height of the macroblock.
      */
     uint8_t w, h;
     /**
      * Absolute source position. Can be outside the frame area.
+     * Usually, position of matched macroblock in reference frame.
      */
     int16_t src_x, src_y;
     /**
      * Absolute destination position. Can be outside the frame area.
+     * Usually, position of current macroblock.
      */
     int16_t dst_x, dst_y;
     /**
-- 
2.6.4 (Apple Git-63)

