[FFmpeg-soc] [soc]: r537 - dirac/libavcodec/dirac.c

marco subversion at mplayerhq.hu
Thu Jul 26 20:19:35 CEST 2007


Author: marco
Date: Thu Jul 26 20:19:35 2007
New Revision: 537

Log:
read motion vectors and dc values

Modified:
   dirac/libavcodec/dirac.c

Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c	(original)
+++ dirac/libavcodec/dirac.c	Thu Jul 26 20:19:35 2007
@@ -1202,18 +1202,18 @@ static void blockmode_prediction(AVCodec
 static void blockglob_prediction(AVCodecContext *avctx, int x, int y) {
     DiracContext *s = avctx->priv_data;
 
-    s->blmotion[y * s-> blwidth + x].use_global = 0;
+    s->blmotion[y * s->blwidth + x].use_global = 0;
 
     /* Global motion compensation is not used at all.  */
     if (!s->globalmc_flag)
         return;
 
     /* Global motion compensation is not used for this block.  */
-    if (s->blmotion[y * s-> blwidth + x].use_ref[0] == 0
-        || s->blmotion[y * s-> blwidth + x].use_ref[0] == 0) {
+    if (s->blmotion[y * s->blwidth + x].use_ref[0] == 0
+        || s->blmotion[y * s->blwidth + x].use_ref[0] == 0) {
         int res = dirac_arith_get_bit(&s->arith, ARITH_CONTEXT_GLOBAL_BLOCK);
         res ^= global_mode_prediction(avctx, x, y);
-        s->blmotion[y * s-> blwidth + x].use_global = res;
+        s->blmotion[y * s->blwidth + x].use_global = res;
     }
 }
 
@@ -1230,8 +1230,124 @@ static void propagate_block_data(AVCodec
 }
 
 static int motion_vector_prediction(AVCodecContext *avctx, int x, int y,
-                                    int res, int dir) {
-    return 0;
+                                    int ref, int dir) {
+    DiracContext *s = avctx->priv_data;
+    int cnt = 0;
+    int left = 0, top = 0, lefttop = 0;
+
+    if (x > 0) {
+        /* Test if the block to the left has a motion vector for this
+           reference frame.  */
+        if (!s->blmotion[y * s->blwidth + x - 1].use_global
+            && s->blmotion[y * s->blwidth + x - 1].use_ref[ref]) {
+            if (ref == 0) /* XXX */
+                left = s->blmotion[y * s->blwidth + x - 1].ref1[dir];
+            else
+                left = s->blmotion[y * s->blwidth + x - 1].ref2[dir];
+
+            /* This is the only reference, return it.  */
+            if (y == 0)
+                return left;
+
+            cnt++;
+        }
+    }
+
+    if (y > 0) {
+        /* Test if the block above the current one has a motion vector
+           for this reference frame.  */
+        if (!s->blmotion[(y - 1) * s->blwidth + x].use_global
+            && s->blmotion[(y - 1) * s->blwidth + x].use_ref[ref])
+            {
+                if (ref == 0) /* XXX */
+                    top = s->blmotion[(y - 1) * s->blwidth + x].ref1[dir];
+                else
+                    top = s->blmotion[(y - 1) * s->blwidth + x].ref2[dir];
+
+                /* This is the only reference, return it.  */
+                if (x == 0)
+                    return top;
+
+                cnt++;
+            }
+    }
+
+    if (x > 0 && y > 0) {
+        /* Test if the block above the current one has a motion vector
+           for this reference frame.  */
+        if (!s->blmotion[(y - 1) * s->blwidth + x - 1].use_global
+            && s->blmotion[(y - 1) * s->blwidth + x - 1].use_ref[ref]) {
+            if (ref == 0) /* XXX */
+                lefttop = s->blmotion[(y - 1) * s->blwidth + x - 1].ref1[dir];
+            else
+                lefttop = s->blmotion[(y - 1) * s->blwidth + x - 1].ref2[dir];
+
+            cnt++;
+        }
+    }
+
+    /* No references for the prediction.  */
+    if (cnt == 0)
+        return 0;
+
+    assert(cnt == 2 || cnt == 3);
+
+    /* Return the median of two motion vectors.  */
+    if (cnt == 2)
+        return (left + top + lefttop) / 2;
+
+    /* Return the median of three motion vectors.  */
+    return mid_pred(left, top, lefttop);
+}
+
+static int block_dc_prediction(AVCodecContext *avctx, int x, int y, int comp) {
+    DiracContext *s = avctx->priv_data;
+    int total = 0;
+    int cnt = 0;
+
+    if (x > 0) {
+        if (   !s->blmotion[y * s->blwidth + x - 1].use_ref[0]
+            && !s->blmotion[y * s->blwidth + x - 1].use_ref[1]) {
+            total += s->blmotion[y * s->blwidth + x - 1].dc[comp];
+            cnt++;
+        }
+    }
+
+    if (y > 0) {
+        if (   !s->blmotion[(y - 1) * s->blwidth + x].use_ref[0]
+            && !s->blmotion[(y - 1) * s->blwidth + x].use_ref[1]) {
+            total += s->blmotion[(y - 1) * s->blwidth + x].dc[comp];
+            cnt++;
+        }
+    }
+
+    if (x > 0 && y > 0) {
+        if (   !s->blmotion[(y - 1) * s->blwidth + x - 1].use_ref[0]
+            && !s->blmotion[(y - 1) * s->blwidth + x - 1].use_ref[1]) {
+            total += s->blmotion[(y - 1) * s->blwidth + x - 1].dc[comp];
+            cnt++;
+        }
+    }
+
+    if (cnt == 0)
+        return (1 << s->sequence.video_depth) - 1;
+
+    /* Return the average of all DC values that were counted.  */
+    return total / cnt;
+}
+
+static void unpack_block_dc(AVCodecContext *avctx, int x, int y, int comp) {
+    DiracContext *s = avctx->priv_data;
+    int res;
+
+    if (   !s->blmotion[y * s->blwidth + x].use_ref[0]
+        && !s->blmotion[y * s->blwidth + x].use_ref[1])
+        return;
+
+    res = dirac_arith_read_int(&s->arith, &context_set_dc);
+    res += block_dc_prediction(avctx, x, y, comp);
+
+    s->blmotion[y * s->blwidth + x].dc[comp] = res;
 }
 
 /**
@@ -1240,8 +1356,9 @@ static int motion_vector_prediction(AVCo
  * @param ref reference frame
  * @param dir direction horizontal=0, vertical=1
  */
-static void dirac_unpack_motion_vector(AVCodecContext *avctx, int x, int y,
-                                       int ref, int dir) {
+static void dirac_unpack_motion_vector(AVCodecContext *avctx,
+                                       int ref, int dir,
+                                       int x, int y) {
     DiracContext *s = avctx->priv_data;
     int res;
 
@@ -1282,17 +1399,17 @@ static void dirac_unpack_motion_vectors(
 
             for (q = 0; q < blkcnt; q++)
                 for (p = 0; p < blkcnt; p++) {
-
+                    dirac_unpack_motion_vector(avctx, ref, dir,
+                                         4 * y + p * step,
+                                         4 * y + q * step);
                     propagate_block_data(avctx, step,
                                          4 * y + p * step,
                                          4 * y + q * step);
-
                 }
         }
     dirac_arith_flush(&s->arith);
 }
 
-
 /**
  * Unpack the motion compensation parameters
  */
@@ -1300,6 +1417,7 @@ static void dirac_unpack_prediction_data
     DiracContext *s = avctx->priv_data;
     GetBitContext *gb = s->gb;
     int length;
+    int comp;
     int x, y;
 
     s->blwidth  = s->sequence.luma_width  / s->frame_decoding.luma_xbsep;
@@ -1307,8 +1425,8 @@ static void dirac_unpack_prediction_data
     s->sbwidth  = s->blwidth  >> 2;
     s->sbheight = s->blheight >> 2;
 
-    s->sbsplit  = av_malloc(s->sbwidth * s->sbheight);
-    s->blmotion = av_malloc(s->blwidth * s->blheight);
+    s->sbsplit  = av_mallocz(s->sbwidth * s->sbheight);
+    s->blmotion = av_mallocz(s->blwidth * s->blheight);
 
     /* Superblock splitmodes.  */
     length = dirac_get_ue_golomb(gb);
@@ -1345,12 +1463,38 @@ static void dirac_unpack_prediction_data
         }
     dirac_arith_flush(&s->arith);
 
+    /* Unpack the motion vectors.  */
     dirac_unpack_motion_vectors(avctx, 0, 0);
     dirac_unpack_motion_vectors(avctx, 0, 1);
     if (s->refs == 2) {
         dirac_unpack_motion_vectors(avctx, 1, 0);
         dirac_unpack_motion_vectors(avctx, 1, 1);
     }
+
+    /* Unpack the DC values for all the three components (YUV).  */
+    for (comp = 0; comp < 3; comp++) {
+        /* Unpack the DC values.  */
+        length = dirac_get_ue_golomb(gb);
+        dirac_arith_init(&s->arith, gb, length);
+        for (y = 0; y < s->sbheight; y++)
+            for (x = 0; x < s->sbwidth; x++) {
+                int q, p;
+                int blkcnt = 1 << s->sbsplit[y * s->sbwidth + x];
+                int step   = 4 >> s->sbsplit[y * s->sbwidth + x];
+
+                for (q = 0; q < blkcnt; q++)
+                    for (p = 0; p < blkcnt; p++) {
+                        unpack_block_dc(avctx,
+                                        4 * y + p * step,
+                                        4 * y + q * step,
+                                        comp);
+                        propagate_block_data(avctx, step,
+                                             4 * y + p * step,
+                                             4 * y + q * step);
+                    }
+            }
+        dirac_arith_flush(&s->arith);
+    }
 }
 
 /**



More information about the FFmpeg-soc mailing list