avcodec/vc1: implement interlaced out-of-bounds reference pixel replication
authorJerome Borsboom <jerome.borsboom@carpalis.nl>
Mon, 23 Apr 2018 18:59:41 +0000 (20:59 +0200)
committerPaul B Mahol <onemda@gmail.com>
Wed, 25 Apr 2018 20:07:20 +0000 (22:07 +0200)
The existing implementation did out-of-bounds reference pixel replication for
progressive reference frames. In interlaced reference frames both the even and
odd line on the horizontal edges need to be replicated.

Fixes #3262.

Signed-off-by: Jerome Borsboom <jerome.borsboom@carpalis.nl>
libavcodec/vc1_mc.c
tests/ref/fate/vc1_ilaced_twomv

index 5eacaaa..04b3592 100644 (file)
@@ -254,9 +254,14 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir)
         uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
     } else {
         src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
-        src_y   = av_clip(  src_y, -18, s->avctx->coded_height + 1);
         uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
-        uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
+        if (v->fcm == ILACE_FRAME) {
+            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
+            uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
+        } else {
+            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
+            uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+        }
     }
 
     srcY += src_y   * s->linesize   + src_x;
@@ -284,22 +289,113 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir)
         const int k = 17 + s->mspel * 2;
 
         srcY -= s->mspel * (1 + s->linesize);
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
-                                 s->linesize, s->linesize,
-                                 k, k,
-                                 src_x - s->mspel, src_y - s->mspel,
-                                 s->h_edge_pos, v_edge_pos);
+        if (v->fcm == ILACE_FRAME) {
+            if (src_y - s->mspel & 1) {
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
+                                         srcY,
+                                         2 * s->linesize,
+                                         2 * s->linesize,
+                                         k,
+                                         k + 1 >> 1,
+                                         src_x - s->mspel,
+                                         src_y - s->mspel >> 1,
+                                         s->h_edge_pos,
+                                         v_edge_pos + 1 >> 1);
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize,
+                                         srcY + s->linesize,
+                                         2 * s->linesize,
+                                         2 * s->linesize,
+                                         k,
+                                         k >> 1,
+                                         src_x - s->mspel,
+                                         src_y - s->mspel + 1 >> 1,
+                                         s->h_edge_pos,
+                                         v_edge_pos >> 1);
+            } else {
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
+                                         srcY,
+                                         2 * s->linesize,
+                                         2 * s->linesize,
+                                         k,
+                                         k + 1 >> 1,
+                                         src_x - s->mspel,
+                                         src_y - s->mspel >> 1,
+                                         s->h_edge_pos,
+                                         v_edge_pos >> 1);
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize,
+                                         srcY + s->linesize,
+                                         2 * s->linesize,
+                                         2 * s->linesize,
+                                         k,
+                                         k >> 1,
+                                         src_x - s->mspel,
+                                         src_y - s->mspel + 1 >> 1,
+                                         s->h_edge_pos,
+                                         v_edge_pos + 1 >> 1);
+            }
+        } else
+            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
+                                     s->linesize, s->linesize,
+                                     k, k,
+                                     src_x - s->mspel, src_y - s->mspel,
+                                     s->h_edge_pos, v_edge_pos);
         srcY = s->sc.edge_emu_buffer;
