Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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