LCOV - code coverage report
Current view: top level - libavcodec - vc1_mc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 461 533 86.5 %
Date: 2017-12-15 11:05:35 Functions: 9 11 81.8 %

          Line data    Source code
       1             : /*
       2             :  * VC-1 and WMV3 decoder
       3             :  * Copyright (c) 2011 Mashiat Sarker Shakkhar
       4             :  * Copyright (c) 2006-2007 Konstantin Shishkov
       5             :  * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
       6             :  *
       7             :  * This file is part of FFmpeg.
       8             :  *
       9             :  * FFmpeg is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public
      11             :  * License as published by the Free Software Foundation; either
      12             :  * version 2.1 of the License, or (at your option) any later version.
      13             :  *
      14             :  * FFmpeg is distributed in the hope that it will be useful,
      15             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public
      20             :  * License along with FFmpeg; if not, write to the Free Software
      21             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      22             :  */
      23             : 
      24             : /**
      25             :  * @file
      26             :  * VC-1 and WMV3 block decoding routines
      27             :  */
      28             : 
      29             : #include "avcodec.h"
      30             : #include "h264chroma.h"
      31             : #include "mathops.h"
      32             : #include "mpegvideo.h"
      33             : #include "vc1.h"
      34             : 
      35           0 : static av_always_inline void vc1_scale_luma(uint8_t *srcY,
      36             :                                             int k, int linesize)
      37             : {
      38             :     int i, j;
      39           0 :     for (j = 0; j < k; j++) {
      40           0 :         for (i = 0; i < k; i++)
      41           0 :             srcY[i] = ((srcY[i] - 128) >> 1) + 128;
      42           0 :         srcY += linesize;
      43             :     }
      44           0 : }
      45             : 
      46           0 : static av_always_inline void vc1_scale_chroma(uint8_t *srcU, uint8_t *srcV,
      47             :                                               int k, int uvlinesize)
      48             : {
      49             :     int i, j;
      50           0 :     for (j = 0; j < k; j++) {
      51           0 :         for (i = 0; i < k; i++) {
      52           0 :             srcU[i] = ((srcU[i] - 128) >> 1) + 128;
      53           0 :             srcV[i] = ((srcV[i] - 128) >> 1) + 128;
      54             :         }
      55           0 :         srcU += uvlinesize;
      56           0 :         srcV += uvlinesize;
      57             :     }
      58           0 : }
      59             : 
      60        3813 : static av_always_inline void vc1_lut_scale_luma(uint8_t *srcY,
      61             :                                                 uint8_t *lut1, uint8_t *lut2,
      62             :                                                 int k, int linesize)
      63             : {
      64             :     int i, j;
      65             : 
      66       37708 :     for (j = 0; j < k; j += 2) {
      67      746564 :         for (i = 0; i < k; i++)
      68      708856 :             srcY[i] = lut1[srcY[i]];
      69       37708 :         srcY += linesize;
      70             : 
      71       37708 :         if (j + 1 == k)
      72        3813 :             break;
      73             : 
      74      671148 :         for (i = 0; i < k; i++)
      75      637253 :             srcY[i] = lut2[srcY[i]];
      76       33895 :         srcY += linesize;
      77             :     }
      78        3813 : }
      79             : 
      80        3813 : static av_always_inline void vc1_lut_scale_chroma(uint8_t *srcU, uint8_t *srcV,
      81             :                                                   uint8_t *lut1, uint8_t *lut2,
      82             :                                                   int k, int uvlinesize)
      83             : {
      84             :     int i, j;
      85             : 
      86       19065 :     for (j = 0; j < k; j += 2) {
      87      190650 :         for (i = 0; i < k; i++) {
      88      171585 :             srcU[i] = lut1[srcU[i]];
      89      171585 :             srcV[i] = lut1[srcV[i]];
      90             :         }
      91       19065 :         srcU += uvlinesize;
      92       19065 :         srcV += uvlinesize;
      93             : 
      94       19065 :         if (j + 1 == k)
      95        3813 :             break;
      96             : 
      97      152520 :         for (i = 0; i < k; i++) {
      98      137268 :             srcU[i] = lut2[srcU[i]];
      99      137268 :             srcV[i] = lut2[srcV[i]];
     100             :         }
     101       15252 :         srcU += uvlinesize;
     102       15252 :         srcV += uvlinesize;
     103             :     }
     104        3813 : }
     105             : 
     106             : static const uint8_t popcount4[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
     107             : 
     108       23108 : static av_always_inline int get_luma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty)
     109             : {
     110       23108 :     MpegEncContext *s = &v->s;
     111       69324 :     int idx = v->mv_f[dir][s->block_index[0] + v->blocks_off] |
     112       46216 :              (v->mv_f[dir][s->block_index[1] + v->blocks_off] << 1) |
     113       23108 :              (v->mv_f[dir][s->block_index[2] + v->blocks_off] << 2) |
     114       23108 :              (v->mv_f[dir][s->block_index[3] + v->blocks_off] << 3);
     115             :     static const uint8_t index2[16] = { 0, 0, 0, 0x23, 0, 0x13, 0x03, 0, 0, 0x12, 0x02, 0, 0x01, 0, 0, 0 };
     116       23108 :     int opp_count = popcount4[idx];
     117             : 
     118       23108 :     switch (opp_count) {
     119       16111 :     case 0:
     120             :     case 4:
     121       16111 :         *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
     122       16111 :         *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
     123       16111 :         break;
     124        2829 :     case 1:
     125        2829 :         *tx = mid_pred(s->mv[dir][idx < 2][0], s->mv[dir][1 + (idx < 4)][0], s->mv[dir][2 + (idx < 8)][0]);
     126        2829 :         *ty = mid_pred(s->mv[dir][idx < 2][1], s->mv[dir][1 + (idx < 4)][1], s->mv[dir][2 + (idx < 8)][1]);
     127        2829 :         break;
     128        2560 :     case 3:
     129        2560 :         *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
     130        2560 :         *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
     131        2560 :         break;
     132        1608 :     case 2:
     133        1608 :         *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
     134        1608 :         *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
     135        1608 :         break;
     136             :     }
     137       23108 :     return opp_count;
     138             : }
     139             : 
     140       20967 : static av_always_inline int get_chroma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty)
     141             : {
     142       20967 :     MpegEncContext *s = &v->s;
     143       62901 :     int idx = !v->mb_type[0][s->block_index[0]] |
     144       41934 :              (!v->mb_type[0][s->block_index[1]] << 1) |
     145       20967 :              (!v->mb_type[0][s->block_index[2]] << 2) |
     146       20967 :              (!v->mb_type[0][s->block_index[3]] << 3);
     147             :     static const uint8_t index2[16] = { 0, 0, 0, 0x01, 0, 0x02, 0x12, 0, 0, 0x03, 0x13, 0, 0x23, 0, 0, 0 };
     148       20967 :     int valid_count = popcount4[idx];
     149             : 
     150       20967 :     switch (valid_count) {
     151       16868 :     case 4:
     152       16868 :         *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
     153       16868 :         *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
     154       16868 :         break;
     155        1960 :     case 3:
     156        1960 :         *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
     157        1960 :         *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
     158        1960 :         break;
     159        1114 :     case 2:
     160        1114 :         *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
     161        1114 :         *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
     162        1114 :         break;
     163        1025 :     default:
     164        1025 :         return 0;
     165             :     }
     166       19942 :     return valid_count;
     167             : }
     168             : 
     169             : /** Do motion compensation over 1 macroblock
     170             :  * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
     171             :  */
     172      145326 : void ff_vc1_mc_1mv(VC1Context *v, int dir)
     173             : {
     174      145326 :     MpegEncContext *s = &v->s;
     175      145326 :     H264ChromaContext *h264chroma = &v->h264chroma;
     176             :     uint8_t *srcY, *srcU, *srcV;
     177             :     int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
     178      145326 :     int v_edge_pos = s->v_edge_pos >> v->field_mode;
     179             :     int i;
     180             :     uint8_t (*luty)[256], (*lutuv)[256];
     181             :     int use_ic;
     182             : 
     183      207815 :     if ((!v->field_mode ||
     184      167025 :          (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
     185       88748 :         !v->s.last_picture.f->data[0])
     186           0 :         return;
     187             : 
     188      145326 :     mx = s->mv[dir][0][0];
     189      145326 :     my = s->mv[dir][0][1];
     190             : 
     191             :     // store motion vectors for further use in B-frames
     192      145326 :     if (s->pict_type == AV_PICTURE_TYPE_P) {
     193      410335 :         for (i = 0; i < 4; i++) {
     194      328268 :             s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
     195      328268 :             s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
     196             :         }
     197             :     }
     198             : 
     199      145326 :     uvmx = (mx + ((mx & 3) == 3)) >> 1;
     200      145326 :     uvmy = (my + ((my & 3) == 3)) >> 1;
     201      145326 :     v->luma_mv[s->mb_x][0] = uvmx;
     202      145326 :     v->luma_mv[s->mb_x][1] = uvmy;
     203             : 
     204      207815 :     if (v->field_mode &&
     205       62489 :         v->cur_field_type != v->ref_field_type[dir]) {
     206       35969 :         my   = my   - 2 + 4 * v->cur_field_type;
     207       35969 :         uvmy = uvmy - 2 + 4 * v->cur_field_type;
     208             :     }
     209             : 
     210             :     // fastuvmc shall be ignored for interlaced frame picture
     211      145326 :     if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
     212           0 :         uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
     213           0 :         uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
     214             :     }
     215      145326 :     if (!dir) {
     216      125098 :         if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
     217       24294 :             srcY = s->current_picture.f->data[0];
     218       24294 :             srcU = s->current_picture.f->data[1];
     219       24294 :             srcV = s->current_picture.f->data[2];
     220       24294 :             luty  = v->curr_luty;
     221       24294 :             lutuv = v->curr_lutuv;
     222       24294 :             use_ic = *v->curr_use_ic;
     223             :         } else {
     224      100804 :             srcY = s->last_picture.f->data[0];
     225      100804 :             srcU = s->last_picture.f->data[1];
     226      100804 :             srcV = s->last_picture.f->data[2];
     227      100804 :             luty  = v->last_luty;
     228      100804 :             lutuv = v->last_lutuv;
     229      100804 :             use_ic = v->last_use_ic;
     230             :         }
     231             :     } else {
     232       20228 :         srcY = s->next_picture.f->data[0];
     233       20228 :         srcU = s->next_picture.f->data[1];
     234       20228 :         srcV = s->next_picture.f->data[2];
     235       20228 :         luty  = v->next_luty;
     236       20228 :         lutuv = v->next_lutuv;
     237       20228 :         use_ic = v->next_use_ic;
     238             :     }
     239             : 
     240      145326 :     if (!srcY || !srcU) {
     241           0 :         av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
     242           0 :         return;
     243             :     }
     244             : 
     245      145326 :     src_x   = s->mb_x * 16 + (mx   >> 2);
     246      145326 :     src_y   = s->mb_y * 16 + (my   >> 2);
     247      145326 :     uvsrc_x = s->mb_x *  8 + (uvmx >> 2);
     248      145326 :     uvsrc_y = s->mb_y *  8 + (uvmy >> 2);
     249             : 
     250      145326 :     if (v->profile != PROFILE_ADVANCED) {
     251       26509 :         src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
     252       26509 :         src_y   = av_clip(  src_y, -16, s->mb_height * 16);
     253       26509 :         uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
     254       26509 :         uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
     255             :     } else {
     256      118817 :         src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
     257      118817 :         src_y   = av_clip(  src_y, -18, s->avctx->coded_height + 1);
     258      118817 :         uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
     259      118817 :         uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
     260             :     }
     261             : 
     262      145326 :     srcY += src_y   * s->linesize   + src_x;
     263      145326 :     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
     264      145326 :     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
     265             : 
     266      145326 :     if (v->field_mode && v->ref_field_type[dir]) {
     267       15788 :         srcY += s->current_picture_ptr->f->linesize[0];
     268       15788 :         srcU += s->current_picture_ptr->f->linesize[1];
     269       15788 :         srcV += s->current_picture_ptr->f->linesize[2];
     270             :     }
     271             : 
     272             :     /* for grayscale we should not try to read from unknown area */
     273             :     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) {
     274             :         srcU = s->sc.edge_emu_buffer + 18 * s->linesize;
     275             :         srcV = s->sc.edge_emu_buffer + 18 * s->linesize;
     276             :     }
     277             : 
     278      145326 :     if (v->rangeredfrm || use_ic
     279      141513 :         || s->h_edge_pos < 22 || v_edge_pos < 22
     280      141513 :         || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
     281      136021 :         || (unsigned)(src_y - 1)        > v_edge_pos    - (my&3) - 16 - 3) {
     282       20871 :         uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
     283       20871 :         uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
     284       20871 :         const int k = 17 + s->mspel * 2;
     285             : 
     286       20871 :         srcY -= s->mspel * (1 + s->linesize);
     287       62613 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
     288             :                                  s->linesize, s->linesize,
     289             :                                  k, k,
     290       41742 :                                  src_x - s->mspel, src_y - s->mspel,
     291             :                                  s->h_edge_pos, v_edge_pos);
     292       20871 :         srcY = s->sc.edge_emu_buffer;
     293       41742 :         s->vdsp.emulated_edge_mc(ubuf, srcU,
     294             :                                  s->uvlinesize, s->uvlinesize,
     295             :                                  8 + 1, 8 + 1,
     296             :                                  uvsrc_x, uvsrc_y,
     297       20871 :                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
     298       41742 :         s->vdsp.emulated_edge_mc(vbuf, srcV,
     299             :                                  s->uvlinesize, s->uvlinesize,
     300             :                                  8 + 1, 8 + 1,
     301             :                                  uvsrc_x, uvsrc_y,
     302       20871 :                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
     303       20871 :         srcU = ubuf;
     304       20871 :         srcV = vbuf;
     305             :         /* if we deal with range reduction we need to scale source blocks */
     306       20871 :         if (v->rangeredfrm) {
     307           0 :             vc1_scale_luma(srcY, k, s->linesize);
     308           0 :             vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
     309             :         }
     310             :         /* if we deal with intensity compensation we need to scale source blocks */
     311       20871 :         if (use_ic) {
     312        7626 :             vc1_lut_scale_luma(srcY,
     313        3813 :                                luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)],
     314        3813 :                                luty[v->field_mode ? v->ref_field_type[dir] : ((1 + src_y - s->mspel) & 1)],
     315        3813 :                                k, s->linesize);
     316        7626 :             vc1_lut_scale_chroma(srcU, srcV,
     317        3813 :                                  lutuv[v->field_mode ? v->ref_field_type[dir] : ((0 + uvsrc_y) & 1)],
     318        3813 :                                  lutuv[v->field_mode ? v->ref_field_type[dir] : ((1 + uvsrc_y) & 1)],
     319        3813 :                                  9, s->uvlinesize);
     320             :         }
     321       20871 :         srcY += s->mspel * (1 + s->linesize);
     322             :     }
     323             : 
     324      145326 :     if (s->mspel) {
     325       98958 :         dxy = ((my & 3) << 2) | (mx & 3);
     326       98958 :         v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
     327             :     } else { // hpel mc - always used for luma
     328       46368 :         dxy = (my & 2) | ((mx & 2) >> 1);
     329       46368 :         if (!v->rnd)
     330       16435 :             s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
     331             :         else
     332       29933 :             s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
     333             :     }
     334             : 
     335             :     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
     336             :         return;
     337             :     /* Chroma MC always uses qpel bilinear */
     338      145326 :     uvmx = (uvmx & 3) << 1;
     339      145326 :     uvmy = (uvmy & 3) << 1;
     340      145326 :     if (!v->rnd) {
     341       73237 :         h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
     342       73237 :         h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     343             :     } else {
     344       72089 :         v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
     345       72089 :         v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     346             :     }
     347             : }
     348             : 
     349             : /** Do motion compensation for 4-MV macroblock - luminance block
     350             :  */
     351      257598 : void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
     352             : {
     353      257598 :     MpegEncContext *s = &v->s;
     354             :     uint8_t *srcY;
     355             :     int dxy, mx, my, src_x, src_y;
     356             :     int off;
     357      257598 :     int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
     358      257598 :     int v_edge_pos = s->v_edge_pos >> v->field_mode;
     359             :     uint8_t (*luty)[256];
     360             :     int use_ic;
     361             : 
     362      322630 :     if ((!v->field_mode ||
     363      295058 :          (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
     364      205208 :         !v->s.last_picture.f->data[0])
     365           0 :         return;
     366             : 
     367      257598 :     mx = s->mv[dir][n][0];
     368      257598 :     my = s->mv[dir][n][1];
     369             : 
     370      257598 :     if (!dir) {
     371      200824 :         if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
     372       18181 :             srcY = s->current_picture.f->data[0];
     373       18181 :             luty = v->curr_luty;
     374       18181 :             use_ic = *v->curr_use_ic;
     375             :         } else {
     376      182643 :             srcY = s->last_picture.f->data[0];
     377      182643 :             luty = v->last_luty;
     378      182643 :             use_ic = v->last_use_ic;
     379             :         }
     380             :     } else {
     381       56774 :         srcY = s->next_picture.f->data[0];
     382       56774 :         luty = v->next_luty;
     383       56774 :         use_ic = v->next_use_ic;
     384             :     }
     385             : 
     386      257598 :     if (!srcY) {
     387           0 :         av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
     388           0 :         return;
     389             :     }
     390             : 
     391      257598 :     if (v->field_mode) {
     392       65032 :         if (v->cur_field_type != v->ref_field_type[dir])
     393       32438 :             my = my - 2 + 4 * v->cur_field_type;
     394             :     }
     395             : 
     396      257598 :     if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
     397       13700 :         int opp_count = get_luma_mv(v, 0,
     398        6850 :                                     &s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
     399        6850 :                                     &s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1]);
     400        6850 :         int k, f = opp_count > 2;
     401       34250 :         for (k = 0; k < 4; k++)
     402       27400 :             v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
     403             :     }
     404             : 
     405      257598 :     if (v->fcm == ILACE_FRAME) {  // not sure if needed for other types of picture
     406             :         int qx, qy;
     407      116452 :         int width  = s->avctx->coded_width;
     408      116452 :         int height = s->avctx->coded_height >> 1;
     409      116452 :         if (s->pict_type == AV_PICTURE_TYPE_P) {
     410       26340 :             s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
     411       26340 :             s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
     412             :         }
     413      116452 :         qx = (s->mb_x * 16) + (mx >> 2);
     414      116452 :         qy = (s->mb_y *  8) + (my >> 3);
     415             : 
     416      116452 :         if (qx < -17)
     417         244 :             mx -= 4 * (qx + 17);
     418      116208 :         else if (qx > width)
     419         704 :             mx -= 4 * (qx - width);
     420      116452 :         if (qy < -18)
     421          20 :             my -= 8 * (qy + 18);
     422      116432 :         else if (qy > height + 1)
     423         443 :             my -= 8 * (qy - height - 1);
     424             :     }
     425             : 
     426      257598 :     if ((v->fcm == ILACE_FRAME) && fieldmv)
     427      113636 :         off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
     428             :     else
     429      143962 :         off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
     430             : 
     431      257598 :     src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
     432      257598 :     if (!fieldmv)
     433      143962 :         src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
     434             :     else
     435      113636 :         src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
     436             : 
     437      257598 :     if (v->profile != PROFILE_ADVANCED) {
     438           0 :         src_x = av_clip(src_x, -16, s->mb_width  * 16);
     439           0 :         src_y = av_clip(src_y, -16, s->mb_height * 16);
     440             :     } else {
     441      257598 :         src_x = av_clip(src_x, -17, s->avctx->coded_width);
     442      257598 :         if (v->fcm == ILACE_FRAME) {
     443      116452 :             if (src_y & 1)
     444       72519 :                 src_y = av_clip(src_y, -17, s->avctx->coded_height + 1);
     445             :             else
     446       43933 :                 src_y = av_clip(src_y, -18, s->avctx->coded_height);
     447             :         } else {
     448      141146 :             src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
     449             :         }
     450             :     }
     451             : 
     452      257598 :     srcY += src_y * s->linesize + src_x;
     453      257598 :     if (v->field_mode && v->ref_field_type[dir])
     454       24818 :         srcY += s->current_picture_ptr->f->linesize[0];
     455             : 
     456      257598 :     if (fieldmv) {
     457      113636 :         if (!(src_y & 1))
     458       42387 :             v_edge_pos--;
     459             :         else
     460       71249 :             src_y -= (src_y < 4);
     461             :     }
     462      257598 :     if (v->rangeredfrm || use_ic
     463      257598 :         || s->h_edge_pos < 13 || v_edge_pos < 23
     464      257598 :         || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
     465      251828 :         || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
     466       15715 :         const int k = 9 + s->mspel * 2;
     467             : 
     468       15715 :         srcY -= s->mspel * (1 + (s->linesize << fieldmv));
     469             :         /* check emulate edge stride and offset */
     470       47145 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
     471             :                                  s->linesize, s->linesize,
     472             :                                  k, k << fieldmv,
     473       31430 :                                  src_x - s->mspel, src_y - (s->mspel << fieldmv),
     474             :                                  s->h_edge_pos, v_edge_pos);
     475       15715 :         srcY = s->sc.edge_emu_buffer;
     476             :         /* if we deal with range reduction we need to scale source blocks */
     477       15715 :         if (v->rangeredfrm) {
     478           0 :             vc1_scale_luma(srcY, k, s->linesize << fieldmv);
     479             :         }
     480             :         /* if we deal with intensity compensation we need to scale source blocks */
     481       15715 :         if (use_ic) {
     482           0 :             vc1_lut_scale_luma(srcY,
     483           0 :                                luty[v->field_mode ? v->ref_field_type[dir] : (((0<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
     484           0 :                                luty[v->field_mode ? v->ref_field_type[dir] : (((1<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
     485           0 :                                k, s->linesize << fieldmv);
     486             :         }
     487       15715 :         srcY += s->mspel * (1 + (s->linesize << fieldmv));
     488             :     }
     489             : 
     490      257598 :     if (s->mspel) {
     491      257598 :         dxy = ((my & 3) << 2) | (mx & 3);
     492      257598 :         if (avg)
     493       20328 :             v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
     494             :         else
     495      237270 :             v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
     496             :     } else { // hpel mc - always used for luma
     497           0 :         dxy = (my & 2) | ((mx & 2) >> 1);
     498           0 :         if (!v->rnd)
     499           0 :             s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
     500             :         else
     501           0 :             s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
     502             :     }
     503             : }
     504             : 
     505             : /** Do motion compensation for 4-MV macroblock - both chroma blocks
     506             :  */
     507       37225 : void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir)
     508             : {
     509       37225 :     MpegEncContext *s = &v->s;
     510       37225 :     H264ChromaContext *h264chroma = &v->h264chroma;
     511             :     uint8_t *srcU, *srcV;
     512             :     int uvmx, uvmy, uvsrc_x, uvsrc_y;
     513             :     int16_t tx, ty;
     514             :     int chroma_ref_type;
     515       37225 :     int v_edge_pos = s->v_edge_pos >> v->field_mode;
     516             :     uint8_t (*lutuv)[256];
     517             :     int use_ic;
     518             : 
     519       37225 :     if (!v->field_mode && !v->s.last_picture.f->data[0])
     520        1025 :         return;
     521             :     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
     522             :         return;
     523             : 
     524             :     /* calculate chroma MV vector from four luma MVs */
     525       57167 :     if (!v->field_mode || !v->numref) {
     526       20967 :         int valid_count = get_chroma_mv(v, dir, &tx, &ty);
     527       20967 :         if (!valid_count) {
     528        1025 :             s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
     529        1025 :             s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
     530        1025 :             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
     531        1025 :             return; //no need to do MC for intra blocks
     532             :         }
     533       19942 :         chroma_ref_type = v->ref_field_type[dir];
     534             :     } else {
     535       16258 :         int opp_count = get_luma_mv(v, dir, &tx, &ty);
     536       16258 :         chroma_ref_type = v->cur_field_type ^ (opp_count > 2);
     537             :     }
     538       36200 :     if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f->data[0])
     539           0 :         return;
     540       36200 :     s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
     541       36200 :     s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
     542       36200 :     uvmx = (tx + ((tx & 3) == 3)) >> 1;
     543       36200 :     uvmy = (ty + ((ty & 3) == 3)) >> 1;
     544             : 
     545       36200 :     v->luma_mv[s->mb_x][0] = uvmx;
     546       36200 :     v->luma_mv[s->mb_x][1] = uvmy;
     547             : 
     548       36200 :     if (v->fastuvmc) {
     549           0 :         uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
     550           0 :         uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
     551             :     }
     552             :     // Field conversion bias
     553       36200 :     if (v->cur_field_type != chroma_ref_type)
     554        7493 :         uvmy += 2 - 4 * chroma_ref_type;
     555             : 
     556       36200 :     uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
     557       36200 :     uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
     558             : 
     559       36200 :     if (v->profile != PROFILE_ADVANCED) {
     560           0 :         uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width  * 8);
     561           0 :         uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
     562             :     } else {
     563       36200 :         uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
     564       36200 :         uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
     565             :     }
     566             : 
     567       36200 :     if (!dir) {
     568       31684 :         if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
     569        4366 :             srcU = s->current_picture.f->data[1];
     570        4366 :             srcV = s->current_picture.f->data[2];
     571        4366 :             lutuv = v->curr_lutuv;
     572        4366 :             use_ic = *v->curr_use_ic;
     573             :         } else {
     574       27318 :             srcU = s->last_picture.f->data[1];
     575       27318 :             srcV = s->last_picture.f->data[2];
     576       27318 :             lutuv = v->last_lutuv;
     577       27318 :             use_ic = v->last_use_ic;
     578             :         }
     579             :     } else {
     580        4516 :         srcU = s->next_picture.f->data[1];
     581        4516 :         srcV = s->next_picture.f->data[2];
     582        4516 :         lutuv = v->next_lutuv;
     583        4516 :         use_ic = v->next_use_ic;
     584             :     }
     585             : 
     586       36200 :     if (!srcU) {
     587           0 :         av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
     588           0 :         return;
     589             :     }
     590             : 
     591       36200 :     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
     592       36200 :     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
     593             : 
     594       36200 :     if (v->field_mode) {
     595       16258 :         if (chroma_ref_type) {
     596        6083 :             srcU += s->current_picture_ptr->f->linesize[1];
     597        6083 :             srcV += s->current_picture_ptr->f->linesize[2];
     598             :         }
     599             :     }
     600             : 
     601       36200 :     if (v->rangeredfrm || use_ic
     602       36200 :         || s->h_edge_pos < 18 || v_edge_pos < 18
     603       36200 :         || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
     604       35332 :         || (unsigned)uvsrc_y > (v_edge_pos    >> 1) - 9) {
     605        5486 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
     606             :                                  s->uvlinesize, s->uvlinesize,
     607             :                                  8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
     608        2743 :                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
     609        5486 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
     610             :                                  s->uvlinesize, s->uvlinesize,
     611             :                                  8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
     612        2743 :                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
     613        2743 :         srcU = s->sc.edge_emu_buffer;
     614        2743 :         srcV = s->sc.edge_emu_buffer + 16;
     615             : 
     616             :         /* if we deal with range reduction we need to scale source blocks */
     617        2743 :         if (v->rangeredfrm) {
     618           0 :             vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
     619             :         }
     620             :         /* if we deal with intensity compensation we need to scale source blocks */
     621        2743 :         if (use_ic) {
     622           0 :             vc1_lut_scale_chroma(srcU, srcV,
     623           0 :                                  lutuv[v->field_mode ? chroma_ref_type : ((0 + uvsrc_y) & 1)],
     624           0 :                                  lutuv[v->field_mode ? chroma_ref_type : ((1 + uvsrc_y) & 1)],
     625           0 :                                  9, s->uvlinesize);
     626             :         }
     627             :     }
     628             : 
     629             :     /* Chroma MC always uses qpel bilinear */
     630       36200 :     uvmx = (uvmx & 3) << 1;
     631       36200 :     uvmy = (uvmy & 3) << 1;
     632       36200 :     if (!v->rnd) {
     633       19496 :         h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
     634       19496 :         h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     635             :     } else {
     636       16704 :         v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
     637       16704 :         v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     638             :     }
     639             : }
     640             : 
     641             : /** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
     642             :  */
     643       29113 : void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
     644             : {
     645       29113 :     MpegEncContext *s = &v->s;
     646       29113 :     H264ChromaContext *h264chroma = &v->h264chroma;
     647             :     uint8_t *srcU, *srcV;
     648             :     int uvsrc_x, uvsrc_y;
     649             :     int uvmx_field[4], uvmy_field[4];
     650             :     int i, off, tx, ty;
     651       29113 :     int fieldmv = v->blk_mv_type[s->block_index[0]];
     652             :     static const uint8_t s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
     653       29113 :     int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
     654       29113 :     int v_edge_pos = s->v_edge_pos >> 1;
     655             :     int use_ic;
     656             :     uint8_t (*lutuv)[256];
     657             : 
     658             :     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
     659           0 :         return;
     660             : 
     661      145565 :     for (i = 0; i < 4; i++) {
     662      116452 :         int d = i < 2 ? dir: dir2;
     663      116452 :         tx = s->mv[d][i][0];
     664      116452 :         uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
     665      116452 :         ty = s->mv[d][i][1];
     666      116452 :         if (fieldmv)
     667      113636 :             uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
     668             :         else
     669        2816 :             uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
     670             :     }
     671             : 
     672      145565 :     for (i = 0; i < 4; i++) {
     673      116452 :         off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
     674      116452 :         uvsrc_x = s->mb_x * 8 +  (i & 1) * 4           + (uvmx_field[i] >> 2);
     675      116452 :         uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
     676             :         // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
     677      116452 :         uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
     678      116452 :         uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
     679      116452 :         if (i < 2 ? dir : dir2) {
     680       38710 :             srcU = s->next_picture.f->data[1];
     681       38710 :             srcV = s->next_picture.f->data[2];
     682       38710 :             lutuv  = v->next_lutuv;
     683       38710 :             use_ic = v->next_use_ic;
     684             :         } else {
     685       77742 :             srcU = s->last_picture.f->data[1];
     686       77742 :             srcV = s->last_picture.f->data[2];
     687       77742 :             lutuv  = v->last_lutuv;
     688       77742 :             use_ic = v->last_use_ic;
     689             :         }
     690      116452 :         if (!srcU)
     691           0 :             return;
     692      116452 :         srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
     693      116452 :         srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
     694      116452 :         uvmx_field[i] = (uvmx_field[i] & 3) << 1;
     695      116452 :         uvmy_field[i] = (uvmy_field[i] & 3) << 1;
     696             : 
     697      116452 :         if (fieldmv) {
     698      113636 :             if (!(uvsrc_y & 1))
     699       42866 :                 v_edge_pos = (s->v_edge_pos >> 1) - 1;
     700             :             else
     701       70770 :                 uvsrc_y -= (uvsrc_y < 2);
     702             :         }
     703      116452 :         if (use_ic
     704      116452 :             || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
     705      116452 :             || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
     706      113912 :             || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
     707       11090 :             s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcU,
     708             :                                      s->uvlinesize, s->uvlinesize,
     709             :                                      5, (5 << fieldmv), uvsrc_x, uvsrc_y,
     710        5545 :                                      s->h_edge_pos >> 1, v_edge_pos);
     711       11090 :             s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, srcV,
     712             :                                      s->uvlinesize, s->uvlinesize,
     713             :                                      5, (5 << fieldmv), uvsrc_x, uvsrc_y,
     714        5545 :                                      s->h_edge_pos >> 1, v_edge_pos);
     715        5545 :             srcU = s->sc.edge_emu_buffer;
     716        5545 :             srcV = s->sc.edge_emu_buffer + 16;
     717             : 
     718             :             /* if we deal with intensity compensation we need to scale source blocks */
     719        5545 :             if (use_ic) {
     720           0 :                 vc1_lut_scale_chroma(srcU, srcV,
     721           0 :                                      lutuv[(uvsrc_y + (0 << fieldmv)) & 1],
     722           0 :                                      lutuv[(uvsrc_y + (1 << fieldmv)) & 1],
     723           0 :                                      5, s->uvlinesize << fieldmv);
     724             :             }
     725             :         }
     726      116452 :         if (avg) {
     727       20328 :             if (!v->rnd) {
     728       10832 :                 h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
     729       10832 :                 h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
     730             :             } else {
     731        9496 :                 v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
     732        9496 :                 v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
     733             :             }
     734             :         } else {
     735       96124 :             if (!v->rnd) {
     736       53028 :                 h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
     737       53028 :                 h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
     738             :             } else {
     739       43096 :                 v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
     740       43096 :                 v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
     741             :             }
     742             :         }
     743             :     }
     744             : }
     745             : 
     746             : /** Motion compensation for direct or interpolated blocks in B-frames
     747             :  */
     748       23100 : void ff_vc1_interp_mc(VC1Context *v)
     749             : {
     750       23100 :     MpegEncContext *s = &v->s;
     751       23100 :     H264ChromaContext *h264chroma = &v->h264chroma;
     752             :     uint8_t *srcY, *srcU, *srcV;
     753             :     int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
     754       23100 :     int v_edge_pos = s->v_edge_pos >> v->field_mode;
     755       23100 :     int use_ic = v->next_use_ic;
     756             : 
     757       23100 :     if (!v->field_mode && !v->s.next_picture.f->data[0])
     758           0 :         return;
     759             : 
     760       23100 :     mx   = s->mv[1][0][0];
     761       23100 :     my   = s->mv[1][0][1];
     762       23100 :     uvmx = (mx + ((mx & 3) == 3)) >> 1;
     763       23100 :     uvmy = (my + ((my & 3) == 3)) >> 1;
     764       23100 :     if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) {
     765        5223 :         my   = my   - 2 + 4 * v->cur_field_type;
     766        5223 :         uvmy = uvmy - 2 + 4 * v->cur_field_type;
     767             :     }
     768       23100 :     if (v->fastuvmc) {
     769           0 :         uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
     770           0 :         uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
     771             :     }
     772       23100 :     srcY = s->next_picture.f->data[0];
     773       23100 :     srcU = s->next_picture.f->data[1];
     774       23100 :     srcV = s->next_picture.f->data[2];
     775             : 
     776       23100 :     src_x   = s->mb_x * 16 + (mx   >> 2);
     777       23100 :     src_y   = s->mb_y * 16 + (my   >> 2);
     778       23100 :     uvsrc_x = s->mb_x *  8 + (uvmx >> 2);
     779       23100 :     uvsrc_y = s->mb_y *  8 + (uvmy >> 2);
     780             : 
     781       23100 :     if (v->profile != PROFILE_ADVANCED) {
     782           0 :         src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
     783           0 :         src_y   = av_clip(  src_y, -16, s->mb_height * 16);
     784           0 :         uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
     785           0 :         uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
     786             :     } else {
     787       23100 :         src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
     788       23100 :         src_y   = av_clip(  src_y, -18, s->avctx->coded_height + 1);
     789       23100 :         uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
     790       23100 :         uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
     791             :     }
     792             : 
     793       23100 :     srcY += src_y   * s->linesize   + src_x;
     794       23100 :     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
     795       23100 :     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
     796             : 
     797       23100 :     if (v->field_mode && v->ref_field_type[1]) {
     798        4716 :         srcY += s->current_picture_ptr->f->linesize[0];
     799        4716 :         srcU += s->current_picture_ptr->f->linesize[1];
     800        4716 :         srcV += s->current_picture_ptr->f->linesize[2];
     801             :     }
     802             : 
     803             :     /* for grayscale we should not try to read from unknown area */
     804             :     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) {
     805             :         srcU = s->sc.edge_emu_buffer + 18 * s->linesize;
     806             :         srcV = s->sc.edge_emu_buffer + 18 * s->linesize;
     807             :     }
     808             : 
     809       23100 :     if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
     810       23100 :         || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
     811       22160 :         || (unsigned)(src_y - 1) > v_edge_pos    - (my & 3) - 16 - 3) {
     812        3142 :         uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
     813        3142 :         uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
     814        3142 :         const int k = 17 + s->mspel * 2;
     815             : 
     816        3142 :         srcY -= s->mspel * (1 + s->linesize);
     817        9426 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
     818             :                                  s->linesize, s->linesize,
     819             :                                  k, k,
     820        6284 :                                  src_x - s->mspel, src_y - s->mspel,
     821             :                                  s->h_edge_pos, v_edge_pos);
     822        3142 :         srcY = s->sc.edge_emu_buffer;
     823        6284 :         s->vdsp.emulated_edge_mc(ubuf, srcU,
     824             :                                  s->uvlinesize, s->uvlinesize,
     825             :                                  8 + 1, 8 + 1,
     826             :                                  uvsrc_x, uvsrc_y,
     827        3142 :                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
     828        6284 :         s->vdsp.emulated_edge_mc(vbuf, srcV,
     829             :                                  s->uvlinesize, s->uvlinesize,
     830             :                                  8 + 1, 8 + 1,
     831             :                                  uvsrc_x, uvsrc_y,
     832        3142 :                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
     833        3142 :         srcU = ubuf;
     834        3142 :         srcV = vbuf;
     835             :         /* if we deal with range reduction we need to scale source blocks */
     836        3142 :         if (v->rangeredfrm) {
     837           0 :             vc1_scale_luma(srcY, k, s->linesize);
     838           0 :             vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
     839             :         }
     840             : 
     841        3142 :         if (use_ic) {
     842           0 :             uint8_t (*luty )[256] = v->next_luty;
     843           0 :             uint8_t (*lutuv)[256] = v->next_lutuv;
     844           0 :             vc1_lut_scale_luma(srcY,
     845           0 :                                luty[v->field_mode ? v->ref_field_type[1] : ((0+src_y - s->mspel) & 1)],
     846           0 :                                luty[v->field_mode ? v->ref_field_type[1] : ((1+src_y - s->mspel) & 1)],
     847           0 :                                k, s->linesize);
     848           0 :             vc1_lut_scale_chroma(srcU, srcV,
     849           0 :                                  lutuv[v->field_mode ? v->ref_field_type[1] : ((0+uvsrc_y) & 1)],
     850           0 :                                  lutuv[v->field_mode ? v->ref_field_type[1] : ((1+uvsrc_y) & 1)],
     851           0 :                                  9, s->uvlinesize);
     852             :         }
     853        3142 :         srcY += s->mspel * (1 + s->linesize);
     854             :     }
     855             : 
     856       23100 :     if (s->mspel) {
     857       16451 :         dxy = ((my & 3) << 2) | (mx & 3);
     858       16451 :         v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
     859             :     } else { // hpel mc
     860        6649 :         dxy = (my & 2) | ((mx & 2) >> 1);
     861             : 
     862        6649 :         if (!v->rnd)
     863        3673 :             s->hdsp.avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
     864             :         else
     865        2976 :             s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0], srcY, s->linesize, 16);
     866             :     }
     867             : 
     868             :     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
     869             :         return;
     870             :     /* Chroma MC always uses qpel bilinear */
     871       23100 :     uvmx = (uvmx & 3) << 1;
     872       23100 :     uvmy = (uvmy & 3) << 1;
     873       23100 :     if (!v->rnd) {
     874       15141 :         h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
     875       15141 :         h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     876             :     } else {
     877        7959 :         v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
     878        7959 :         v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     879             :     }
     880             : }

Generated by: LCOV version 1.13