-        s->vdsp.emulated_edge_mc(ubuf, srcU,
-                                 s->uvlinesize, s->uvlinesize,
-                                 8 + 1, 8 + 1,
-                                 uvsrc_x, uvsrc_y,
-                                 s->h_edge_pos >> 1, v_edge_pos >> 1);
-        s->vdsp.emulated_edge_mc(vbuf, srcV,
-                                 s->uvlinesize, s->uvlinesize,
-                                 8 + 1, 8 + 1,
-                                 uvsrc_x, uvsrc_y,
-                                 s->h_edge_pos >> 1, v_edge_pos >> 1);
+        if (v->fcm == ILACE_FRAME) {
+            if (uvsrc_y & 1) {
+                s->vdsp.emulated_edge_mc(ubuf, srcU,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 5,
+                                         uvsrc_x, uvsrc_y >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
+                s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 4,
+                                         uvsrc_x, uvsrc_y + 1 >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
+                s->vdsp.emulated_edge_mc(vbuf, srcV,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 5,
+                                         uvsrc_x, uvsrc_y >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
+                s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 4,
+                                         uvsrc_x, uvsrc_y + 1 >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
+            } else {
+                s->vdsp.emulated_edge_mc(ubuf, srcU,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 5,
+                                         uvsrc_x, uvsrc_y >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
+                s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 4,
+                                         uvsrc_x, uvsrc_y + 1 >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
+                s->vdsp.emulated_edge_mc(vbuf, srcV,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 5,
+                                         uvsrc_x, uvsrc_y >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
+                s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 4,
+                                         uvsrc_x, uvsrc_y + 1 >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
+            }
+        } else {
+            s->vdsp.emulated_edge_mc(ubuf, srcU,
+                                     s->uvlinesize, s->uvlinesize,
+                                     8 + 1, 8 + 1,
+                                     uvsrc_x, uvsrc_y,
+                                     s->h_edge_pos >> 1, v_edge_pos >> 1);
+            s->vdsp.emulated_edge_mc(vbuf, srcV,
+                                     s->uvlinesize, s->uvlinesize,
+                                     8 + 1, 8 + 1,
+                                     uvsrc_x, uvsrc_y,
+                                     s->h_edge_pos >> 1, v_edge_pos >> 1);
+        }
         srcU = ubuf;
         srcV = vbuf;
         /* if we deal with range reduction we need to scale source blocks */
@@ -443,26 +539,16 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
         src_y = av_clip(src_y, -16, s->mb_height * 16);
     } else {
         src_x = av_clip(src_x, -17, s->avctx->coded_width);
-        if (v->fcm == ILACE_FRAME) {
-            if (src_y & 1)
-                src_y = av_clip(src_y, -17, s->avctx->coded_height + 1);
-            else
-                src_y = av_clip(src_y, -18, s->avctx->coded_height);
-        } else {
+        if (v->fcm == ILACE_FRAME)
+            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
+        else
             src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
-        }
     }
 
     srcY += src_y * s->linesize + src_x;
     if (v->field_mode && v->ref_field_type[dir])
         srcY += s->current_picture_ptr->f->linesize[0];
 
-    if (fieldmv) {
-        if (!(src_y & 1))
-            v_edge_pos--;
-        else
-            src_y -= (src_y < 4);
-    }
     if (v->rangeredfrm || use_ic
         || s->h_edge_pos < 13 || v_edge_pos < 23
         || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
@@ -471,11 +557,36 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
 
         srcY -= s->mspel * (1 + (s->linesize << fieldmv));
         /* check emulate edge stride and offset */
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
-                                 s->linesize, s->linesize,
-                                 k, k << fieldmv,
-                                 src_x - s->mspel, src_y - (s->mspel << fieldmv),
-                                 s->h_edge_pos, v_edge_pos);
+        if (v->fcm == ILACE_FRAME) {
+            if (src_y - (s->mspel << fieldmv) & 1) {
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
+                                         2 * s->linesize, 2 * s->linesize,
+                                         k, (k << fieldmv) + 1 >> 1,
+                                         src_x - s->mspel, src_y - (s->mspel << fieldmv) >> 1,
+                                         s->h_edge_pos, v_edge_pos + 1 >> 1);
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, srcY + s->linesize,
+                                         2 * s->linesize, 2 * s->linesize,
+                                         k, (k << fieldmv) >> 1,
+                                         src_x - s->mspel, src_y - (s->mspel << fieldmv) + 1 >> 1,
+                                         s->h_edge_pos, v_edge_pos >> 1);
+            } else {
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
+                                         2 * s->linesize, 2 * s->linesize,
+                                         k, (k << fieldmv) + 1 >> 1,
+                                         src_x - s->mspel, src_y - (s->mspel << fieldmv) >> 1,
+                                         s->h_edge_pos, v_edge_pos >> 1);
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize, srcY + s->linesize,
+                                         2 * s->linesize, 2 * s->linesize,
+                                         k, (k << fieldmv) >> 1,
+                                         src_x - s->mspel, src_y - (s->mspel << fieldmv) + 1 >> 1,
+                                         s->h_edge_pos, v_edge_pos + 1 >> 1);
+            }
+        } else
+            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
+                                     s->linesize, s->linesize,
+                                     k, k,
+                                     src_x - s->mspel, src_y - s->mspel,
+                                     s->h_edge_pos, v_edge_pos);
         srcY = s->sc.edge_emu_buffer;
         /* if we deal with range reduction we need to scale source blocks */
         if (v->rangeredfrm) {
@@ -683,7 +794,10 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
         uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
         // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
         uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
-        uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+        if (v->fcm == ILACE_FRAME)
+            uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
+        else
+            uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
         if (i < 2 ? dir : dir2) {
             srcU = s->next_picture.f->data[1];
             srcV = s->next_picture.f->data[2];
@@ -702,24 +816,56 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
         uvmx_field[i] = (uvmx_field[i] & 3) << 1;
         uvmy_field[i] = (uvmy_field[i] & 3) << 1;
 
-        if (fieldmv) {
-            if (!(uvsrc_y & 1))
-                v_edge_pos = (s->v_edge_pos >> 1) - 1;
-            else
-                uvsrc_y -= (uvsrc_y < 2);
-        }
         if (use_ic
             || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
             || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
             || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
-            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
-                                     s->uvlinesize, s->uvlinesize,
-                                     5, (5 << fieldmv), uvsrc_x, uvsrc_y,
-                                     s->h_edge_pos >> 1, v_edge_pos);
-            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
-                                     s->uvlinesize, s->uvlinesize,
-                                     5, (5 << fieldmv), uvsrc_x, uvsrc_y,
-                                     s->h_edge_pos >> 1, v_edge_pos);
+            if (v->fcm == ILACE_FRAME) {
+                if (uvsrc_y & 1) {
+                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
+                                             2 * s->uvlinesize, 2 * s->uvlinesize,
+                                             5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1,
+                                             s->h_edge_pos >> 1, v_edge_pos + 1 >> 1);
+                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->uvlinesize, srcU + s->uvlinesize,
+                                             2 * s->uvlinesize, 2 * s->uvlinesize,
+                                             5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1,
+                                             s->h_edge_pos >> 1, v_edge_pos >> 1);
+                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
+                                             2 * s->uvlinesize, 2 * s->uvlinesize,
+                                             5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1,
+                                             s->h_edge_pos >> 1, v_edge_pos + 1 >> 1);
+                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + s->uvlinesize, srcV + s->uvlinesize,
+                                             2 * s->uvlinesize, 2 * s->uvlinesize,
+                                             5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1,
+                                             s->h_edge_pos >> 1, v_edge_pos >> 1);
+                } else {
+                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
+                                             2 * s->uvlinesize, 2 * s->uvlinesize,
+                                             5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1,
+                                             s->h_edge_pos >> 1, v_edge_pos >> 1);
+                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->uvlinesize, srcU + s->uvlinesize,
+                                             2 * s->uvlinesize, 2 * s->uvlinesize,
+                                             5, (5 << fieldmv) >> 1, uvsrc_x, uvsrc_y + 1 >> 1,
+                                             s->h_edge_pos >> 1, v_edge_pos + 1 >> 1);
+                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
+                                             2 * s->uvlinesize, 2 * s->uvlinesize,
+                                             5, (5 << fieldmv) + 1 >> 1, uvsrc_x, uvsrc_y >> 1,
+                                             s->h_edge_pos >> 1, v_edge_pos >> 1);
+                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + s->uvlinesize, srcV + s->uvlinesize,
+                                             2 * s->uvlinesize, 2 * s->uvlinesize,
+                                             5, (5 << fieldmv) + 1, uvsrc_x, uvsrc_y + 1 >> 1,
+                                             s->h_edge_pos >> 1, v_edge_pos + 1 >> 1);
+                }
+            } else {
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
+                                         s->uvlinesize, s->uvlinesize,
+                                         5, 5, uvsrc_x, uvsrc_y,
+                                         s->h_edge_pos >> 1, v_edge_pos);
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
+                                         s->uvlinesize, s->uvlinesize,
+                                         5, 5, uvsrc_x, uvsrc_y,
+                                         s->h_edge_pos >> 1, v_edge_pos);
+            }
             srcU = s->sc.edge_emu_buffer;
             srcV = s->sc.edge_emu_buffer + 16;
 
