LCOV - code coverage report
Current view: top level - libavcodec - mpegvideo_motion.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 370 497 74.4 %
Date: 2018-05-20 11:54:08 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2000,2001 Fabrice Bellard
       3             :  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
       4             :  *
       5             :  * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
       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             : #include <string.h>
      25             : 
      26             : #include "libavutil/avassert.h"
      27             : #include "libavutil/internal.h"
      28             : #include "avcodec.h"
      29             : #include "h261.h"
      30             : #include "mpegutils.h"
      31             : #include "mpegvideo.h"
      32             : #include "mjpegenc.h"
      33             : #include "msmpeg4.h"
      34             : #include "qpeldsp.h"
      35             : #include "wmv2.h"
      36             : #include <limits.h>
      37             : 
      38           0 : static void gmc1_motion(MpegEncContext *s,
      39             :                         uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
      40             :                         uint8_t **ref_picture)
      41             : {
      42             :     uint8_t *ptr;
      43             :     int src_x, src_y, motion_x, motion_y;
      44             :     ptrdiff_t offset, linesize, uvlinesize;
      45           0 :     int emu = 0;
      46             : 
      47           0 :     motion_x   = s->sprite_offset[0][0];
      48           0 :     motion_y   = s->sprite_offset[0][1];
      49           0 :     src_x      = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));
      50           0 :     src_y      = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));
      51           0 :     motion_x *= 1 << (3 - s->sprite_warping_accuracy);
      52           0 :     motion_y *= 1 << (3 - s->sprite_warping_accuracy);
      53           0 :     src_x      = av_clip(src_x, -16, s->width);
      54           0 :     if (src_x == s->width)
      55           0 :         motion_x = 0;
      56           0 :     src_y = av_clip(src_y, -16, s->height);
      57           0 :     if (src_y == s->height)
      58           0 :         motion_y = 0;
      59             : 
      60           0 :     linesize   = s->linesize;
      61           0 :     uvlinesize = s->uvlinesize;
      62             : 
      63           0 :     ptr = ref_picture[0] + src_y * linesize + src_x;
      64             : 
      65           0 :     if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||
      66           0 :         (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {
      67           0 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
      68             :                                  linesize, linesize,
      69             :                                  17, 17,
      70             :                                  src_x, src_y,
      71             :                                  s->h_edge_pos, s->v_edge_pos);
      72           0 :         ptr = s->sc.edge_emu_buffer;
      73             :     }
      74             : 
      75           0 :     if ((motion_x | motion_y) & 7) {
      76           0 :         s->mdsp.gmc1(dest_y, ptr, linesize, 16,
      77           0 :                      motion_x & 15, motion_y & 15, 128 - s->no_rounding);
      78           0 :         s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,
      79           0 :                      motion_x & 15, motion_y & 15, 128 - s->no_rounding);
      80             :     } else {
      81             :         int dxy;
      82             : 
      83           0 :         dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);
      84           0 :         if (s->no_rounding) {
      85           0 :             s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
      86             :         } else {
      87           0 :             s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
      88             :         }
      89             :     }
      90             : 
      91             :     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
      92             :         return;
      93             : 
      94           0 :     motion_x   = s->sprite_offset[1][0];
      95           0 :     motion_y   = s->sprite_offset[1][1];
      96           0 :     src_x      = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));
      97           0 :     src_y      = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));
      98           0 :     motion_x  *= 1 << (3 - s->sprite_warping_accuracy);
      99           0 :     motion_y  *= 1 << (3 - s->sprite_warping_accuracy);
     100           0 :     src_x      = av_clip(src_x, -8, s->width >> 1);
     101           0 :     if (src_x == s->width >> 1)
     102           0 :         motion_x = 0;
     103           0 :     src_y = av_clip(src_y, -8, s->height >> 1);
     104           0 :     if (src_y == s->height >> 1)
     105           0 :         motion_y = 0;
     106             : 
     107           0 :     offset = (src_y * uvlinesize) + src_x;
     108           0 :     ptr    = ref_picture[1] + offset;
     109           0 :     if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||
     110           0 :         (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {
     111           0 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
     112             :                                  uvlinesize, uvlinesize,
     113             :                                  9, 9,
     114             :                                  src_x, src_y,
     115           0 :                                  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
     116           0 :         ptr = s->sc.edge_emu_buffer;
     117           0 :         emu = 1;
     118             :     }
     119           0 :     s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8,
     120           0 :                  motion_x & 15, motion_y & 15, 128 - s->no_rounding);
     121             : 
     122           0 :     ptr = ref_picture[2] + offset;
     123           0 :     if (emu) {
     124           0 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
     125             :                                  uvlinesize, uvlinesize,
     126             :                                  9, 9,
     127             :                                  src_x, src_y,
     128           0 :                                  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
     129           0 :         ptr = s->sc.edge_emu_buffer;
     130             :     }
     131           0 :     s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8,
     132           0 :                  motion_x & 15, motion_y & 15, 128 - s->no_rounding);
     133             : }
     134             : 
     135           0 : static void gmc_motion(MpegEncContext *s,
     136             :                        uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
     137             :                        uint8_t **ref_picture)
     138             : {
     139             :     uint8_t *ptr;
     140             :     int linesize, uvlinesize;
     141           0 :     const int a = s->sprite_warping_accuracy;
     142             :     int ox, oy;
     143             : 
     144           0 :     linesize   = s->linesize;
     145           0 :     uvlinesize = s->uvlinesize;
     146             : 
     147           0 :     ptr = ref_picture[0];
     148             : 
     149           0 :     ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +
     150           0 :          s->sprite_delta[0][1] * s->mb_y * 16;
     151           0 :     oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +
     152           0 :          s->sprite_delta[1][1] * s->mb_y * 16;
     153             : 
     154           0 :     s->mdsp.gmc(dest_y, ptr, linesize, 16,
     155             :                 ox, oy,
     156             :                 s->sprite_delta[0][0], s->sprite_delta[0][1],
     157             :                 s->sprite_delta[1][0], s->sprite_delta[1][1],
     158           0 :                 a + 1, (1 << (2 * a + 1)) - s->no_rounding,
     159             :                 s->h_edge_pos, s->v_edge_pos);
     160           0 :     s->mdsp.gmc(dest_y + 8, ptr, linesize, 16,
     161           0 :                 ox + s->sprite_delta[0][0] * 8,
     162           0 :                 oy + s->sprite_delta[1][0] * 8,
     163             :                 s->sprite_delta[0][0], s->sprite_delta[0][1],
     164             :                 s->sprite_delta[1][0], s->sprite_delta[1][1],
     165           0 :                 a + 1, (1 << (2 * a + 1)) - s->no_rounding,
     166             :                 s->h_edge_pos, s->v_edge_pos);
     167             : 
     168             :     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
     169             :         return;
     170             : 
     171           0 :     ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +
     172           0 :          s->sprite_delta[0][1] * s->mb_y * 8;
     173           0 :     oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +
     174           0 :          s->sprite_delta[1][1] * s->mb_y * 8;
     175             : 
     176           0 :     ptr = ref_picture[1];
     177           0 :     s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8,
     178             :                 ox, oy,
     179             :                 s->sprite_delta[0][0], s->sprite_delta[0][1],
     180             :                 s->sprite_delta[1][0], s->sprite_delta[1][1],
     181           0 :                 a + 1, (1 << (2 * a + 1)) - s->no_rounding,
     182           0 :                 (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
     183             : 
     184           0 :     ptr = ref_picture[2];
     185           0 :     s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8,
     186             :                 ox, oy,
     187             :                 s->sprite_delta[0][0], s->sprite_delta[0][1],
     188             :                 s->sprite_delta[1][0], s->sprite_delta[1][1],
     189           0 :                 a + 1, (1 << (2 * a + 1)) - s->no_rounding,
     190           0 :                 (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
     191             : }
     192             : 
     193     2634960 : static inline int hpel_motion(MpegEncContext *s,
     194             :                               uint8_t *dest, uint8_t *src,
     195             :                               int src_x, int src_y,
     196             :                               op_pixels_func *pix_op,
     197             :                               int motion_x, int motion_y)
     198             : {
     199     2634960 :     int dxy = 0;
     200     2634960 :     int emu = 0;
     201             : 
     202     2634960 :     src_x += motion_x >> 1;
     203     2634960 :     src_y += motion_y >> 1;
     204             : 
     205             :     /* WARNING: do no forget half pels */
     206     2634960 :     src_x = av_clip(src_x, -16, s->width); // FIXME unneeded for emu?
     207     2634960 :     if (src_x != s->width)
     208     2633055 :         dxy |= motion_x & 1;
     209     2634960 :     src_y = av_clip(src_y, -16, s->height);
     210     2634960 :     if (src_y != s->height)
     211     2632627 :         dxy |= (motion_y & 1) << 1;
     212     2634960 :     src += src_y * s->linesize + src_x;
     213             : 
     214     5227133 :         if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 7, 0) ||
     215     2592173 :             (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 1) - 7, 0)) {
     216       88908 :             s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src,
     217             :                                      s->linesize, s->linesize,
     218             :                                      9, 9,
     219             :                                      src_x, src_y,
     220             :                                      s->h_edge_pos, s->v_edge_pos);
     221       88908 :             src = s->sc.edge_emu_buffer;
     222       88908 :             emu = 1;
     223             :         }
     224     2634960 :     pix_op[dxy](dest, src, s->linesize, 8);
     225     2634960 :     return emu;
     226             : }
     227             : 
     228             : static av_always_inline
     229     7968378 : void mpeg_motion_internal(MpegEncContext *s,
     230             :                           uint8_t *dest_y,
     231             :                           uint8_t *dest_cb,
     232             :                           uint8_t *dest_cr,
     233             :                           int field_based,
     234             :                           int bottom_field,
     235             :                           int field_select,
     236             :                           uint8_t **ref_picture,
     237             :                           op_pixels_func (*pix_op)[4],
     238             :                           int motion_x,
     239             :                           int motion_y,
     240             :                           int h,
     241             :                           int is_mpeg12,
     242             :                           int is_16x8,
     243             :                           int mb_y)
     244             : {
     245             :     uint8_t *ptr_y, *ptr_cb, *ptr_cr;
     246             :     int dxy, uvdxy, mx, my, src_x, src_y,
     247             :         uvsrc_x, uvsrc_y, v_edge_pos, block_y_half;
     248             :     ptrdiff_t uvlinesize, linesize;
     249             : 
     250     7968378 :     v_edge_pos = s->v_edge_pos >> field_based;
     251     7968378 :     linesize   = s->current_picture.f->linesize[0] << field_based;
     252     7968378 :     uvlinesize = s->current_picture.f->linesize[1] << field_based;
     253     7968378 :     block_y_half = (field_based | is_16x8);
     254             : 
     255     7968378 :     dxy   = ((motion_y & 1) << 1) | (motion_x & 1);
     256     7968378 :     src_x = s->mb_x * 16 + (motion_x >> 1);
     257     7968378 :     src_y = (mb_y << (4 - block_y_half)) + (motion_y >> 1);
     258             : 
     259     7968378 :     if (!is_mpeg12 && s->out_format == FMT_H263) {
     260     7516026 :         if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) {
     261           0 :             mx      = (motion_x >> 1) | (motion_x & 1);
     262           0 :             my      = motion_y >> 1;
     263           0 :             uvdxy   = ((my & 1) << 1) | (mx & 1);
     264           0 :             uvsrc_x = s->mb_x * 8 + (mx >> 1);
     265           0 :             uvsrc_y = (mb_y << (3 - block_y_half)) + (my >> 1);
     266             :         } else {
     267     3758013 :             uvdxy   = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
     268     3758013 :             uvsrc_x = src_x >> 1;
     269     3758013 :             uvsrc_y = src_y >> 1;
     270             :         }
     271             :     // Even chroma mv's are full pel in H261
     272     4210365 :     } else if (!is_mpeg12 && s->out_format == FMT_H261) {
     273      205957 :         mx      = motion_x / 4;
     274      205957 :         my      = motion_y / 4;
     275      205957 :         uvdxy   = 0;
     276      205957 :         uvsrc_x = s->mb_x * 8 + mx;
     277      205957 :         uvsrc_y = mb_y * 8 + my;
     278             :     } else {
     279     4004408 :         if (s->chroma_y_shift) {
     280     3328912 :             mx      = motion_x / 2;
     281     3328912 :             my      = motion_y / 2;
     282     3328912 :             uvdxy   = ((my & 1) << 1) | (mx & 1);
     283     3328912 :             uvsrc_x = s->mb_x * 8 + (mx >> 1);
     284     3328912 :             uvsrc_y = (mb_y << (3 - block_y_half)) + (my >> 1);
     285             :         } else {
     286      675496 :             if (s->chroma_x_shift) {
     287             :                 // Chroma422
     288      675496 :                 mx      = motion_x / 2;
     289      675496 :                 uvdxy   = ((motion_y & 1) << 1) | (mx & 1);
     290      675496 :                 uvsrc_x = s->mb_x * 8 + (mx >> 1);
     291      675496 :                 uvsrc_y = src_y;
     292             :             } else {
     293             :                 // Chroma444
     294           0 :                 uvdxy   = dxy;
     295           0 :                 uvsrc_x = src_x;
     296           0 :                 uvsrc_y = src_y;
     297             :             }
     298             :         }
     299             :     }
     300             : 
     301     7968378 :     ptr_y  = ref_picture[0] + src_y * linesize + src_x;
     302     7968378 :     ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
     303     7968378 :     ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
     304             : 
     305    15799722 :     if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 15   , 0) ||
     306     7831344 :         (unsigned)src_y >= FFMAX(   v_edge_pos - (motion_y & 1) - h + 1, 0)) {
     307      573974 :         if (is_mpeg12 ||
     308      573974 :             s->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
     309      286987 :             s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
     310           0 :             av_log(s->avctx, AV_LOG_DEBUG,
     311             :                    "MPEG motion vector out of boundary (%d %d)\n", src_x,
     312             :                    src_y);
     313           0 :             return;
     314             :         }
     315      286987 :         src_y = (unsigned)src_y << field_based;
     316      286987 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
     317             :                                  s->linesize, s->linesize,
     318             :                                  17, 17 + field_based,
     319             :                                  src_x, src_y,
     320             :                                  s->h_edge_pos, s->v_edge_pos);
     321      286987 :         ptr_y = s->sc.edge_emu_buffer;
     322             :         if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
     323      286987 :             uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
     324      286987 :             uint8_t *vbuf = ubuf + 10 * s->uvlinesize;
     325      286987 :             if (s->workaround_bugs & FF_BUG_IEDGE)
     326           0 :                 vbuf -= s->uvlinesize;
     327      286987 :             uvsrc_y = (unsigned)uvsrc_y << field_based;
     328      860961 :             s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
     329             :                                      s->uvlinesize, s->uvlinesize,
     330             :                                      9, 9 + field_based,
     331             :                                      uvsrc_x, uvsrc_y,
     332      573974 :                                      s->h_edge_pos >> 1, s->v_edge_pos >> 1);
     333      860961 :             s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
     334             :                                      s->uvlinesize, s->uvlinesize,
     335             :                                      9, 9 + field_based,
     336             :                                      uvsrc_x, uvsrc_y,
     337      573974 :                                      s->h_edge_pos >> 1, s->v_edge_pos >> 1);
     338      286987 :             ptr_cb = ubuf;
     339      286987 :             ptr_cr = vbuf;
     340             :         }
     341             :     }
     342             : 
     343             :     /* FIXME use this for field pix too instead of the obnoxious hack which
     344             :      * changes picture.data */
     345     7968378 :     if (bottom_field) {
     346      221989 :         dest_y  += s->linesize;
     347      221989 :         dest_cb += s->uvlinesize;
     348      221989 :         dest_cr += s->uvlinesize;
     349             :     }
     350             : 
     351     7968378 :     if (field_select) {
     352      591565 :         ptr_y  += s->linesize;
     353      591565 :         ptr_cb += s->uvlinesize;
     354      591565 :         ptr_cr += s->uvlinesize;
     355             :     }
     356             : 
     357     7968378 :     pix_op[0][dxy](dest_y, ptr_y, linesize, h);
     358             : 
     359             :     if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
     360    15936756 :         pix_op[s->chroma_x_shift][uvdxy]
     361     7968378 :             (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
     362    15936756 :         pix_op[s->chroma_x_shift][uvdxy]
     363     7968378 :             (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
     364             :     }
     365    11932348 :     if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&
     366     3963970 :         s->out_format == FMT_H261) {
     367      205957 :         ff_h261_loop_filter(s);
     368             :     }
     369             : }
     370             : /* apply one mpeg motion vector to the three components */
     371     7524400 : static void mpeg_motion(MpegEncContext *s,
     372             :                         uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
     373             :                         int field_select, uint8_t **ref_picture,
     374             :                         op_pixels_func (*pix_op)[4],
     375             :                         int motion_x, int motion_y, int h, int is_16x8, int mb_y)
     376             : {
     377             : #if !CONFIG_SMALL
     378     7524400 :     if (s->out_format == FMT_MPEG1)
     379     3560430 :         mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
     380             :                              field_select, ref_picture, pix_op,
     381             :                              motion_x, motion_y, h, 1, is_16x8, mb_y);
     382             :     else
     383             : #endif
     384     3963970 :         mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
     385             :                              field_select, ref_picture, pix_op,
     386             :                              motion_x, motion_y, h, 0, is_16x8, mb_y);
     387     7524400 : }
     388             : 
     389      443978 : static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y,
     390             :                               uint8_t *dest_cb, uint8_t *dest_cr,
     391             :                               int bottom_field, int field_select,
     392             :                               uint8_t **ref_picture,
     393             :                               op_pixels_func (*pix_op)[4],
     394             :                               int motion_x, int motion_y, int h, int mb_y)
     395             : {
     396             : #if !CONFIG_SMALL
     397      443978 :     if (s->out_format == FMT_MPEG1)
     398      443978 :         mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
     399             :                              bottom_field, field_select, ref_picture, pix_op,
     400             :                              motion_x, motion_y, h, 1, 0, mb_y);
     401             :     else
     402             : #endif
     403           0 :         mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
     404             :                              bottom_field, field_select, ref_picture, pix_op,
     405             :                              motion_x, motion_y, h, 0, 0, mb_y);
     406      443978 : }
     407             : 
     408             : // FIXME: SIMDify, avg variant, 16x16 version
     409      412968 : static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride)
     410             : {
     411             :     int x;
     412      412968 :     uint8_t *const top    = src[1];
     413      412968 :     uint8_t *const left   = src[2];
     414      412968 :     uint8_t *const mid    = src[0];
     415      412968 :     uint8_t *const right  = src[3];
     416      412968 :     uint8_t *const bottom = src[4];
     417             : #define OBMC_FILTER(x, t, l, m, r, b)\
     418             :     dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3
     419             : #define OBMC_FILTER4(x, t, l, m, r, b)\
     420             :     OBMC_FILTER(x         , t, l, m, r, b);\
     421             :     OBMC_FILTER(x+1       , t, l, m, r, b);\
     422             :     OBMC_FILTER(x  +stride, t, l, m, r, b);\
     423             :     OBMC_FILTER(x+1+stride, t, l, m, r, b);
     424             : 
     425      412968 :     x = 0;
     426      412968 :     OBMC_FILTER (x    , 2, 2, 4, 0, 0);
     427      412968 :     OBMC_FILTER (x + 1, 2, 1, 5, 0, 0);
     428      412968 :     OBMC_FILTER4(x + 2, 2, 1, 5, 0, 0);
     429      412968 :     OBMC_FILTER4(x + 4, 2, 0, 5, 1, 0);
     430      412968 :     OBMC_FILTER (x + 6, 2, 0, 5, 1, 0);
     431      412968 :     OBMC_FILTER (x + 7, 2, 0, 4, 2, 0);
     432      412968 :     x += stride;
     433      412968 :     OBMC_FILTER (x    , 1, 2, 5, 0, 0);
     434      412968 :     OBMC_FILTER (x + 1, 1, 2, 5, 0, 0);
     435      412968 :     OBMC_FILTER (x + 6, 1, 0, 5, 2, 0);
     436      412968 :     OBMC_FILTER (x + 7, 1, 0, 5, 2, 0);
     437      412968 :     x += stride;
     438      412968 :     OBMC_FILTER4(x    , 1, 2, 5, 0, 0);
     439      412968 :     OBMC_FILTER4(x + 2, 1, 1, 6, 0, 0);
     440      412968 :     OBMC_FILTER4(x + 4, 1, 0, 6, 1, 0);
     441      412968 :     OBMC_FILTER4(x + 6, 1, 0, 5, 2, 0);
     442      412968 :     x += 2 * stride;
     443      412968 :     OBMC_FILTER4(x    , 0, 2, 5, 0, 1);
     444      412968 :     OBMC_FILTER4(x + 2, 0, 1, 6, 0, 1);
     445      412968 :     OBMC_FILTER4(x + 4, 0, 0, 6, 1, 1);
     446      412968 :     OBMC_FILTER4(x + 6, 0, 0, 5, 2, 1);
     447      412968 :     x += 2*stride;
     448      412968 :     OBMC_FILTER (x    , 0, 2, 5, 0, 1);
     449      412968 :     OBMC_FILTER (x + 1, 0, 2, 5, 0, 1);
     450      412968 :     OBMC_FILTER4(x + 2, 0, 1, 5, 0, 2);
     451      412968 :     OBMC_FILTER4(x + 4, 0, 0, 5, 1, 2);
     452      412968 :     OBMC_FILTER (x + 6, 0, 0, 5, 2, 1);
     453      412968 :     OBMC_FILTER (x + 7, 0, 0, 5, 2, 1);
     454      412968 :     x += stride;
     455      412968 :     OBMC_FILTER (x    , 0, 2, 4, 0, 2);
     456      412968 :     OBMC_FILTER (x + 1, 0, 1, 5, 0, 2);
     457      412968 :     OBMC_FILTER (x + 6, 0, 0, 5, 1, 2);
     458      412968 :     OBMC_FILTER (x + 7, 0, 0, 4, 2, 2);
     459      412968 : }
     460             : 
     461             : /* obmc for 1 8x8 luma block */
     462      412968 : static inline void obmc_motion(MpegEncContext *s,
     463             :                                uint8_t *dest, uint8_t *src,
     464             :                                int src_x, int src_y,
     465             :                                op_pixels_func *pix_op,
     466             :                                int16_t mv[5][2] /* mid top left right bottom */)
     467             : #define MID    0
     468             : {
     469             :     int i;
     470             :     uint8_t *ptr[5];
     471             : 
     472             :     av_assert2(s->quarter_sample == 0);
     473             : 
     474     2477808 :     for (i = 0; i < 5; i++) {
     475     2064840 :         if (i && mv[i][0] == mv[MID][0] && mv[i][1] == mv[MID][1]) {
     476     1241572 :             ptr[i] = ptr[MID];
     477             :         } else {
     478     1646536 :             ptr[i] = s->sc.obmc_scratchpad + 8 * (i & 1) +
     479      823268 :                      s->linesize * 8 * (i >> 1);
     480     1646536 :             hpel_motion(s, ptr[i], src, src_x, src_y, pix_op,
     481     1646536 :                         mv[i][0], mv[i][1]);
     482             :         }
     483             :     }
     484             : 
     485      412968 :     put_obmc(dest, ptr, s->linesize);
     486      412968 : }
     487             : 
     488      212545 : static inline void qpel_motion(MpegEncContext *s,
     489             :                                uint8_t *dest_y,
     490             :                                uint8_t *dest_cb,
     491             :                                uint8_t *dest_cr,
     492             :                                int field_based, int bottom_field,
     493             :                                int field_select, uint8_t **ref_picture,
     494             :                                op_pixels_func (*pix_op)[4],
     495             :                                qpel_mc_func (*qpix_op)[16],
     496             :                                int motion_x, int motion_y, int h)
     497             : {
     498             :     uint8_t *ptr_y, *ptr_cb, *ptr_cr;
     499             :     int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos;
     500             :     ptrdiff_t linesize, uvlinesize;
     501             : 
     502      212545 :     dxy   = ((motion_y & 3) << 2) | (motion_x & 3);
     503             : 
     504      212545 :     src_x = s->mb_x *  16                 + (motion_x >> 2);
     505      212545 :     src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
     506             : 
     507      212545 :     v_edge_pos = s->v_edge_pos >> field_based;
     508      212545 :     linesize   = s->linesize   << field_based;
     509      212545 :     uvlinesize = s->uvlinesize << field_based;
     510             : 
     511      212545 :     if (field_based) {
     512           0 :         mx = motion_x / 2;
     513           0 :         my = motion_y >> 1;
     514      212545 :     } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA2) {
     515             :         static const int rtab[8] = { 0, 0, 1, 1, 0, 0, 0, 1 };
     516           0 :         mx = (motion_x >> 1) + rtab[motion_x & 7];
     517           0 :         my = (motion_y >> 1) + rtab[motion_y & 7];
     518      212545 :     } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA) {
     519           0 :         mx = (motion_x >> 1) | (motion_x & 1);
     520           0 :         my = (motion_y >> 1) | (motion_y & 1);
     521             :     } else {
     522      212545 :         mx = motion_x / 2;
     523      212545 :         my = motion_y / 2;
     524             :     }
     525      212545 :     mx = (mx >> 1) | (mx & 1);
     526      212545 :     my = (my >> 1) | (my & 1);
     527             : 
     528      212545 :     uvdxy = (mx & 1) | ((my & 1) << 1);
     529      212545 :     mx  >>= 1;
     530      212545 :     my  >>= 1;
     531             : 
     532      212545 :     uvsrc_x = s->mb_x *  8                 + mx;
     533      212545 :     uvsrc_y = s->mb_y * (8 >> field_based) + my;
     534             : 
     535      212545 :     ptr_y  = ref_picture[0] + src_y   * linesize   + src_x;
     536      212545 :     ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
     537      212545 :     ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
     538             : 
     539      415541 :     if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 15   , 0) ||
     540      202996 :         (unsigned)src_y >= FFMAX(   v_edge_pos - (motion_y & 3) - h + 1, 0)) {
     541       20705 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
     542             :                                  s->linesize, s->linesize,
     543             :                                  17, 17 + field_based,
     544             :                                  src_x, src_y * (1 << field_based),
     545             :                                  s->h_edge_pos, s->v_edge_pos);
     546       20705 :         ptr_y = s->sc.edge_emu_buffer;
     547             :         if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
     548       20705 :             uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
     549       20705 :             uint8_t *vbuf = ubuf + 10 * s->uvlinesize;
     550       20705 :             if (s->workaround_bugs & FF_BUG_IEDGE)
     551           0 :                 vbuf -= s->uvlinesize;
     552       62115 :             s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
     553             :                                      s->uvlinesize, s->uvlinesize,
     554             :                                      9, 9 + field_based,
     555             :                                      uvsrc_x, uvsrc_y * (1 << field_based),
     556       41410 :                                      s->h_edge_pos >> 1, s->v_edge_pos >> 1);
     557       62115 :             s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
     558             :                                      s->uvlinesize, s->uvlinesize,
     559             :                                      9, 9 + field_based,
     560             :                                      uvsrc_x, uvsrc_y * (1 << field_based),
     561       41410 :                                      s->h_edge_pos >> 1, s->v_edge_pos >> 1);
     562       20705 :             ptr_cb = ubuf;
     563       20705 :             ptr_cr = vbuf;
     564             :         }
     565             :     }
     566             : 
     567      212545 :     if (!field_based)
     568      212545 :         qpix_op[0][dxy](dest_y, ptr_y, linesize);
     569             :     else {
     570           0 :         if (bottom_field) {
     571           0 :             dest_y  += s->linesize;
     572           0 :             dest_cb += s->uvlinesize;
     573           0 :             dest_cr += s->uvlinesize;
     574             :         }
     575             : 
     576           0 :         if (field_select) {
     577           0 :             ptr_y  += s->linesize;
     578           0 :             ptr_cb += s->uvlinesize;
     579           0 :             ptr_cr += s->uvlinesize;
     580             :         }
     581             :         // damn interlaced mode
     582             :         // FIXME boundary mirroring is not exactly correct here
     583           0 :         qpix_op[1][dxy](dest_y, ptr_y, linesize);
     584           0 :         qpix_op[1][dxy](dest_y + 8, ptr_y + 8, linesize);
     585             :     }
     586             :     if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
     587      212545 :         pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1);
     588      212545 :         pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1);
     589             :     }
     590      212545 : }
     591             : 
     592             : /**
     593             :  * H.263 chroma 4mv motion compensation.
     594             :  */
     595      682696 : static void chroma_4mv_motion(MpegEncContext *s,
     596             :                               uint8_t *dest_cb, uint8_t *dest_cr,
     597             :                               uint8_t **ref_picture,
     598             :                               op_pixels_func *pix_op,
     599             :                               int mx, int my)
     600             : {
     601             :     uint8_t *ptr;
     602      682696 :     int src_x, src_y, dxy, emu = 0;
     603             :     ptrdiff_t offset;
     604             : 
     605             :     /* In case of 8X8, we construct a single chroma motion vector
     606             :      * with a special rounding */
     607      682696 :     mx = ff_h263_round_chroma(mx);
     608      682696 :     my = ff_h263_round_chroma(my);
     609             : 
     610      682696 :     dxy  = ((my & 1) << 1) | (mx & 1);
     611      682696 :     mx >>= 1;
     612      682696 :     my >>= 1;
     613             : 
     614      682696 :     src_x = s->mb_x * 8 + mx;
     615      682696 :     src_y = s->mb_y * 8 + my;
     616      682696 :     src_x = av_clip(src_x, -8, (s->width >> 1));
     617      682696 :     if (src_x == (s->width >> 1))
     618           2 :         dxy &= ~1;
     619      682696 :     src_y = av_clip(src_y, -8, (s->height >> 1));
     620      682696 :     if (src_y == (s->height >> 1))
     621          15 :         dxy &= ~2;
     622             : 
     623      682696 :     offset = src_y * s->uvlinesize + src_x;
     624      682696 :     ptr    = ref_picture[1] + offset;
     625     1338502 :     if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - (dxy  & 1) - 7, 0) ||
     626      655806 :         (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 7, 0)) {
     627      166797 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
     628             :                                  s->uvlinesize, s->uvlinesize,
     629             :                                  9, 9, src_x, src_y,
     630      111198 :                                  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
     631       55599 :         ptr = s->sc.edge_emu_buffer;
     632       55599 :         emu = 1;
     633             :     }
     634      682696 :     pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
     635             : 
     636      682696 :     ptr = ref_picture[2] + offset;
     637      682696 :     if (emu) {
     638      166797 :         s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
     639             :                                  s->uvlinesize, s->uvlinesize,
     640             :                                  9, 9, src_x, src_y,
     641      111198 :                                  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
     642       55599 :         ptr = s->sc.edge_emu_buffer;
     643             :     }
     644      682696 :     pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
     645      682696 : }
     646             : 
     647     8503778 : static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir)
     648             : {
     649             :     /* fetch pixels for estimated mv 4 macroblocks ahead
     650             :      * optimized for 64byte cache lines */
     651     8503778 :     const int shift = s->quarter_sample ? 2 : 1;
     652     8503778 :     const int mx    = (s->mv[dir][0][0] >> shift) + 16 * s->mb_x + 8;
     653     8503778 :     const int my    = (s->mv[dir][0][1] >> shift) + 16 * s->mb_y;
     654     8503778 :     int off         = mx + (my + (s->mb_x & 3) * 4) * s->linesize + 64;
     655             : 
     656     8503778 :     s->vdsp.prefetch(pix[0] + off, s->linesize, 4);
     657     8503778 :     off = (mx >> 1) + ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize + 64;
     658     8503778 :     s->vdsp.prefetch(pix[1] + off, pix[2] - pix[1], 2);
     659     8503778 : }
     660             : 
     661      103242 : static inline void apply_obmc(MpegEncContext *s,
     662             :                               uint8_t *dest_y,
     663             :                               uint8_t *dest_cb,
     664             :                               uint8_t *dest_cr,
     665             :                               uint8_t **ref_picture,
     666             :                               op_pixels_func (*pix_op)[4])
     667             : {
     668      103242 :     LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
     669      103242 :     Picture *cur_frame   = &s->current_picture;
     670      103242 :     int mb_x = s->mb_x;
     671      103242 :     int mb_y = s->mb_y;
     672      103242 :     const int xy         = mb_x + mb_y * s->mb_stride;
     673      103242 :     const int mot_stride = s->b8_stride;
     674      103242 :     const int mot_xy     = mb_x * 2 + mb_y * 2 * mot_stride;
     675             :     int mx, my, i;
     676             : 
     677             :     av_assert2(!s->mb_skipped);
     678             : 
     679      103242 :     AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy]);
     680      103242 :     AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
     681             : 
     682      103242 :     AV_COPY32(mv_cache[2][1],
     683             :               cur_frame->motion_val[0][mot_xy + mot_stride]);
     684      103242 :     AV_COPY32(mv_cache[2][2],
     685             :               cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
     686             : 
     687      103242 :     AV_COPY32(mv_cache[3][1],
     688             :               cur_frame->motion_val[0][mot_xy + mot_stride]);
     689      103242 :     AV_COPY32(mv_cache[3][2],
     690             :               cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
     691             : 
     692      103242 :     if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
     693        7740 :         AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
     694        7740 :         AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
     695             :     } else {
     696       95502 :         AV_COPY32(mv_cache[0][1],
     697             :                   cur_frame->motion_val[0][mot_xy - mot_stride]);
     698       95502 :         AV_COPY32(mv_cache[0][2],
     699             :                   cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
     700             :     }
     701             : 
     702      103242 :     if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) {
     703        6486 :         AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
     704        6486 :         AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
     705             :     } else {
     706       96756 :         AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]);
     707       96756 :         AV_COPY32(mv_cache[2][0],
     708             :                   cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
     709             :     }
     710             : 
     711      103242 :     if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) {
     712        6529 :         AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
     713        6529 :         AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
     714             :     } else {
     715       96713 :         AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]);
     716       96713 :         AV_COPY32(mv_cache[2][3],
     717             :                   cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
     718             :     }
     719             : 
     720      103242 :     mx = 0;
     721      103242 :     my = 0;
     722      516210 :     for (i = 0; i < 4; i++) {
     723      412968 :         const int x      = (i & 1) + 1;
     724      412968 :         const int y      = (i >> 1) + 1;
     725     4129680 :         int16_t mv[5][2] = {
     726      825936 :             { mv_cache[y][x][0],     mv_cache[y][x][1]         },
     727      825936 :             { mv_cache[y - 1][x][0], mv_cache[y - 1][x][1]     },
     728      825936 :             { mv_cache[y][x - 1][0], mv_cache[y][x - 1][1]     },
     729      825936 :             { mv_cache[y][x + 1][0], mv_cache[y][x + 1][1]     },
     730      825936 :             { mv_cache[y + 1][x][0], mv_cache[y + 1][x][1]     }
     731             :         };
     732             :         // FIXME cleanup
     733      825936 :         obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
     734             :                     ref_picture[0],
     735      825936 :                     mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8,
     736      412968 :                     pix_op[1],
     737             :                     mv);
     738             : 
     739      412968 :         mx += mv[0][0];
     740      412968 :         my += mv[0][1];
     741             :     }
     742             :     if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
     743      103242 :         chroma_4mv_motion(s, dest_cb, dest_cr,
     744      103242 :                           ref_picture, pix_op[1],
     745             :                           mx, my);
     746      103242 : }
     747             : 
     748      579454 : static inline void apply_8x8(MpegEncContext *s,
     749             :                              uint8_t *dest_y,
     750             :                              uint8_t *dest_cb,
     751             :                              uint8_t *dest_cr,
     752             :                              int dir,
     753             :                              uint8_t **ref_picture,
     754             :                              qpel_mc_func (*qpix_op)[16],
     755             :                              op_pixels_func (*pix_op)[4])
     756             : {
     757             :     int dxy, mx, my, src_x, src_y;
     758             :     int i;
     759      579454 :     int mb_x = s->mb_x;
     760      579454 :     int mb_y = s->mb_y;
     761             :     uint8_t *ptr, *dest;
     762             : 
     763      579454 :     mx = 0;
     764      579454 :     my = 0;
     765      579454 :     if (s->quarter_sample) {
     766      632655 :         for (i = 0; i < 4; i++) {
     767      506124 :             int motion_x = s->mv[dir][i][0];
     768      506124 :             int motion_y = s->mv[dir][i][1];
     769             : 
     770      506124 :             dxy   = ((motion_y & 3) << 2) | (motion_x & 3);
     771      506124 :             src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
     772      506124 :             src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8;
     773             : 
     774             :             /* WARNING: do no forget half pels */
     775      506124 :             src_x = av_clip(src_x, -16, s->width);
     776      506124 :             if (src_x == s->width)
     777         698 :                 dxy &= ~3;
     778      506124 :             src_y = av_clip(src_y, -16, s->height);
     779      506124 :             if (src_y == s->height)
     780         838 :                 dxy &= ~12;
     781             : 
     782      506124 :             ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
     783     1000589 :             if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 7, 0) ||
     784      494465 :                 (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 3) - 7, 0)) {
     785       24373 :                 s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
     786             :                                          s->linesize, s->linesize,
     787             :                                          9, 9,
     788             :                                          src_x, src_y,
     789             :                                          s->h_edge_pos,
     790             :                                          s->v_edge_pos);
     791       24373 :                 ptr = s->sc.edge_emu_buffer;
     792             :             }
     793      506124 :             dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
     794      506124 :             qpix_op[1][dxy](dest, ptr, s->linesize);
     795             : 
     796      506124 :             mx += s->mv[dir][i][0] / 2;
     797      506124 :             my += s->mv[dir][i][1] / 2;
     798             :         }
     799             :     } else {
     800     2264615 :         for (i = 0; i < 4; i++) {
     801     7246768 :             hpel_motion(s,
     802     1811692 :                         dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
     803             :                         ref_picture[0],
     804     1811692 :                         mb_x * 16 + (i & 1) * 8,
     805     1811692 :                         mb_y * 16 + (i >> 1) * 8,
     806     1811692 :                         pix_op[1],
     807             :                         s->mv[dir][i][0],
     808             :                         s->mv[dir][i][1]);
     809             : 
     810     1811692 :             mx += s->mv[dir][i][0];
     811     1811692 :             my += s->mv[dir][i][1];
     812             :         }
     813             :     }
     814             : 
     815             :     if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
     816      579454 :         chroma_4mv_motion(s, dest_cb, dest_cr,
     817      579454 :                           ref_picture, pix_op[1], mx, my);
     818      579454 : }
     819             : 
     820             : /**
     821             :  * motion compensation of a single macroblock
     822             :  * @param s context
     823             :  * @param dest_y luma destination pointer
     824             :  * @param dest_cb chroma cb/u destination pointer
     825             :  * @param dest_cr chroma cr/v destination pointer
     826             :  * @param dir direction (0->forward, 1->backward)
     827             :  * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
     828             :  * @param pix_op halfpel motion compensation function (average or put normally)
     829             :  * @param qpix_op qpel motion compensation function (average or put normally)
     830             :  * the motion vectors are taken from s->mv and the MV type from s->mv_type
     831             :  */
     832     8503778 : static av_always_inline void mpv_motion_internal(MpegEncContext *s,
     833             :                                                  uint8_t *dest_y,
     834             :                                                  uint8_t *dest_cb,
     835             :                                                  uint8_t *dest_cr,
     836             :                                                  int dir,
     837             :                                                  uint8_t **ref_picture,
     838             :                                                  op_pixels_func (*pix_op)[4],
     839             :                                                  qpel_mc_func (*qpix_op)[16],
     840             :                                                  int is_mpeg12)
     841             : {
     842             :     int i;
     843     8503778 :     int mb_y = s->mb_y;
     844             : 
     845     8503778 :     prefetch_motion(s, ref_picture, dir);
     846             : 
     847     8503778 :     if (!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B) {
     848      103242 :         apply_obmc(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op);
     849      103242 :         return;
     850             :     }
     851             : 
     852     8400536 :     switch (s->mv_type) {
     853     7096098 :     case MV_TYPE_16X16:
     854     7096098 :         if (s->mcsel) {
     855           0 :             if (s->real_sprite_warping_points == 1) {
     856           0 :                 gmc1_motion(s, dest_y, dest_cb, dest_cr,
     857             :                             ref_picture);
     858             :             } else {
     859           0 :                 gmc_motion(s, dest_y, dest_cb, dest_cr,
     860             :                            ref_picture);
     861             :             }
     862     7096098 :         } else if (!is_mpeg12 && s->quarter_sample) {
     863      212545 :             qpel_motion(s, dest_y, dest_cb, dest_cr,
     864             :                         0, 0, 0,
     865             :                         ref_picture, pix_op, qpix_op,
     866             :                         s->mv[dir][0][0], s->mv[dir][0][1], 16);
     867    10928016 :         } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&
     868     4124956 :                    s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {
     869       80493 :             ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
     870             :                             ref_picture, pix_op,
     871             :                             s->mv[dir][0][0], s->mv[dir][0][1], 16);
     872             :         } else {
     873     6803060 :             mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
     874             :                         ref_picture, pix_op,
     875             :                         s->mv[dir][0][0], s->mv[dir][0][1], 16, 0, mb_y);
     876             :         }
     877     7096098 :         break;
     878      579454 :     case MV_TYPE_8X8:
     879      579454 :         if (!is_mpeg12)
     880      579454 :             apply_8x8(s, dest_y, dest_cb, dest_cr,
     881             :                       dir, ref_picture, qpix_op, pix_op);
     882      579454 :         break;
     883      506639 :     case MV_TYPE_FIELD:
     884      506639 :         if (s->picture_structure == PICT_FRAME) {
     885      221989 :             if (!is_mpeg12 && s->quarter_sample) {
     886           0 :                 for (i = 0; i < 2; i++)
     887           0 :                     qpel_motion(s, dest_y, dest_cb, dest_cr,
     888             :                                 1, i, s->field_select[dir][i],
     889             :                                 ref_picture, pix_op, qpix_op,
     890             :                                 s->mv[dir][i][0], s->mv[dir][i][1], 8);
     891             :             } else {
     892             :                 /* top field */
     893      221989 :                 mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
     894             :                                   0, s->field_select[dir][0],
     895             :                                   ref_picture, pix_op,
     896             :                                   s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y);
     897             :                 /* bottom field */
     898      221989 :                 mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
     899             :                                   1, s->field_select[dir][1],
     900             :                                   ref_picture, pix_op,
     901             :                                   s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y);
     902             :             }
     903             :         } else {
     904      284650 :             if (   s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field
     905      258697 :                 || !ref_picture[0]) {
     906       25953 :                 ref_picture = s->current_picture_ptr->f->data;
     907             :             }
     908             : 
     909      284650 :             mpeg_motion(s, dest_y, dest_cb, dest_cr,
     910             :                         s->field_select[dir][0],
     911             :                         ref_picture, pix_op,
     912             :                         s->mv[dir][0][0], s->mv[dir][0][1], 16, 0, mb_y >> 1);
     913             :         }
     914      506639 :         break;
     915      203181 :     case MV_TYPE_16X8:
     916      609543 :         for (i = 0; i < 2; i++) {
     917             :             uint8_t **ref2picture;
     918             : 
     919      406362 :             if ((s->picture_structure == s->field_select[dir][i] + 1
     920       54915 :                 || s->pict_type == AV_PICTURE_TYPE_B || s->first_field) && ref_picture[0]) {
     921      358900 :                 ref2picture = ref_picture;
     922             :             } else {
     923       47462 :                 ref2picture = s->current_picture_ptr->f->data;
     924             :             }
     925             : 
     926      406362 :             mpeg_motion(s, dest_y, dest_cb, dest_cr,
     927             :                         s->field_select[dir][i],
     928             :                         ref2picture, pix_op,
     929             :                         s->mv[dir][i][0], s->mv[dir][i][1],
     930      406362 :                         8, 1, (mb_y & ~1) + i);
     931             : 
     932      406362 :             dest_y  += 16 * s->linesize;
     933      406362 :             dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize;
     934      406362 :             dest_cr += (16 >> s->chroma_y_shift) * s->uvlinesize;
     935             :         }
     936      203181 :         break;
     937       15164 :     case MV_TYPE_DMV:
     938       15164 :         if (s->picture_structure == PICT_FRAME) {
     939           0 :             for (i = 0; i < 2; i++) {
     940             :                 int j;
     941           0 :                 for (j = 0; j < 2; j++)
     942           0 :                     mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
     943             :                                       j, j ^ i, ref_picture, pix_op,
     944           0 :                                       s->mv[dir][2 * i + j][0],
     945           0 :                                       s->mv[dir][2 * i + j][1], 8, mb_y);
     946           0 :                 pix_op = s->hdsp.avg_pixels_tab;
     947             :             }
     948             :         } else {
     949       15164 :             if (!ref_picture[0]) {
     950           0 :                 ref_picture = s->current_picture_ptr->f->data;
     951             :             }
     952       45492 :             for (i = 0; i < 2; i++) {
     953      121312 :                 mpeg_motion(s, dest_y, dest_cb, dest_cr,
     954       30328 :                             s->picture_structure != i + 1,
     955             :                             ref_picture, pix_op,
     956       60656 :                             s->mv[dir][2 * i][0], s->mv[dir][2 * i][1],
     957             :                             16, 0, mb_y >> 1);
     958             : 
     959             :                 // after put we make avg of the same block
     960       30328 :                 pix_op = s->hdsp.avg_pixels_tab;
     961             : 
     962             :                 /* opposite parity is always in the same frame if this is
     963             :                  * second field */
     964       30328 :                 if (!s->first_field) {
     965       26096 :                     ref_picture = s->current_picture_ptr->f->data;
     966             :                 }
     967             :             }
     968             :         }
     969       15164 :         break;
     970             :     default: av_assert2(0);
     971             :     }
     972             : }
     973             : 
     974     8503778 : void ff_mpv_motion(MpegEncContext *s,
     975             :                    uint8_t *dest_y, uint8_t *dest_cb,
     976             :                    uint8_t *dest_cr, int dir,
     977             :                    uint8_t **ref_picture,
     978             :                    op_pixels_func (*pix_op)[4],
     979             :                    qpel_mc_func (*qpix_op)[16])
     980             : {
     981             : #if !CONFIG_SMALL
     982     8503778 :     if (s->out_format == FMT_MPEG1)
     983     3564074 :         mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
     984             :                             ref_picture, pix_op, qpix_op, 1);
     985             :     else
     986             : #endif
     987     4939704 :         mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
     988             :                             ref_picture, pix_op, qpix_op, 0);
     989     8503778 : }

Generated by: LCOV version 1.13