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