@@ -793,9 +939,14 @@ void ff_vc1_interp_mc(VC1Context *v)
         uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
     } else {
         src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
-        src_y   = av_clip(  src_y, -18, s->avctx->coded_height + 1);
         uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
-        uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
+        if (v->fcm == ILACE_FRAME) {
+            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
+            uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
+        } else {
+            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
+            uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
+        }
     }
 
     srcY += src_y   * s->linesize   + src_x;
@@ -822,22 +973,113 @@ void ff_vc1_interp_mc(VC1Context *v)
         const int k = 17 + s->mspel * 2;
 
         srcY -= s->mspel * (1 + s->linesize);
-        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
-                                 s->linesize, s->linesize,
-                                 k, k,
-                                 src_x - s->mspel, src_y - s->mspel,
-                                 s->h_edge_pos, v_edge_pos);
+        if (v->fcm == ILACE_FRAME) {
+            if (src_y - s->mspel & 1) {
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
+                                         srcY,
+                                         2 * s->linesize,
+                                         2 * s->linesize,
+                                         k,
+                                         k + 1 >> 1,
+                                         src_x - s->mspel,
+                                         src_y - s->mspel >> 1,
+                                         s->h_edge_pos,
+                                         v_edge_pos + 1 >> 1);
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize,
+                                         srcY + s->linesize,
+                                         2 * s->linesize,
+                                         2 * s->linesize,
+                                         k,
+                                         k >> 1,
+                                         src_x - s->mspel,
+                                         src_y - s->mspel + 1 >> 1,
+                                         s->h_edge_pos,
+                                         v_edge_pos >> 1);
+            } else {
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
+                                         srcY,
+                                         2 * s->linesize,
+                                         2 * s->linesize,
+                                         k,
+                                         k + 1 >> 1,
+                                         src_x - s->mspel,
+                                         src_y - s->mspel >> 1,
+                                         s->h_edge_pos,
+                                         v_edge_pos >> 1);
+                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + s->linesize,
+                                         srcY + s->linesize,
+                                         2 * s->linesize,
+                                         2 * s->linesize,
+                                         k,
+                                         k >> 1,
+                                         src_x - s->mspel,
+                                         src_y - s->mspel + 1 >> 1,
+                                         s->h_edge_pos,
+                                         v_edge_pos + 1 >> 1);
+            }
+        } else
+            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
+                                     s->linesize, s->linesize,
+                                     k, k,
+                                     src_x - s->mspel, src_y - s->mspel,
+                                     s->h_edge_pos, v_edge_pos);
         srcY = s->sc.edge_emu_buffer;
