FFmpeg
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 "h261.h"
30 #include "mpegutils.h"
31 #include "mpegvideo.h"
32 #include "mjpegenc.h"
33 #include "msmpeg4.h"
34 #include "qpeldsp.h"
35 #include "wmv2.h"
36 #include <limits.h>
37 
39  uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
40  uint8_t **ref_picture)
41 {
42  uint8_t *ptr;
43  int src_x, src_y, motion_x, motion_y;
44  ptrdiff_t offset, linesize, uvlinesize;
45  int emu = 0;
46 
47  motion_x = s->sprite_offset[0][0];
48  motion_y = s->sprite_offset[0][1];
49  src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));
50  src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));
51  motion_x *= 1 << (3 - s->sprite_warping_accuracy);
52  motion_y *= 1 << (3 - s->sprite_warping_accuracy);
53  src_x = av_clip(src_x, -16, s->width);
54  if (src_x == s->width)
55  motion_x = 0;
56  src_y = av_clip(src_y, -16, s->height);
57  if (src_y == s->height)
58  motion_y = 0;
59 
60  linesize = s->linesize;
61  uvlinesize = s->uvlinesize;
62 
63  ptr = ref_picture[0] + src_y * linesize + src_x;
64 
65  if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||
66  (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {
67  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
69  17, 17,
70  src_x, src_y,
71  s->h_edge_pos, s->v_edge_pos);
72  ptr = s->sc.edge_emu_buffer;
73  }
74 
75  if ((motion_x | motion_y) & 7) {
76  s->mdsp.gmc1(dest_y, ptr, linesize, 16,
77  motion_x & 15, motion_y & 15, 128 - s->no_rounding);
78  s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,
79  motion_x & 15, motion_y & 15, 128 - s->no_rounding);
80  } else {
81  int dxy;
82 
83  dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);
84  if (s->no_rounding) {
85  s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
86  } else {
87  s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
88  }
89  }
90 
91  if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
92  return;
93 
94  motion_x = s->sprite_offset[1][0];
95  motion_y = s->sprite_offset[1][1];
96  src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));
97  src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));
98  motion_x *= 1 << (3 - s->sprite_warping_accuracy);
99  motion_y *= 1 << (3 - s->sprite_warping_accuracy);
100  src_x = av_clip(src_x, -8, s->width >> 1);
101  if (src_x == s->width >> 1)
102  motion_x = 0;
103  src_y = av_clip(src_y, -8, s->height >> 1);
104  if (src_y == s->height >> 1)
105  motion_y = 0;
106 
107  offset = (src_y * uvlinesize) + src_x;
108  ptr = ref_picture[1] + offset;
109  if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||
110  (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {
111  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
113  9, 9,
114  src_x, src_y,
115  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
116  ptr = s->sc.edge_emu_buffer;
117  emu = 1;
118  }
119  s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8,
120  motion_x & 15, motion_y & 15, 128 - s->no_rounding);
121 
122  ptr = ref_picture[2] + offset;
123  if (emu) {
124  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
126  9, 9,
127  src_x, src_y,
128  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
129  ptr = s->sc.edge_emu_buffer;
130  }
131  s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8,
132  motion_x & 15, motion_y & 15, 128 - s->no_rounding);
133 }
134 
136  uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
137  uint8_t **ref_picture)
138 {
139  uint8_t *ptr;
140  int linesize, uvlinesize;
141  const int a = s->sprite_warping_accuracy;
142  int ox, oy;
143 
144  linesize = s->linesize;
145  uvlinesize = s->uvlinesize;
146 
147  ptr = ref_picture[0];
148 
149  ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +
150  s->sprite_delta[0][1] * s->mb_y * 16;
151  oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +
152  s->sprite_delta[1][1] * s->mb_y * 16;
153 
154  s->mdsp.gmc(dest_y, ptr, linesize, 16,
155  ox, oy,
156  s->sprite_delta[0][0], s->sprite_delta[0][1],
157  s->sprite_delta[1][0], s->sprite_delta[1][1],
158  a + 1, (1 << (2 * a + 1)) - s->no_rounding,
159  s->h_edge_pos, s->v_edge_pos);
160  s->mdsp.gmc(dest_y + 8, ptr, linesize, 16,
161  ox + s->sprite_delta[0][0] * 8,
162  oy + s->sprite_delta[1][0] * 8,
163  s->sprite_delta[0][0], s->sprite_delta[0][1],
164  s->sprite_delta[1][0], s->sprite_delta[1][1],
165  a + 1, (1 << (2 * a + 1)) - s->no_rounding,
166  s->h_edge_pos, s->v_edge_pos);
167 
168  if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
169  return;
170 
171  ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +
172  s->sprite_delta[0][1] * s->mb_y * 8;
173  oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +
174  s->sprite_delta[1][1] * s->mb_y * 8;
175 
176  ptr = ref_picture[1];
177  s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8,
178  ox, oy,
179  s->sprite_delta[0][0], s->sprite_delta[0][1],
180  s->sprite_delta[1][0], s->sprite_delta[1][1],
181  a + 1, (1 << (2 * a + 1)) - s->no_rounding,
182  (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
183 
184  ptr = ref_picture[2];
185  s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8,
186  ox, oy,
187  s->sprite_delta[0][0], s->sprite_delta[0][1],
188  s->sprite_delta[1][0], s->sprite_delta[1][1],
189  a + 1, (1 << (2 * a + 1)) - s->no_rounding,
190  (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
191 }
192 
193 static inline int hpel_motion(MpegEncContext *s,
194  uint8_t *dest, uint8_t *src,
195  int src_x, int src_y,
196  op_pixels_func *pix_op,
197  int motion_x, int motion_y)
198 {
199  int dxy = 0;
200  int emu = 0;
201 
202  src_x += motion_x >> 1;
203  src_y += motion_y >> 1;
204 
205  /* WARNING: do no forget half pels */
206  src_x = av_clip(src_x, -16, s->width); // FIXME unneeded for emu?
207  if (src_x != s->width)
208  dxy |= motion_x & 1;
209  src_y = av_clip(src_y, -16, s->height);
210  if (src_y != s->height)
211  dxy |= (motion_y & 1) << 1;
212  src += src_y * s->linesize + src_x;
213 
214  if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 7, 0) ||
215  (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 1) - 7, 0)) {
216  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src,
217  s->linesize, s->linesize,
218  9, 9,
219  src_x, src_y,
220  s->h_edge_pos, s->v_edge_pos);
221  src = s->sc.edge_emu_buffer;
222  emu = 1;
223  }
224  pix_op[dxy](dest, src, s->linesize, 8);
225  return emu;
226 }
227 
228 static av_always_inline
230  uint8_t *dest_y,
231  uint8_t *dest_cb,
232  uint8_t *dest_cr,
233  int field_based,
234  int bottom_field,
235  int field_select,
236  uint8_t **ref_picture,
237  op_pixels_func (*pix_op)[4],
238  int motion_x,
239  int motion_y,
240  int h,
241  int is_mpeg12,
242  int is_16x8,
243  int mb_y)
244 {
245  uint8_t *ptr_y, *ptr_cb, *ptr_cr;
246  int dxy, uvdxy, mx, my, src_x, src_y,
247  uvsrc_x, uvsrc_y, v_edge_pos, block_y_half;
248  ptrdiff_t uvlinesize, linesize;
249 
250  v_edge_pos = s->v_edge_pos >> field_based;
251  linesize = s->current_picture.f->linesize[0] << field_based;
252  uvlinesize = s->current_picture.f->linesize[1] << field_based;
253  block_y_half = (field_based | is_16x8);
254 
255  dxy = ((motion_y & 1) << 1) | (motion_x & 1);
256  src_x = s->mb_x * 16 + (motion_x >> 1);
257  src_y = (mb_y << (4 - block_y_half)) + (motion_y >> 1);
258 
259  if (!is_mpeg12 && s->out_format == FMT_H263) {
260  if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) {
261  mx = (motion_x >> 1) | (motion_x & 1);
262  my = motion_y >> 1;
263  uvdxy = ((my & 1) << 1) | (mx & 1);
264  uvsrc_x = s->mb_x * 8 + (mx >> 1);
265  uvsrc_y = (mb_y << (3 - block_y_half)) + (my >> 1);
266  } else {
267  uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
268  uvsrc_x = src_x >> 1;
269  uvsrc_y = src_y >> 1;
270  }
271  // Even chroma mv's are full pel in H261
272  } else if (!is_mpeg12 && s->out_format == FMT_H261) {
273  mx = motion_x / 4;
274  my = motion_y / 4;
275  uvdxy = 0;
276  uvsrc_x = s->mb_x * 8 + mx;
277  uvsrc_y = mb_y * 8 + my;
278  } else {
279  if (s->chroma_y_shift) {
280  mx = motion_x / 2;
281  my = motion_y / 2;
282  uvdxy = ((my & 1) << 1) | (mx & 1);
283  uvsrc_x = s->mb_x * 8 + (mx >> 1);
284  uvsrc_y = (mb_y << (3 - block_y_half)) + (my >> 1);
285  } else {
286  if (s->chroma_x_shift) {
287  // Chroma422
288  mx = motion_x / 2;
289  uvdxy = ((motion_y & 1) << 1) | (mx & 1);
290  uvsrc_x = s->mb_x * 8 + (mx >> 1);
291  uvsrc_y = src_y;
292  } else {
293  // Chroma444
294  uvdxy = dxy;
295  uvsrc_x = src_x;
296  uvsrc_y = src_y;
297  }
298  }
299  }
300 
301  ptr_y = ref_picture[0] + src_y * linesize + src_x;
302  ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
303  ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
304 
305  if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 15 , 0) ||
306  (unsigned)src_y >= FFMAX( v_edge_pos - (motion_y & 1) - h + 1, 0)) {
307  if (is_mpeg12 ||
308  s->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
309  s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
310  av_log(s->avctx, AV_LOG_DEBUG,
311  "MPEG motion vector out of boundary (%d %d)\n", src_x,
312  src_y);
313  return;
314  }
315  src_y = (unsigned)src_y << field_based;
316  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
317  s->linesize, s->linesize,
318  17, 17 + field_based,
319  src_x, src_y,
320  s->h_edge_pos, s->v_edge_pos);
321  ptr_y = s->sc.edge_emu_buffer;
322  if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
323  uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
324  uint8_t *vbuf = ubuf + 10 * s->uvlinesize;
325  if (s->workaround_bugs & FF_BUG_IEDGE)
326  vbuf -= s->uvlinesize;
327  uvsrc_y = (unsigned)uvsrc_y << field_based;
328  s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
329  s->uvlinesize, s->uvlinesize,
330  9, 9 + field_based,
331  uvsrc_x, uvsrc_y,
332  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
333  s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
334  s->uvlinesize, s->uvlinesize,
335  9, 9 + field_based,
336  uvsrc_x, uvsrc_y,
337  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
338  ptr_cb = ubuf;
339  ptr_cr = vbuf;
340  }
341  }
342 
343  /* FIXME use this for field pix too instead of the obnoxious hack which
344  * changes picture.data */
345  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->avctx->flags & AV_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) {
368  }
369 }
370 /* apply one mpeg motion vector to the three components */
372  uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
373  int field_select, uint8_t **ref_picture,
374  op_pixels_func (*pix_op)[4],
375  int motion_x, int motion_y, int h, int is_16x8, int mb_y)
376 {
377 #if !CONFIG_SMALL
378  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, is_16x8, 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, is_16x8, mb_y);
387 }
388 
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, 0, 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, 0, mb_y);
406 }
407 
408 // FIXME: SIMDify, 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->sc.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) - 15 , 0) ||
540  (unsigned)src_y >= FFMAX( v_edge_pos - (motion_y & 3) - h + 1, 0)) {
541  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
542  s->linesize, s->linesize,
543  17, 17 + field_based,
544  src_x, src_y * (1 << field_based),
545  s->h_edge_pos, s->v_edge_pos);
546  ptr_y = s->sc.edge_emu_buffer;
547  if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
548  uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
549  uint8_t *vbuf = ubuf + 10 * s->uvlinesize;
550  if (s->workaround_bugs & FF_BUG_IEDGE)
551  vbuf -= s->uvlinesize;
552  s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
553  s->uvlinesize, s->uvlinesize,
554  9, 9 + field_based,
555  uvsrc_x, uvsrc_y * (1 << field_based),
556  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
557  s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
558  s->uvlinesize, s->uvlinesize,
559  9, 9 + field_based,
560  uvsrc_x, uvsrc_y * (1 << field_based),
561  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
562  ptr_cb = ubuf;
563  ptr_cr = vbuf;
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->avctx->flags & AV_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  * H.263 chroma 4mv motion compensation.
594  */
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 ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - (dxy & 1) - 7, 0) ||
626  (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 7, 0)) {
627  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
628  s->uvlinesize, s->uvlinesize,
629  9, 9, src_x, src_y,
630  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
631  ptr = s->sc.edge_emu_buffer;
632  emu = 1;
633  }
634  pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
635 
636  ptr = ref_picture[2] + offset;
637  if (emu) {
638  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
639  s->uvlinesize, s->uvlinesize,
640  9, 9, src_x, src_y,
641  s->h_edge_pos >> 1, s->v_edge_pos >> 1);
642  ptr = s->sc.edge_emu_buffer;
643  }
644  pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
645 }
646 
647 static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir)
648 {
649  /* fetch pixels for estimated mv 4 macroblocks ahead
650  * optimized for 64byte cache lines */
651  const int shift = s->quarter_sample ? 2 : 1;
652  const int mx = (s->mv[dir][0][0] >> shift) + 16 * s->mb_x + 8;
653  const int my = (s->mv[dir][0][1] >> shift) + 16 * s->mb_y;
654  int off = mx + (my + (s->mb_x & 3) * 4) * s->linesize + 64;
655 
656  s->vdsp.prefetch(pix[0] + off, s->linesize, 4);
657  off = (mx >> 1) + ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize + 64;
658  s->vdsp.prefetch(pix[1] + off, pix[2] - pix[1], 2);
659 }
660 
661 static inline void apply_obmc(MpegEncContext *s,
662  uint8_t *dest_y,
663  uint8_t *dest_cb,
664  uint8_t *dest_cr,
665  uint8_t **ref_picture,
666  op_pixels_func (*pix_op)[4])
667 {
668  LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
669  Picture *cur_frame = &s->current_picture;
670  int mb_x = s->mb_x;
671  int mb_y = s->mb_y;
672  const int xy = mb_x + mb_y * s->mb_stride;
673  const int mot_stride = s->b8_stride;
674  const int mot_xy = mb_x * 2 + mb_y * 2 * mot_stride;
675  int mx, my, i;
676 
677  av_assert2(!s->mb_skipped);
678 
679  AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy]);
680  AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
681 
682  AV_COPY32(mv_cache[2][1],
683  cur_frame->motion_val[0][mot_xy + mot_stride]);
684  AV_COPY32(mv_cache[2][2],
685  cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
686 
687  AV_COPY32(mv_cache[3][1],
688  cur_frame->motion_val[0][mot_xy + mot_stride]);
689  AV_COPY32(mv_cache[3][2],
690  cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
691 
692  if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
693  AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
694  AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
695  } else {
696  AV_COPY32(mv_cache[0][1],
697  cur_frame->motion_val[0][mot_xy - mot_stride]);
698  AV_COPY32(mv_cache[0][2],
699  cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
700  }
701 
702  if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) {
703  AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
704  AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
705  } else {
706  AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]);
707  AV_COPY32(mv_cache[2][0],
708  cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
709  }
710 
711  if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) {
712  AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
713  AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
714  } else {
715  AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]);
716  AV_COPY32(mv_cache[2][3],
717  cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
718  }
719 
720  mx = 0;
721  my = 0;
722  for (i = 0; i < 4; i++) {
723  const int x = (i & 1) + 1;
724  const int y = (i >> 1) + 1;
725  int16_t mv[5][2] = {
726  { mv_cache[y][x][0], mv_cache[y][x][1] },
727  { mv_cache[y - 1][x][0], mv_cache[y - 1][x][1] },
728  { mv_cache[y][x - 1][0], mv_cache[y][x - 1][1] },
729  { mv_cache[y][x + 1][0], mv_cache[y][x + 1][1] },
730  { mv_cache[y + 1][x][0], mv_cache[y + 1][x][1] }
731  };
732  // FIXME cleanup
733  obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
734  ref_picture[0],
735  mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8,
736  pix_op[1],
737  mv);
738 
739  mx += mv[0][0];
740  my += mv[0][1];
741  }
742  if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
743  chroma_4mv_motion(s, dest_cb, dest_cr,
744  ref_picture, pix_op[1],
745  mx, my);
746 }
747 
748 static inline void apply_8x8(MpegEncContext *s,
749  uint8_t *dest_y,
750  uint8_t *dest_cb,
751  uint8_t *dest_cr,
752  int dir,
753  uint8_t **ref_picture,
754  qpel_mc_func (*qpix_op)[16],
755  op_pixels_func (*pix_op)[4])
756 {
757  int dxy, mx, my, src_x, src_y;
758  int i;
759  int mb_x = s->mb_x;
760  int mb_y = s->mb_y;
761  uint8_t *ptr, *dest;
762 
763  mx = 0;
764  my = 0;
765  if (s->quarter_sample) {
766  for (i = 0; i < 4; i++) {
767  int motion_x = s->mv[dir][i][0];
768  int motion_y = s->mv[dir][i][1];
769 
770  dxy = ((motion_y & 3) << 2) | (motion_x & 3);
771  src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
772  src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8;
773 
774  /* WARNING: do no forget half pels */
775  src_x = av_clip(src_x, -16, s->width);
776  if (src_x == s->width)
777  dxy &= ~3;
778  src_y = av_clip(src_y, -16, s->height);
779  if (src_y == s->height)
780  dxy &= ~12;
781 
782  ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
783  if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 7, 0) ||
784  (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 3) - 7, 0)) {
785  s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
786  s->linesize, s->linesize,
787  9, 9,
788  src_x, src_y,
789  s->h_edge_pos,
790  s->v_edge_pos);
791  ptr = s->sc.edge_emu_buffer;
792  }
793  dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
794  qpix_op[1][dxy](dest, ptr, s->linesize);
795 
796  mx += s->mv[dir][i][0] / 2;
797  my += s->mv[dir][i][1] / 2;
798  }
799  } else {
800  for (i = 0; i < 4; i++) {
801  hpel_motion(s,
802  dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
803  ref_picture[0],
804  mb_x * 16 + (i & 1) * 8,
805  mb_y * 16 + (i >> 1) * 8,
806  pix_op[1],
807  s->mv[dir][i][0],
808  s->mv[dir][i][1]);
809 
810  mx += s->mv[dir][i][0];
811  my += s->mv[dir][i][1];
812  }
813  }
814 
815  if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
816  chroma_4mv_motion(s, dest_cb, dest_cr,
817  ref_picture, pix_op[1], mx, my);
818 }
819 
820 /**
821  * motion compensation of a single macroblock
822  * @param s context
823  * @param dest_y luma destination pointer
824  * @param dest_cb chroma cb/u destination pointer
825  * @param dest_cr chroma cr/v destination pointer
826  * @param dir direction (0->forward, 1->backward)
827  * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
828  * @param pix_op halfpel motion compensation function (average or put normally)
829  * @param qpix_op qpel motion compensation function (average or put normally)
830  * the motion vectors are taken from s->mv and the MV type from s->mv_type
831  */
833  uint8_t *dest_y,
834  uint8_t *dest_cb,
835  uint8_t *dest_cr,
836  int dir,
837  uint8_t **ref_picture,
838  op_pixels_func (*pix_op)[4],
839  qpel_mc_func (*qpix_op)[16],
840  int is_mpeg12)
841 {
842  int i;
843  int mb_y = s->mb_y;
844 
845  prefetch_motion(s, ref_picture, dir);
846 
847  if (!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B) {
848  apply_obmc(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op);
849  return;
850  }
851 
852  switch (s->mv_type) {
853  case MV_TYPE_16X16:
854  if (s->mcsel) {
855  if (s->real_sprite_warping_points == 1) {
856  gmc1_motion(s, dest_y, dest_cb, dest_cr,
857  ref_picture);
858  } else {
859  gmc_motion(s, dest_y, dest_cb, dest_cr,
860  ref_picture);
861  }
862  } else if (!is_mpeg12 && s->quarter_sample) {
863  qpel_motion(s, dest_y, dest_cb, dest_cr,
864  0, 0, 0,
865  ref_picture, pix_op, qpix_op,
866  s->mv[dir][0][0], s->mv[dir][0][1], 16);
867  } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&
868  s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {
869  ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
870  ref_picture, pix_op,
871  s->mv[dir][0][0], s->mv[dir][0][1], 16);
872  } else {
873  mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
874  ref_picture, pix_op,
875  s->mv[dir][0][0], s->mv[dir][0][1], 16, 0, mb_y);
876  }
877  break;
878  case MV_TYPE_8X8:
879  if (!is_mpeg12)
880  apply_8x8(s, dest_y, dest_cb, dest_cr,
881  dir, ref_picture, qpix_op, pix_op);
882  break;
883  case MV_TYPE_FIELD:
884  if (s->picture_structure == PICT_FRAME) {
885  if (!is_mpeg12 && s->quarter_sample) {
886  for (i = 0; i < 2; i++)
887  qpel_motion(s, dest_y, dest_cb, dest_cr,
888  1, i, s->field_select[dir][i],
889  ref_picture, pix_op, qpix_op,
890  s->mv[dir][i][0], s->mv[dir][i][1], 8);
891  } else {
892  /* top field */
893  mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
894  0, s->field_select[dir][0],
895  ref_picture, pix_op,
896  s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y);
897  /* bottom field */
898  mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
899  1, s->field_select[dir][1],
900  ref_picture, pix_op,
901  s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y);
902  }
903  } else {
904  if ( s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field
905  || !ref_picture[0]) {
906  ref_picture = s->current_picture_ptr->f->data;
907  }
908 
909  mpeg_motion(s, dest_y, dest_cb, dest_cr,
910  s->field_select[dir][0],
911  ref_picture, pix_op,
912  s->mv[dir][0][0], s->mv[dir][0][1], 16, 0, mb_y >> 1);
913  }
914  break;
915  case MV_TYPE_16X8:
916  for (i = 0; i < 2; i++) {
917  uint8_t **ref2picture;
918 
919  if ((s->picture_structure == s->field_select[dir][i] + 1
920  || s->pict_type == AV_PICTURE_TYPE_B || s->first_field) && ref_picture[0]) {
921  ref2picture = ref_picture;
922  } else {
923  ref2picture = s->current_picture_ptr->f->data;
924  }
925 
926  mpeg_motion(s, dest_y, dest_cb, dest_cr,
927  s->field_select[dir][i],
928  ref2picture, pix_op,
929  s->mv[dir][i][0], s->mv[dir][i][1],
930  8, 1, (mb_y & ~1) + i);
931 
932  dest_y += 16 * s->linesize;
933  dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize;
934  dest_cr += (16 >> s->chroma_y_shift) * s->uvlinesize;
935  }
936  break;
937  case MV_TYPE_DMV:
938  if (s->picture_structure == PICT_FRAME) {
939  for (i = 0; i < 2; i++) {
940  int j;
941  for (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  }
969  break;
970  default: av_assert2(0);
971  }
972 }
973 
975  uint8_t *dest_y, uint8_t *dest_cb,
976  uint8_t *dest_cr, int dir,
977  uint8_t **ref_picture,
978  op_pixels_func (*pix_op)[4],
979  qpel_mc_func (*qpix_op)[16])
980 {
981 #if !CONFIG_SMALL
982  if (s->out_format == FMT_MPEG1)
983  mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
984  ref_picture, pix_op, qpix_op, 1);
985  else
986 #endif
987  mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
988  ref_picture, pix_op, qpix_op, 0);
989 }
ff_h263_round_chroma
static int ff_h263_round_chroma(int x)
Definition: motion_est.h:101
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:39
stride
int stride
Definition: mace.c:144
MV_TYPE_16X16
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:266
FMT_MPEG1
@ FMT_MPEG1
Definition: mpegutils.h:124
chroma_4mv_motion
static void 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)
H.263 chroma 4mv motion compensation.
Definition: mpegvideo_motion.c:595
MV_TYPE_16X8
#define MV_TYPE_16X8
2 vectors, one per 16x8 block
Definition: mpegvideo.h:268
apply_obmc
static void 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])
Definition: mpegvideo_motion.c:661
mv
static const int8_t mv[256][2]
Definition: 4xm.c:77
qpel_motion
static void 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)
Definition: mpegvideo_motion.c:488
obmc_motion
static void 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])
Definition: mpegvideo_motion.c:462
MpegEncContext::dest
uint8_t * dest[3]
Definition: mpegvideo.h:295
mpegvideo.h
Picture
Picture.
Definition: mpegpicture.h:45
FF_BUG_HPEL_CHROMA
#define FF_BUG_HPEL_CHROMA
Definition: avcodec.h:2610
mpegutils.h
mpeg_motion_field
static void 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)
Definition: mpegvideo_motion.c:389
MV_TYPE_DMV
#define MV_TYPE_DMV
2 vectors, special mpeg2 Dual Prime Vectors
Definition: mpegvideo.h:270
FF_BUG_QPEL_CHROMA2
#define FF_BUG_QPEL_CHROMA2
Definition: avcodec.h:2607
h261.h
MpegEncContext::linesize
ptrdiff_t linesize
line size, in bytes, may be different from width
Definition: mpegvideo.h:134
src
#define src
Definition: vp8dsp.c:254
mpeg_motion
static void 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)
Definition: mpegvideo_motion.c:371
LOCAL_ALIGNED_8
#define LOCAL_ALIGNED_8(t, v,...)
Definition: internal.h:125
avassert.h
apply_8x8
static void 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])
Definition: mpegvideo_motion.c:748
s
#define s(width, name)
Definition: cbs_vp9.c:257
ff_mpv_motion
void 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])
Definition: mpegvideo_motion.c:974
AV_CODEC_ID_WMV2
@ AV_CODEC_ID_WMV2
Definition: avcodec.h:236
FMT_H261
@ FMT_H261
Definition: mpegutils.h:125
gmc1_motion
static void gmc1_motion(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, uint8_t **ref_picture)
Definition: mpegvideo_motion.c:38
OBMC_FILTER4
#define OBMC_FILTER4(x, t, l, m, r, b)
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
limits.h
IS_INTRA
#define IS_INTRA(x, y)
MpegEncContext::field_select
int field_select[2][2]
Definition: mpegvideo.h:277
mpv_motion_internal
static av_always_inline void 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)
motion compensation of a single macroblock
Definition: mpegvideo_motion.c:832
MpegEncContext::mb_y
int mb_y
Definition: mpegvideo.h:288
FF_BUG_IEDGE
#define FF_BUG_IEDGE
Definition: avcodec.h:2614
qpeldsp.h
op_pixels_func
void(* op_pixels_func)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
Definition: hpeldsp.h:38
wmv2.h
qpel_mc_func
void(* qpel_mc_func)(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
Definition: qpeldsp.h:65
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: avcodec.h:219
MV_TYPE_8X8
#define MV_TYPE_8X8
4 vectors (H.263, MPEG-4 4MV)
Definition: mpegvideo.h:267
hpel_motion
static int 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)
Definition: mpegvideo_motion.c:193
AV_CODEC_FLAG_GRAY
#define AV_CODEC_FLAG_GRAY
Only decode/encode grayscale.
Definition: avcodec.h:883
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
MpegEncContext::v_edge_pos
int v_edge_pos
horizontal / vertical position of the right/bottom edge (pixel replication)
Definition: mpegvideo.h:132
OBMC_FILTER
#define OBMC_FILTER(x, t, l, m, r, b)
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
MV_TYPE_FIELD
#define MV_TYPE_FIELD
2 vectors, one per field
Definition: mpegvideo.h:269
Picture::motion_val
int16_t(*[2] motion_val)[2]
Definition: mpegpicture.h:53
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
MpegEncContext::uvlinesize
ptrdiff_t uvlinesize
line size, for chroma in bytes, may be different from width
Definition: mpegvideo.h:135
FMT_H263
@ FMT_H263
Definition: mpegutils.h:126
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
internal.h
MpegEncContext::mb_x
int mb_x
Definition: mpegvideo.h:288
av_always_inline
#define av_always_inline
Definition: attributes.h:43
prefetch_motion
static void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir)
Definition: mpegvideo_motion.c:647
uint8_t
uint8_t
Definition: audio_convert.c:194
AV_COPY32
#define AV_COPY32(d, s)
Definition: intreadwrite.h:601
MID
#define MID
FF_BUG_QPEL_CHROMA
#define FF_BUG_QPEL_CHROMA
Definition: avcodec.h:2605
avcodec.h
msmpeg4.h
gmc_motion
static void gmc_motion(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, uint8_t **ref_picture)
Definition: mpegvideo_motion.c:135
ff_h261_loop_filter
void ff_h261_loop_filter(MpegEncContext *s)
Definition: h261.c:63
mpeg_motion_internal
static av_always_inline void 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)
Definition: mpegvideo_motion.c:229
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
put_obmc
static void put_obmc(uint8_t *dst, uint8_t *src[5], int stride)
Definition: mpegvideo_motion.c:409
Picture::mb_type
uint32_t * mb_type
types and macros are defined in mpegutils.h
Definition: mpegpicture.h:56
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:276
shift
static int shift(int a, int b)
Definition: sonic.c:82
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
h
h
Definition: vp9dsp_template.c:2038
mjpegenc.h
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: avcodec.h:220
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:81
ff_mspel_motion
void ff_mspel_motion(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, uint8_t **ref_picture, op_pixels_func(*pix_op)[4], int motion_x, int motion_y, int h)
Definition: wmv2.c:100