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