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

marco subversion at mplayerhq.hu
Thu Aug 16 21:58:37 CEST 2007


Author: marco
Date: Thu Aug 16 21:58:37 2007
New Revision: 896

Log:
merge qpel/eighthpel code with the motion_comp_1ref code to optimize border conditions and make further optimizations possible

Modified:
   dirac/libavcodec/dirac.c

Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c	(original)
+++ dirac/libavcodec/dirac.c	Thu Aug 16 21:58:37 2007
@@ -2379,8 +2379,12 @@ static void motion_comp_block1ref(DiracC
                                   int comp) {
     int x, y;
     int16_t *line;
+    uint8_t  *refline;
     int px, py;
     int vect[2];
+    int refxstart, refystart;
+
+START_TIMER
 
         vect[0] = currblock->vect[ref][0];
         vect[1] = currblock->vect[ref][1];
@@ -2390,9 +2394,27 @@ static void motion_comp_block1ref(DiracC
         vect[1] >>= s->chroma_vshift;
     }
 
+    if (s->frame_decoding.mv_precision > 0) {
+        refxstart   = (xstart << s->frame_decoding.mv_precision) + vect[0];
+        refxstart >>= s->frame_decoding.mv_precision - 1;
+        refystart   = (ystart << s->frame_decoding.mv_precision) + vect[1];
+        refystart >>= s->frame_decoding.mv_precision - 1;
+    } else {
+        refxstart = (xstart + vect[0]) << 1;
+        refxstart >>= s->frame_decoding.mv_precision - 1;
+        refystart = (ystart + vect[1]) << 1;
+        refystart >>= s->frame_decoding.mv_precision - 1;
+    }
+
     line = &coeffs[s->width * ystart];
+    refline = &refframe[refystart * s->refwidth];
     for (y = ystart; y < ystop; y++) {
         for (x = xstart; x < xstop; x++) {
+            int hx, hy;
+            int rx, ry;
+            /* XXX: This matrix can perhaps be stored in a fixed
+               table.  */
+            int w00, w01, w10, w11;
             int val = 0;
 
             if (s->frame_decoding.mv_precision > 0) {
@@ -2403,8 +2425,39 @@ static void motion_comp_block1ref(DiracC
                 py = (y + vect[1]) << 1;
             }
 
-            val = upconvert(s, refframe, s->refwidth, s->refheight,
-                            px, py, comp);
+            hx = px >> (s->frame_decoding.mv_precision - 1);
+            hy = py >> (s->frame_decoding.mv_precision - 1);
+
+            if (s->frame_decoding.mv_precision == 0
+                || s->frame_decoding.mv_precision == 1) {
+                val = get_halfpel(refframe, s->refwidth, s->refheight, x, y);
+            } else {
+                rx = px - (hx << (s->frame_decoding.mv_precision - 1));
+                ry = py - (hy << (s->frame_decoding.mv_precision - 1));
+
+                w00 = ((1 << (s->frame_decoding.mv_precision - 1)) - ry)
+                    * ((1 << (s->frame_decoding.mv_precision - 1)) - rx);
+                w01 = ((1 << (s->frame_decoding.mv_precision - 1)) - ry) * rx;
+                w10 = ((1 << (s->frame_decoding.mv_precision - 1)) - rx) * ry;
+                w11 = ry * rx;
+
+                if (hx > 0 && hy > 0 && hx < (s->refwidth - 1) && hy < (s->refheight - 11)) {
+                    val += w00 * refline[hx                  ];
+                    val += w01 * refline[hx               + 1];
+                    val += w10 * refline[hx + s->refwidth    ];
+                    val += w11 * refline[hx + s->refwidth + 1];
+                } else {
+                    /* Border condition, keep using the slower code.  */
+                    val += w00 * get_halfpel(refframe, s->refwidth, s->refheight, hx    , hy    );
+                    val += w01 * get_halfpel(refframe, s->refwidth, s->refheight, hx + 1, hy    );
+                    val += w10 * get_halfpel(refframe, s->refwidth, s->refheight, hx    , hy + 1);
+                    val += w11 * get_halfpel(refframe, s->refwidth, s->refheight, hx + 1, hy + 1);
+                }
+
+                val += 1 << (s->frame_decoding.mv_precision - 1);
+                val >>= s->frame_decoding.mv_precision;
+            }
+
             val *= s->frame_decoding.picture_weight_ref1
                  + s->frame_decoding.picture_weight_ref2;
 
@@ -2417,7 +2470,10 @@ static void motion_comp_block1ref(DiracC
             line[x] += val;
         }
         line += s->width;
+        refline += s->refwidth << 1;
     }
+
+STOP_TIMER("single_refframe");
 }
 
 /**



More information about the FFmpeg-soc mailing list