-        s->vdsp.emulated_edge_mc(ubuf, srcU,
-                                 s->uvlinesize, s->uvlinesize,
-                                 8 + 1, 8 + 1,
-                                 uvsrc_x, uvsrc_y,
-                                 s->h_edge_pos >> 1, v_edge_pos >> 1);
-        s->vdsp.emulated_edge_mc(vbuf, srcV,
-                                 s->uvlinesize, s->uvlinesize,
-                                 8 + 1, 8 + 1,
-                                 uvsrc_x, uvsrc_y,
-                                 s->h_edge_pos >> 1, v_edge_pos >> 1);
+        if (v->fcm == ILACE_FRAME) {
+            if (uvsrc_y & 1) {
+                s->vdsp.emulated_edge_mc(ubuf, srcU,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 5,
+                                         uvsrc_x, uvsrc_y >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
+                s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 4,
+                                         uvsrc_x, uvsrc_y + 1 >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
+                s->vdsp.emulated_edge_mc(vbuf, srcV,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 5,
+                                         uvsrc_x, uvsrc_y >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
+                s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 4,
+                                         uvsrc_x, uvsrc_y + 1 >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
+            } else {
+                s->vdsp.emulated_edge_mc(ubuf, srcU,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 5,
+                                         uvsrc_x, uvsrc_y >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
+                s->vdsp.emulated_edge_mc(ubuf + s->uvlinesize, srcU + s->uvlinesize,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 4,
+                                         uvsrc_x, uvsrc_y + 1 >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
+                s->vdsp.emulated_edge_mc(vbuf, srcV,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 5,
+                                         uvsrc_x, uvsrc_y >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) >> 1);
+                s->vdsp.emulated_edge_mc(vbuf + s->uvlinesize, srcV + s->uvlinesize,
+                                         2 * s->uvlinesize, 2 * s->uvlinesize,
+                                         8 + 1, 4,
+                                         uvsrc_x, uvsrc_y + 1 >> 1,
+                                         s->h_edge_pos >> 1, (v_edge_pos >> 1) + 1 >> 1);
+            }
+        } else {
+            s->vdsp.emulated_edge_mc(ubuf, srcU,
+                                     s->uvlinesize, s->uvlinesize,
+                                     8 + 1, 8 + 1,
+                                     uvsrc_x, uvsrc_y,
+                                     s->h_edge_pos >> 1, v_edge_pos >> 1);
+            s->vdsp.emulated_edge_mc(vbuf, srcV,
+                                     s->uvlinesize, s->uvlinesize,
+                                     8 + 1, 8 + 1,
+                                     uvsrc_x, uvsrc_y,
+                                     s->h_edge_pos >> 1, v_edge_pos >> 1);
+        }
         srcU = ubuf;
         srcV = vbuf;
         /* if we deal with range reduction we need to scale source blocks */
index fa56b29..4dd5a40 100644 (file)
@@ -7,12 +7,12 @@
 0,          2,          2,        1,  3110400, 0x3b615b79
 0,          3,          3,        1,  3110400, 0x4fbb6f84
 0,          4,          4,        1,  3110400, 0xc1ca8532
-0,          5,          5,        1,  3110400, 0xb6e7d363
-0,          6,          6,        1,  3110400, 0x1beb5c34
-0,          7,          7,        1,  3110400, 0xcb8cb061
-0,          8,          8,        1,  3110400, 0x13ddbd61
-0,          9,          9,        1,  3110400, 0xde8f052f
-0,         10,         10,        1,  3110400, 0x4d4072db
-0,         11,         11,        1,  3110400, 0x4e5d29e3
-0,         12,         12,        1,  3110400, 0x75300531
-0,         13,         13,        1,  3110400, 0x1114285a
+0,          5,          5,        1,  3110400, 0xbdabd2a8
+0,          6,          6,        1,  3110400, 0x66e60c5a
+0,          7,          7,        1,  3110400, 0x8044891c
+0,          8,          8,        1,  3110400, 0x3a4e8992
+0,          9,          9,        1,  3110400, 0xe49fcb23
+0,         10,         10,        1,  3110400, 0xe8e165b6
+0,         11,         11,        1,  3110400, 0x046321b5
+0,         12,         12,        1,  3110400, 0x3cbe5125
+0,         13,         13,        1,  3110400, 0xcb4328e7