FFmpeg
motion_est.c
Go to the documentation of this file.
1 /*
2  * Motion estimation
3  * Copyright (c) 2000,2001 Fabrice Bellard
4  * Copyright (c) 2002-2004 Michael Niedermayer
5  *
6  * new motion estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at>
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 /**
26  * @file
27  * Motion estimation.
28  */
29 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <limits.h>
33 
34 #include "avcodec.h"
35 #include "mathops.h"
36 #include "motion_est.h"
37 #include "mpegutils.h"
38 #include "mpegvideoenc.h"
39 
40 #define P_LEFT P[1]
41 #define P_TOP P[2]
42 #define P_TOPRIGHT P[3]
43 #define P_MEDIAN P[4]
44 #define P_MV1 P[9]
45 
46 #define ME_MAP_SHIFT 3
47 #define ME_MAP_MV_BITS 11
48 
50  int *mx_ptr, int *my_ptr, int dmin,
51  int src_index, int ref_index,
52  int size, int h);
53 
54 static inline unsigned update_map_generation(MotionEstContext *c)
55 {
56  c->map_generation+= 1<<(ME_MAP_MV_BITS*2);
57  if(c->map_generation==0){
58  c->map_generation= 1<<(ME_MAP_MV_BITS*2);
59  memset(c->map, 0, sizeof(uint32_t)*ME_MAP_SIZE);
60  }
61  return c->map_generation;
62 }
63 
64 /* shape adaptive search stuff */
65 typedef struct Minima{
66  int height;
67  int x, y;
68  int checked;
69 }Minima;
70 
71 static int minima_cmp(const void *a, const void *b){
72  const Minima *da = (const Minima *) a;
73  const Minima *db = (const Minima *) b;
74 
75  return da->height - db->height;
76 }
77 
78 #define FLAG_QPEL 1 //must be 1
79 #define FLAG_CHROMA 2
80 #define FLAG_DIRECT 4
81 
82 static inline void init_ref(MotionEstContext *c, uint8_t *const src[3],
83  uint8_t *const ref[3], uint8_t *const ref2[3],
84  int x, int y, int ref_index)
85 {
86  const int offset[3]= {
87  y*c-> stride + x,
88  ((y*c->uvstride + x)>>1),
89  ((y*c->uvstride + x)>>1),
90  };
91  int i;
92  for(i=0; i<3; i++){
93  c->src[0][i]= src [i] + offset[i];
94  c->ref[0][i]= ref [i] + offset[i];
95  }
96  if(ref_index){
97  for(i=0; i<3; i++){
98  c->ref[ref_index][i]= ref2[i] + offset[i];
99  }
100  }
101 }
102 
103 static int get_flags(MotionEstContext *c, int direct, int chroma){
104  return ((c->avctx->flags&AV_CODEC_FLAG_QPEL) ? FLAG_QPEL : 0)
105  + (direct ? FLAG_DIRECT : 0)
106  + (chroma ? FLAG_CHROMA : 0);
107 }
108 
109 static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
110  const int size, const int h, int ref_index, int src_index,
111  me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){
112  MotionEstContext * const c= &s->me;
113  const int stride= c->stride;
114  const int hx = subx + x * (1 << (1 + qpel));
115  const int hy = suby + y * (1 << (1 + qpel));
116  const uint8_t * const * const ref = c->ref[ref_index];
117  const uint8_t * const * const src = c->src[src_index];
118  int d;
119  //FIXME check chroma 4mv, (no crashes ...)
120  av_assert2(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1));
121  if(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1)){
122  const int time_pp= s->pp_time;
123  const int time_pb= s->pb_time;
124  const int mask= 2*qpel+1;
125  if(s->mv_type==MV_TYPE_8X8){
126  int i;
127  for(i=0; i<4; i++){
128  int fx = c->direct_basis_mv[i][0] + hx;
129  int fy = c->direct_basis_mv[i][1] + hy;
130  int bx = hx ? fx - c->co_located_mv[i][0] : c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(qpel+4));
131  int by = hy ? fy - c->co_located_mv[i][1] : c->co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(qpel+4));
132  int fxy= (fx&mask) + ((fy&mask)<<(qpel+1));
133  int bxy= (bx&mask) + ((by&mask)<<(qpel+1));
134 
135  uint8_t *dst= c->temp + 8*(i&1) + 8*stride*(i>>1);
136  if(qpel){
137  c->qpel_put[1][fxy](dst, ref[0] + (fx>>2) + (fy>>2)*stride, stride);
138  c->qpel_avg[1][bxy](dst, ref[8] + (bx>>2) + (by>>2)*stride, stride);
139  }else{
140  c->hpel_put[1][fxy](dst, ref[0] + (fx>>1) + (fy>>1)*stride, stride, 8);
141  c->hpel_avg[1][bxy](dst, ref[8] + (bx>>1) + (by>>1)*stride, stride, 8);
142  }
143  }
144  }else{
145  int fx = c->direct_basis_mv[0][0] + hx;
146  int fy = c->direct_basis_mv[0][1] + hy;
147  int bx = hx ? fx - c->co_located_mv[0][0] : (c->co_located_mv[0][0]*(time_pb - time_pp)/time_pp);
148  int by = hy ? fy - c->co_located_mv[0][1] : (c->co_located_mv[0][1]*(time_pb - time_pp)/time_pp);
149  int fxy= (fx&mask) + ((fy&mask)<<(qpel+1));
150  int bxy= (bx&mask) + ((by&mask)<<(qpel+1));
151 
152  if(qpel){
153  c->qpel_put[1][fxy](c->temp , ref[0] + (fx>>2) + (fy>>2)*stride , stride);
154  c->qpel_put[1][fxy](c->temp + 8 , ref[0] + (fx>>2) + (fy>>2)*stride + 8 , stride);
155  c->qpel_put[1][fxy](c->temp + 8*stride, ref[0] + (fx>>2) + (fy>>2)*stride + 8*stride, stride);
156  c->qpel_put[1][fxy](c->temp + 8 + 8*stride, ref[0] + (fx>>2) + (fy>>2)*stride + 8 + 8*stride, stride);
157  c->qpel_avg[1][bxy](c->temp , ref[8] + (bx>>2) + (by>>2)*stride , stride);
158  c->qpel_avg[1][bxy](c->temp + 8 , ref[8] + (bx>>2) + (by>>2)*stride + 8 , stride);
159  c->qpel_avg[1][bxy](c->temp + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride + 8*stride, stride);
160  c->qpel_avg[1][bxy](c->temp + 8 + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride + 8 + 8*stride, stride);
161  }else{
162  av_assert2((fx>>1) + 16*s->mb_x >= -16);
163  av_assert2((fy>>1) + 16*s->mb_y >= -16);
164  av_assert2((fx>>1) + 16*s->mb_x <= s->width);
165  av_assert2((fy>>1) + 16*s->mb_y <= s->height);
166  av_assert2((bx>>1) + 16*s->mb_x >= -16);
167  av_assert2((by>>1) + 16*s->mb_y >= -16);
168  av_assert2((bx>>1) + 16*s->mb_x <= s->width);
169  av_assert2((by>>1) + 16*s->mb_y <= s->height);
170 
171  c->hpel_put[0][fxy](c->temp, ref[0] + (fx>>1) + (fy>>1)*stride, stride, 16);
172  c->hpel_avg[0][bxy](c->temp, ref[8] + (bx>>1) + (by>>1)*stride, stride, 16);
173  }
174  }
175  d = cmp_func(s, c->temp, src[0], stride, 16);
176  }else
177  d= 256*256*256*32;
178  return d;
179 }
180 
181 static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
182  const int size, const int h, int ref_index, int src_index,
183  me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel, int chroma){
184  MotionEstContext * const c= &s->me;
185  const int stride= c->stride;
186  const int uvstride= c->uvstride;
187  const int dxy= subx + (suby<<(1+qpel)); //FIXME log2_subpel?
188  const int hx= subx + x*(1<<(1+qpel));
189  const int hy= suby + y*(1<<(1+qpel));
190  const uint8_t * const * const ref = c->ref[ref_index];
191  const uint8_t * const * const src = c->src[src_index];
192  int d;
193  //FIXME check chroma 4mv, (no crashes ...)
194  int uvdxy; /* no, it might not be used uninitialized */
195  if(dxy){
196  if(qpel){
197  if (h << size == 16) {
198  c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h)
199  } else if (size == 0 && h == 8) {
200  c->qpel_put[1][dxy](c->temp , ref[0] + x + y*stride , stride);
201  c->qpel_put[1][dxy](c->temp + 8, ref[0] + x + y*stride + 8, stride);
202  } else
203  av_assert2(0);
204  if(chroma){
205  int cx= hx/2;
206  int cy= hy/2;
207  cx= (cx>>1)|(cx&1);
208  cy= (cy>>1)|(cy&1);
209  uvdxy= (cx&1) + 2*(cy&1);
210  // FIXME x/y wrong, but MPEG-4 qpel is sick anyway, we should drop as much of it as possible in favor for H.264
211  }
212  }else{
213  c->hpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride, h);
214  if(chroma)
215  uvdxy= dxy | (x&1) | (2*(y&1));
216  }
217  d = cmp_func(s, c->temp, src[0], stride, h);
218  }else{
219  d = cmp_func(s, src[0], ref[0] + x + y*stride, stride, h);
220  if(chroma)
221  uvdxy= (x&1) + 2*(y&1);
222  }
223  if(chroma){
224  uint8_t * const uvtemp= c->temp + 16*stride;
225  c->hpel_put[size+1][uvdxy](uvtemp , ref[1] + (x>>1) + (y>>1)*uvstride, uvstride, h>>1);
226  c->hpel_put[size+1][uvdxy](uvtemp+8, ref[2] + (x>>1) + (y>>1)*uvstride, uvstride, h>>1);
227  d += chroma_cmp_func(s, uvtemp , src[1], uvstride, h>>1);
228  d += chroma_cmp_func(s, uvtemp+8, src[2], uvstride, h>>1);
229  }
230  return d;
231 }
232 
233 static int cmp_simple(MpegEncContext *s, const int x, const int y,
234  int ref_index, int src_index,
235  me_cmp_func cmp_func, me_cmp_func chroma_cmp_func){
236  return cmp_inline(s,x,y,0,0,0,16,ref_index,src_index, cmp_func, chroma_cmp_func, 0, 0);
237 }
238 
239 static int cmp_fpel_internal(MpegEncContext *s, const int x, const int y,
240  const int size, const int h, int ref_index, int src_index,
241  me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
242  if(flags&FLAG_DIRECT){
243  return cmp_direct_inline(s,x,y,0,0,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL);
244  }else{
245  return cmp_inline(s,x,y,0,0,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0, flags&FLAG_CHROMA);
246  }
247 }
248 
249 static int cmp_internal(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
250  const int size, const int h, int ref_index, int src_index,
251  me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
252  if(flags&FLAG_DIRECT){
253  return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL);
254  }else{
255  return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL, flags&FLAG_CHROMA);
256  }
257 }
258 
259 /** @brief compares a block (either a full macroblock or a partition thereof)
260  against a proposed motion-compensated prediction of that block
261  */
262 static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
263  const int size, const int h, int ref_index, int src_index,
264  me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
267  && flags==0 && h==16 && size==0 && subx==0 && suby==0){
268  return cmp_simple(s,x,y,ref_index,src_index, cmp_func, chroma_cmp_func);
269  }else if(av_builtin_constant_p(subx) && av_builtin_constant_p(suby)
270  && subx==0 && suby==0){
271  return cmp_fpel_internal(s,x,y,size,h,ref_index,src_index, cmp_func, chroma_cmp_func,flags);
272  }else{
273  return cmp_internal(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags);
274  }
275 }
276 
277 static int cmp_hpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
278  const int size, const int h, int ref_index, int src_index,
279  me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
280  if(flags&FLAG_DIRECT){
281  return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0);
282  }else{
283  return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0, flags&FLAG_CHROMA);
284  }
285 }
286 
287 static int cmp_qpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
288  const int size, const int h, int ref_index, int src_index,
289  me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
290  if(flags&FLAG_DIRECT){
291  return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 1);
292  }else{
293  return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 1, flags&FLAG_CHROMA);
294  }
295 }
296 
297 #include "motion_est_template.c"
298 
299 static int zero_cmp(MpegEncContext *s, const uint8_t *a, const uint8_t *b,
300  ptrdiff_t stride, int h)
301 {
302  return 0;
303 }
304 
305 static void zero_hpel(uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h){
306 }
307 
309  MotionEstContext * const c= &s->me;
310  int cache_size= FFMIN(ME_MAP_SIZE>>ME_MAP_SHIFT, 1<<ME_MAP_SHIFT);
311  int dia_size= FFMAX(FFABS(s->avctx->dia_size)&255, FFABS(s->avctx->pre_dia_size)&255);
312  int ret;
313 
314  if(FFMIN(s->avctx->dia_size, s->avctx->pre_dia_size) < -FFMIN(ME_MAP_SIZE, MAX_SAB_SIZE)){
315  av_log(s->avctx, AV_LOG_ERROR, "ME_MAP size is too small for SAB diamond\n");
316  return -1;
317  }
318 
319  c->avctx= s->avctx;
320 
321  if(s->codec_id == AV_CODEC_ID_H261)
322  c->avctx->me_sub_cmp = c->avctx->me_cmp;
323 
324  if(cache_size < 2*dia_size && !c->stride){
325  av_log(s->avctx, AV_LOG_INFO, "ME_MAP size may be a little small for the selected diamond size\n");
326  }
327 
328  ret = ff_set_cmp(&s->mecc, s->mecc.me_pre_cmp, c->avctx->me_pre_cmp);
329  ret |= ff_set_cmp(&s->mecc, s->mecc.me_cmp, c->avctx->me_cmp);
330  ret |= ff_set_cmp(&s->mecc, s->mecc.me_sub_cmp, c->avctx->me_sub_cmp);
331  ret |= ff_set_cmp(&s->mecc, s->mecc.mb_cmp, c->avctx->mb_cmp);
332  if (ret < 0)
333  return ret;
334 
335  c->flags = get_flags(c, 0, c->avctx->me_cmp &FF_CMP_CHROMA);
336  c->sub_flags= get_flags(c, 0, c->avctx->me_sub_cmp&FF_CMP_CHROMA);
337  c->mb_flags = get_flags(c, 0, c->avctx->mb_cmp &FF_CMP_CHROMA);
338 
339 /*FIXME s->no_rounding b_type*/
340  if (s->avctx->flags & AV_CODEC_FLAG_QPEL) {
341  c->sub_motion_search= qpel_motion_search;
342  c->qpel_avg = s->qdsp.avg_qpel_pixels_tab;
343  if (s->no_rounding)
344  c->qpel_put = s->qdsp.put_no_rnd_qpel_pixels_tab;
345  else
346  c->qpel_put = s->qdsp.put_qpel_pixels_tab;
347  }else{
348  if(c->avctx->me_sub_cmp&FF_CMP_CHROMA)
349  c->sub_motion_search= hpel_motion_search;
350  else if( c->avctx->me_sub_cmp == FF_CMP_SAD
351  && c->avctx-> me_cmp == FF_CMP_SAD
352  && c->avctx-> mb_cmp == FF_CMP_SAD)
353  c->sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles
354  else
355  c->sub_motion_search= hpel_motion_search;
356  }
357  c->hpel_avg = s->hdsp.avg_pixels_tab;
358  if (s->no_rounding)
359  c->hpel_put = s->hdsp.put_no_rnd_pixels_tab;
360  else
361  c->hpel_put = s->hdsp.put_pixels_tab;
362 
363  if(s->linesize){
364  c->stride = s->linesize;
365  c->uvstride= s->uvlinesize;
366  }else{
367  c->stride = 16*s->mb_width + 32;
368  c->uvstride= 8*s->mb_width + 16;
369  }
370 
371  /* 8x8 fullpel search would need a 4x4 chroma compare, which we do
372  * not have yet, and even if we had, the motion estimation code
373  * does not expect it. */
374  if (s->codec_id != AV_CODEC_ID_SNOW) {
375  if ((c->avctx->me_cmp & FF_CMP_CHROMA) /* && !s->mecc.me_cmp[2] */)
376  s->mecc.me_cmp[2] = zero_cmp;
377  if ((c->avctx->me_sub_cmp & FF_CMP_CHROMA) && !s->mecc.me_sub_cmp[2])
378  s->mecc.me_sub_cmp[2] = zero_cmp;
379  c->hpel_put[2][0]= c->hpel_put[2][1]=
380  c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel;
381  }
382 
383  if(s->codec_id == AV_CODEC_ID_H261){
384  c->sub_motion_search= no_sub_motion_search;
385  }
386 
387  return 0;
388 }
389 
390 #define CHECK_SAD_HALF_MV(suffix, x, y) \
391 {\
392  d = s->mecc.pix_abs[size][(x ? 1 : 0) + (y ? 2 : 0)](NULL, pix, ptr + ((x) >> 1), stride, h); \
393  d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*penalty_factor;\
394  COPY3_IF_LT(dminh, d, dx, x, dy, y)\
395 }
396 
398  int *mx_ptr, int *my_ptr, int dmin,
399  int src_index, int ref_index,
400  int size, int h)
401 {
402  MotionEstContext * const c= &s->me;
403  const int penalty_factor= c->sub_penalty_factor;
404  int mx, my, dminh;
405  const uint8_t *pix, *ptr;
406  int stride= c->stride;
408 
409  av_assert2(c->sub_flags == 0);
410 
411  if(c->skip){
412  *mx_ptr = 0;
413  *my_ptr = 0;
414  return dmin;
415  }
416 
417  pix = c->src[src_index][0];
418 
419  mx = *mx_ptr;
420  my = *my_ptr;
421  ptr = c->ref[ref_index][0] + (my * stride) + mx;
422 
423  dminh = dmin;
424 
425  if (mx > xmin && mx < xmax &&
426  my > ymin && my < ymax) {
427  int dx=0, dy=0;
428  int d, pen_x, pen_y;
429  const int index= my*(1<<ME_MAP_SHIFT) + mx;
430  const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)];
431  const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)];
432  const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)];
433  const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)];
434  mx += mx;
435  my += my;
436 
437 
438  pen_x= pred_x + mx;
439  pen_y= pred_y + my;
440 
441  ptr-= stride;
442  if(t<=b){
443  CHECK_SAD_HALF_MV(y2 , 0, -1)
444  if(l<=r){
445  CHECK_SAD_HALF_MV(xy2, -1, -1)
446  if(t+r<=b+l){
447  CHECK_SAD_HALF_MV(xy2, +1, -1)
448  ptr+= stride;
449  }else{
450  ptr+= stride;
451  CHECK_SAD_HALF_MV(xy2, -1, +1)
452  }
453  CHECK_SAD_HALF_MV(x2 , -1, 0)
454  }else{
455  CHECK_SAD_HALF_MV(xy2, +1, -1)
456  if(t+l<=b+r){
457  CHECK_SAD_HALF_MV(xy2, -1, -1)
458  ptr+= stride;
459  }else{
460  ptr+= stride;
461  CHECK_SAD_HALF_MV(xy2, +1, +1)
462  }
463  CHECK_SAD_HALF_MV(x2 , +1, 0)
464  }
465  }else{
466  if(l<=r){
467  if(t+l<=b+r){
468  CHECK_SAD_HALF_MV(xy2, -1, -1)
469  ptr+= stride;
470  }else{
471  ptr+= stride;
472  CHECK_SAD_HALF_MV(xy2, +1, +1)
473  }
474  CHECK_SAD_HALF_MV(x2 , -1, 0)
475  CHECK_SAD_HALF_MV(xy2, -1, +1)
476  }else{
477  if(t+r<=b+l){
478  CHECK_SAD_HALF_MV(xy2, +1, -1)
479  ptr+= stride;
480  }else{
481  ptr+= stride;
482  CHECK_SAD_HALF_MV(xy2, -1, +1)
483  }
484  CHECK_SAD_HALF_MV(x2 , +1, 0)
485  CHECK_SAD_HALF_MV(xy2, +1, +1)
486  }
487  CHECK_SAD_HALF_MV(y2 , 0, +1)
488  }
489  mx+=dx;
490  my+=dy;
491 
492  }else{
493  mx += mx;
494  my += my;
495  }
496 
497  *mx_ptr = mx;
498  *my_ptr = my;
499  return dminh;
500 }
501 
502 static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4)
503 {
504  const int xy= s->mb_x + s->mb_y*s->mb_stride;
505 
506  s->p_mv_table[xy][0] = mx;
507  s->p_mv_table[xy][1] = my;
508 
509  /* has already been set to the 4 MV if 4MV is done */
510  if(mv4){
511  int mot_xy= s->block_index[0];
512 
513  s->current_picture.motion_val[0][mot_xy ][0] = mx;
514  s->current_picture.motion_val[0][mot_xy ][1] = my;
515  s->current_picture.motion_val[0][mot_xy + 1][0] = mx;
516  s->current_picture.motion_val[0][mot_xy + 1][1] = my;
517 
518  mot_xy += s->b8_stride;
519  s->current_picture.motion_val[0][mot_xy ][0] = mx;
520  s->current_picture.motion_val[0][mot_xy ][1] = my;
521  s->current_picture.motion_val[0][mot_xy + 1][0] = mx;
522  s->current_picture.motion_val[0][mot_xy + 1][1] = my;
523  }
524 }
525 
526 /**
527  * get fullpel ME search limits.
528  */
529 static inline void get_limits(MpegEncContext *s, int x, int y)
530 {
531  MotionEstContext * const c= &s->me;
532  int range= c->avctx->me_range >> (1 + !!(c->flags&FLAG_QPEL));
533  int max_range = MAX_MV >> (1 + !!(c->flags&FLAG_QPEL));
534 /*
535  if(c->avctx->me_range) c->range= c->avctx->me_range >> 1;
536  else c->range= 16;
537 */
538  if (s->unrestricted_mv) {
539  c->xmin = - x - 16;
540  c->ymin = - y - 16;
541  c->xmax = - x + s->width;
542  c->ymax = - y + s->height;
543  } else if (s->out_format == FMT_H261){
544  // Search range of H.261 is different from other codec standards
545  c->xmin = (x > 15) ? - 15 : 0;
546  c->ymin = (y > 15) ? - 15 : 0;
547  c->xmax = (x < s->mb_width * 16 - 16) ? 15 : 0;
548  c->ymax = (y < s->mb_height * 16 - 16) ? 15 : 0;
549  } else {
550  c->xmin = - x;
551  c->ymin = - y;
552  c->xmax = - x + s->mb_width *16 - 16;
553  c->ymax = - y + s->mb_height*16 - 16;
554  }
555  if(!range || range > max_range)
556  range = max_range;
557  if(range){
558  c->xmin = FFMAX(c->xmin,-range);
559  c->xmax = FFMIN(c->xmax, range);
560  c->ymin = FFMAX(c->ymin,-range);
561  c->ymax = FFMIN(c->ymax, range);
562  }
563 }
564 
565 static inline void init_mv4_ref(MotionEstContext *c){
566  const int stride= c->stride;
567 
568  c->ref[1][0] = c->ref[0][0] + 8;
569  c->ref[2][0] = c->ref[0][0] + 8*stride;
570  c->ref[3][0] = c->ref[2][0] + 8;
571  c->src[1][0] = c->src[0][0] + 8;
572  c->src[2][0] = c->src[0][0] + 8*stride;
573  c->src[3][0] = c->src[2][0] + 8;
574 }
575 
576 static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
577 {
578  MotionEstContext * const c= &s->me;
579  const int size= 1;
580  const int h=8;
581  int block;
582  int P[10][2];
583  int dmin_sum=0, mx4_sum=0, my4_sum=0, i;
584  int same=1;
585  const int stride= c->stride;
586  const uint8_t *mv_penalty = c->current_mv_penalty;
587  int safety_clipping= s->unrestricted_mv && (s->width&15) && (s->height&15);
588 
589  init_mv4_ref(c);
590 
591  for(block=0; block<4; block++){
592  int mx4, my4;
593  int pred_x4, pred_y4;
594  int dmin4;
595  static const int off[4]= {2, 1, 1, -1};
596  const int mot_stride = s->b8_stride;
597  const int mot_xy = s->block_index[block];
598 
599  if(safety_clipping){
600  c->xmax = - 16*s->mb_x + s->width - 8*(block &1);
601  c->ymax = - 16*s->mb_y + s->height - 8*(block>>1);
602  }
603 
604  P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
605  P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
606 
607  if (P_LEFT[0] > c->xmax * (1 << shift)) P_LEFT[0] = c->xmax * (1 << shift);
608 
609  /* special case for first line */
610  if (s->first_slice_line && block<2) {
611  c->pred_x= pred_x4= P_LEFT[0];
612  c->pred_y= pred_y4= P_LEFT[1];
613  } else {
614  P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0];
615  P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1];
616  P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0];
617  P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1];
618  if (P_TOP[1] > c->ymax * (1 << shift)) P_TOP[1] = c->ymax * (1 << shift);
619  if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift);
620  if (P_TOPRIGHT[0] > c->xmax * (1 << shift)) P_TOPRIGHT[0] = c->xmax * (1 << shift);
621  if (P_TOPRIGHT[1] > c->ymax * (1 << shift)) P_TOPRIGHT[1] = c->ymax * (1 << shift);
622 
623  P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
624  P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
625 
626  c->pred_x= pred_x4 = P_MEDIAN[0];
627  c->pred_y= pred_y4 = P_MEDIAN[1];
628  }
629  P_MV1[0]= mx;
630  P_MV1[1]= my;
631  if(safety_clipping)
632  for(i=1; i<10; i++){
633  if (s->first_slice_line && block<2 && i>1 && i<9)
634  continue;
635  if (i>4 && i<9)
636  continue;
637  if (P[i][0] > c->xmax * (1 << shift)) P[i][0] = c->xmax * (1 << shift);
638  if (P[i][1] > c->ymax * (1 << shift)) P[i][1] = c->ymax * (1 <<shift );
639  }
640 
641  dmin4 = epzs_motion_search2(s, &mx4, &my4, P, block, block, s->p_mv_table, (1<<16)>>shift, 1);
642 
643  dmin4= c->sub_motion_search(s, &mx4, &my4, dmin4, block, block, size, h);
644 
645  if (s->mecc.me_sub_cmp[0] != s->mecc.mb_cmp[0]) {
646  int dxy;
647  const int offset= ((block&1) + (block>>1)*stride)*8;
648  uint8_t *dest_y = c->scratchpad + offset;
649  if(s->quarter_sample){
650  const uint8_t *ref = c->ref[block][0] + (mx4>>2) + (my4>>2)*stride;
651  dxy = ((my4 & 3) << 2) | (mx4 & 3);
652 
653  if(s->no_rounding)
654  s->qdsp.put_no_rnd_qpel_pixels_tab[1][dxy](dest_y, ref, stride);
655  else
656  s->qdsp.put_qpel_pixels_tab[1][dxy](dest_y, ref, stride);
657  }else{
658  const uint8_t *ref = c->ref[block][0] + (mx4>>1) + (my4>>1)*stride;
659  dxy = ((my4 & 1) << 1) | (mx4 & 1);
660 
661  if(s->no_rounding)
662  s->hdsp.put_no_rnd_pixels_tab[1][dxy](dest_y , ref , stride, h);
663  else
664  s->hdsp.put_pixels_tab [1][dxy](dest_y , ref , stride, h);
665  }
666  dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*c->mb_penalty_factor;
667  }else
668  dmin_sum+= dmin4;
669 
670  if(s->quarter_sample){
671  mx4_sum+= mx4/2;
672  my4_sum+= my4/2;
673  }else{
674  mx4_sum+= mx4;
675  my4_sum+= my4;
676  }
677 
678  s->current_picture.motion_val[0][s->block_index[block]][0] = mx4;
679  s->current_picture.motion_val[0][s->block_index[block]][1] = my4;
680 
681  if(mx4 != mx || my4 != my) same=0;
682  }
683 
684  if(same)
685  return INT_MAX;
686 
687  if (s->mecc.me_sub_cmp[0] != s->mecc.mb_cmp[0]) {
688  dmin_sum += s->mecc.mb_cmp[0](s,
689  s->new_picture->data[0] +
690  s->mb_x * 16 + s->mb_y * 16 * stride,
691  c->scratchpad, stride, 16);
692  }
693 
694  if(c->avctx->mb_cmp&FF_CMP_CHROMA){
695  int dxy;
696  int mx, my;
697  int offset;
698 
699  mx= ff_h263_round_chroma(mx4_sum);
700  my= ff_h263_round_chroma(my4_sum);
701  dxy = ((my & 1) << 1) | (mx & 1);
702 
703  offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;
704 
705  if(s->no_rounding){
706  s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad , s->last_picture.f->data[1] + offset, s->uvlinesize, 8);
707  s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad + 8, s->last_picture.f->data[2] + offset, s->uvlinesize, 8);
708  }else{
709  s->hdsp.put_pixels_tab [1][dxy](c->scratchpad , s->last_picture.f->data[1] + offset, s->uvlinesize, 8);
710  s->hdsp.put_pixels_tab [1][dxy](c->scratchpad + 8, s->last_picture.f->data[2] + offset, s->uvlinesize, 8);
711  }
712 
713  dmin_sum += s->mecc.mb_cmp[1](s, s->new_picture->data[1] + s->mb_x * 8 + s->mb_y * 8 * s->uvlinesize, c->scratchpad, s->uvlinesize, 8);
714  dmin_sum += s->mecc.mb_cmp[1](s, s->new_picture->data[2] + s->mb_x * 8 + s->mb_y * 8 * s->uvlinesize, c->scratchpad + 8, s->uvlinesize, 8);
715  }
716 
717  c->pred_x= mx;
718  c->pred_y= my;
719 
720  switch(c->avctx->mb_cmp&0xFF){
721  /*case FF_CMP_SSE:
722  return dmin_sum+ 32*s->qscale*s->qscale;*/
723  case FF_CMP_RD:
724  return dmin_sum;
725  default:
726  return dmin_sum+ 11*c->mb_penalty_factor;
727  }
728 }
729 
730 static inline void init_interlaced_ref(MpegEncContext *s, int ref_index){
731  MotionEstContext * const c= &s->me;
732 
733  c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->linesize;
734  c->src[1][0] = c->src[0][0] + s->linesize;
735  if(c->flags & FLAG_CHROMA){
736  c->ref[1+ref_index][1] = c->ref[0+ref_index][1] + s->uvlinesize;
737  c->ref[1+ref_index][2] = c->ref[0+ref_index][2] + s->uvlinesize;
738  c->src[1][1] = c->src[0][1] + s->uvlinesize;
739  c->src[1][2] = c->src[0][2] + s->uvlinesize;
740  }
741 }
742 
743 static int interlaced_search(MpegEncContext *s, int ref_index,
744  int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my, int user_field_select)
745 {
746  MotionEstContext * const c= &s->me;
747  const int size=0;
748  const int h=8;
749  int block;
750  int P[10][2];
751  const uint8_t * const mv_penalty = c->current_mv_penalty;
752  int same=1;
753  const int stride= 2*s->linesize;
754  int dmin_sum= 0;
755  const int mot_stride= s->mb_stride;
756  const int xy= s->mb_x + s->mb_y*mot_stride;
757 
758  c->ymin>>=1;
759  c->ymax>>=1;
760  c->stride<<=1;
761  c->uvstride<<=1;
762  init_interlaced_ref(s, ref_index);
763 
764  for(block=0; block<2; block++){
765  int field_select;
766  int best_dmin= INT_MAX;
767  int best_field= -1;
768 
769  for(field_select=0; field_select<2; field_select++){
770  int dmin, mx_i, my_i;
771  int16_t (*mv_table)[2]= mv_tables[block][field_select];
772 
773  if(user_field_select){
774  av_assert1(field_select==0 || field_select==1);
775  av_assert1(field_select_tables[block][xy]==0 || field_select_tables[block][xy]==1);
776  if(field_select_tables[block][xy] != field_select)
777  continue;
778  }
779 
780  P_LEFT[0] = mv_table[xy - 1][0];
781  P_LEFT[1] = mv_table[xy - 1][1];
782  if(P_LEFT[0] > (c->xmax<<1)) P_LEFT[0] = (c->xmax<<1);
783 
784  c->pred_x= P_LEFT[0];
785  c->pred_y= P_LEFT[1];
786 
787  if(!s->first_slice_line){
788  P_TOP[0] = mv_table[xy - mot_stride][0];
789  P_TOP[1] = mv_table[xy - mot_stride][1];
790  P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0];
791  P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1];
792  if(P_TOP[1] > (c->ymax<<1)) P_TOP[1] = (c->ymax<<1);
793  if (P_TOPRIGHT[0] < c->xmin * (1 << 1)) P_TOPRIGHT[0] = c->xmin * (1 << 1);
794  if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1);
795  if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->ymax<<1);
796 
797  P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
798  P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
799  }
800  P_MV1[0]= mx; //FIXME not correct if block != field_select
801  P_MV1[1]= my / 2;
802 
803  dmin = epzs_motion_search2(s, &mx_i, &my_i, P, block, field_select+ref_index, mv_table, (1<<16)>>1, 0);
804 
805  dmin= c->sub_motion_search(s, &mx_i, &my_i, dmin, block, field_select+ref_index, size, h);
806 
807  mv_table[xy][0]= mx_i;
808  mv_table[xy][1]= my_i;
809 
810  if (s->mecc.me_sub_cmp[0] != s->mecc.mb_cmp[0]) {
811  int dxy;
812 
813  //FIXME chroma ME
814  const uint8_t *ref = c->ref[field_select+ref_index][0] + (mx_i>>1) + (my_i>>1)*stride;
815  dxy = ((my_i & 1) << 1) | (mx_i & 1);
816 
817  if(s->no_rounding){
818  s->hdsp.put_no_rnd_pixels_tab[size][dxy](c->scratchpad, ref , stride, h);
819  }else{
820  s->hdsp.put_pixels_tab [size][dxy](c->scratchpad, ref , stride, h);
821  }
822  dmin = s->mecc.mb_cmp[size](s, c->src[block][0], c->scratchpad, stride, h);
823  dmin+= (mv_penalty[mx_i-c->pred_x] + mv_penalty[my_i-c->pred_y] + 1)*c->mb_penalty_factor;
824  }else
825  dmin+= c->mb_penalty_factor; //field_select bits
826 
827  dmin += field_select != block; //slightly prefer same field
828 
829  if(dmin < best_dmin){
830  best_dmin= dmin;
831  best_field= field_select;
832  }
833  }
834  {
835  int16_t (*mv_table)[2]= mv_tables[block][best_field];
836 
837  if(mv_table[xy][0] != mx) same=0; //FIXME check if these checks work and are any good at all
838  if(mv_table[xy][1]&1) same=0;
839  if(mv_table[xy][1]*2 != my) same=0;
840  if(best_field != block) same=0;
841  }
842 
843  field_select_tables[block][xy]= best_field;
844  dmin_sum += best_dmin;
845  }
846 
847  c->ymin *= 2;
848  c->ymax<<=1;
849  c->stride>>=1;
850  c->uvstride>>=1;
851 
852  if(same)
853  return INT_MAX;
854 
855  switch(c->avctx->mb_cmp&0xFF){
856  /*case FF_CMP_SSE:
857  return dmin_sum+ 32*s->qscale*s->qscale;*/
858  case FF_CMP_RD:
859  return dmin_sum;
860  default:
861  return dmin_sum+ 11*c->mb_penalty_factor;
862  }
863 }
864 
865 static inline int get_penalty_factor(int lambda, int lambda2, int type){
866  switch(type&0xFF){
867  default:
868  case FF_CMP_SAD:
869  return lambda>>FF_LAMBDA_SHIFT;
870  case FF_CMP_DCT:
871  return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
872  case FF_CMP_W53:
873  return (4*lambda)>>(FF_LAMBDA_SHIFT);
874  case FF_CMP_W97:
875  return (2*lambda)>>(FF_LAMBDA_SHIFT);
876  case FF_CMP_SATD:
877  case FF_CMP_DCT264:
878  return (2*lambda)>>FF_LAMBDA_SHIFT;
879  case FF_CMP_RD:
880  case FF_CMP_PSNR:
881  case FF_CMP_SSE:
882  case FF_CMP_NSSE:
883  return lambda2>>FF_LAMBDA_SHIFT;
884  case FF_CMP_BIT:
885  case FF_CMP_MEDIAN_SAD:
886  return 1;
887  }
888 }
889 
891  int mb_x, int mb_y)
892 {
893  MotionEstContext * const c= &s->me;
894  const uint8_t *pix, *ppix;
895  int sum, mx = 0, my = 0, dmin = 0;
896  int varc; ///< the variance of the block (sum of squared (p[y][x]-average))
897  int vard; ///< sum of squared differences with the estimated motion vector
898  int P[10][2];
899  const int shift= 1+s->quarter_sample;
900  int mb_type=0;
901 
902  init_ref(c, s->new_picture->data, s->last_picture.f->data, NULL, 16*mb_x, 16*mb_y, 0);
903 
904  av_assert0(s->quarter_sample==0 || s->quarter_sample==1);
905  av_assert0(s->linesize == c->stride);
906  av_assert0(s->uvlinesize == c->uvstride);
907 
908  c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
909  c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
910  c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
911  c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
912 
913  get_limits(s, 16*mb_x, 16*mb_y);
914  c->skip=0;
915 
916  /* intra / predictive decision */
917  pix = c->src[0][0];
918  sum = s->mpvencdsp.pix_sum(pix, s->linesize);
919  varc = s->mpvencdsp.pix_norm1(pix, s->linesize) -
920  (((unsigned) sum * sum) >> 8) + 500;
921 
922  s->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
923  s->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;
924  c->mb_var_sum_temp += (varc+128)>>8;
925 
926  if (s->motion_est != FF_ME_ZERO) {
927  const int mot_stride = s->b8_stride;
928  const int mot_xy = s->block_index[0];
929 
930  P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
931  P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
932 
933  if (P_LEFT[0] > (c->xmax << shift))
934  P_LEFT[0] = c->xmax << shift;
935 
936  if (!s->first_slice_line) {
937  P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0];
938  P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1];
939  P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0];
940  P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1];
941  if (P_TOP[1] > (c->ymax << shift))
942  P_TOP[1] = c->ymax << shift;
943  if (P_TOPRIGHT[0] < (c->xmin * (1 << shift)))
944  P_TOPRIGHT[0] = c->xmin * (1 << shift);
945  if (P_TOPRIGHT[1] > (c->ymax * (1 << shift)))
946  P_TOPRIGHT[1] = c->ymax * (1 << shift);
947 
948  P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
949  P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
950 
951  if (s->out_format == FMT_H263) {
952  c->pred_x = P_MEDIAN[0];
953  c->pred_y = P_MEDIAN[1];
954  } else { /* MPEG-1 at least */
955  c->pred_x = P_LEFT[0];
956  c->pred_y = P_LEFT[1];
957  }
958  } else {
959  c->pred_x = P_LEFT[0];
960  c->pred_y = P_LEFT[1];
961  }
962  dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16);
963  }
964 
965  /* At this point (mx,my) are full-pell and the relative displacement */
966  ppix = c->ref[0][0] + (my * s->linesize) + mx;
967 
968  vard = s->mecc.sse[0](NULL, pix, ppix, s->linesize, 16);
969 
970  s->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;
971  c->mc_mb_var_sum_temp += (vard+128)>>8;
972 
973  if (c->avctx->mb_decision > FF_MB_DECISION_SIMPLE) {
974  int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
975  int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
976  c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
977 
978  if (vard*2 + 200*256 > varc && !s->intra_penalty)
979  mb_type|= CANDIDATE_MB_TYPE_INTRA;
980  if (varc*2 + 200*256 > vard || s->qscale > 24){
981 // if (varc*2 + 200*256 + 50*(s->lambda2>>FF_LAMBDA_SHIFT) > vard){
982  mb_type|= CANDIDATE_MB_TYPE_INTER;
983  c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
984  if (s->mpv_flags & FF_MPV_FLAG_MV0)
985  if(mx || my)
986  mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference
987  }else{
988  mx *= 1 << shift;
989  my *= 1 << shift;
990  }
991  if ((s->avctx->flags & AV_CODEC_FLAG_4MV)
992  && !c->skip && varc>50<<8 && vard>10<<8){
993  if(h263_mv4_search(s, mx, my, shift) < INT_MAX)
994  mb_type|=CANDIDATE_MB_TYPE_INTER4V;
995 
996  set_p_mv_tables(s, mx, my, 0);
997  }else
998  set_p_mv_tables(s, mx, my, 1);
999  if ((s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
1000  && !c->skip){ //FIXME varc/d checks
1001  if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX)
1002  mb_type |= CANDIDATE_MB_TYPE_INTER_I;
1003  }
1004  }else{
1005  int intra_score, i;
1006  mb_type= CANDIDATE_MB_TYPE_INTER;
1007 
1008  dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
1009  if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
1010  dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1);
1011 
1012  if ((s->avctx->flags & AV_CODEC_FLAG_4MV)
1013  && !c->skip && varc>50<<8 && vard>10<<8){
1014  int dmin4= h263_mv4_search(s, mx, my, shift);
1015  if(dmin4 < dmin){
1016  mb_type= CANDIDATE_MB_TYPE_INTER4V;
1017  dmin=dmin4;
1018  }
1019  }
1020  if ((s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
1021  && !c->skip){ //FIXME varc/d checks
1022  int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0);
1023  if(dmin_i < dmin){
1024  mb_type = CANDIDATE_MB_TYPE_INTER_I;
1025  dmin= dmin_i;
1026  }
1027  }
1028 
1029  set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V);
1030 
1031  /* get intra luma score */
1032  if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){
1033  intra_score= varc - 500;
1034  }else{
1035  unsigned mean = (sum+128)>>8;
1036  mean*= 0x01010101;
1037 
1038  for(i=0; i<16; i++){
1039  *(uint32_t*)(&c->scratchpad[i*s->linesize+ 0]) = mean;
1040  *(uint32_t*)(&c->scratchpad[i*s->linesize+ 4]) = mean;
1041  *(uint32_t*)(&c->scratchpad[i*s->linesize+ 8]) = mean;
1042  *(uint32_t*)(&c->scratchpad[i*s->linesize+12]) = mean;
1043  }
1044 
1045  intra_score= s->mecc.mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16);
1046  }
1047  intra_score += c->mb_penalty_factor*16 + s->intra_penalty;
1048 
1049  if(intra_score < dmin){
1050  mb_type= CANDIDATE_MB_TYPE_INTRA;
1051  s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
1052  }else
1053  s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = 0;
1054 
1055  {
1056  int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
1057  int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
1058  c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
1059  }
1060  }
1061 
1062  s->mb_type[mb_y*s->mb_stride + mb_x]= mb_type;
1063 }
1064 
1066  int mb_x, int mb_y)
1067 {
1068  MotionEstContext * const c= &s->me;
1069  int mx, my, dmin;
1070  int P[10][2];
1071  const int shift= 1+s->quarter_sample;
1072  const int xy= mb_x + mb_y*s->mb_stride;
1073  init_ref(c, s->new_picture->data, s->last_picture.f->data, NULL, 16*mb_x, 16*mb_y, 0);
1074 
1075  av_assert0(s->quarter_sample==0 || s->quarter_sample==1);
1076 
1077  c->pre_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp);
1078  c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
1079 
1080  get_limits(s, 16*mb_x, 16*mb_y);
1081  c->skip=0;
1082 
1083  P_LEFT[0] = s->p_mv_table[xy + 1][0];
1084  P_LEFT[1] = s->p_mv_table[xy + 1][1];
1085 
1086  if(P_LEFT[0] < (c->xmin<<shift)) P_LEFT[0] = (c->xmin<<shift);
1087 
1088  /* special case for first line */
1089  if (s->first_slice_line) {
1090  c->pred_x= P_LEFT[0];
1091  c->pred_y= P_LEFT[1];
1092  P_TOP[0]= P_TOPRIGHT[0]= P_MEDIAN[0]=
1093  P_TOP[1]= P_TOPRIGHT[1]= P_MEDIAN[1]= 0; //FIXME
1094  } else {
1095  P_TOP[0] = s->p_mv_table[xy + s->mb_stride ][0];
1096  P_TOP[1] = s->p_mv_table[xy + s->mb_stride ][1];
1097  P_TOPRIGHT[0] = s->p_mv_table[xy + s->mb_stride - 1][0];
1098  P_TOPRIGHT[1] = s->p_mv_table[xy + s->mb_stride - 1][1];
1099  if(P_TOP[1] < (c->ymin<<shift)) P_TOP[1] = (c->ymin<<shift);
1100  if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
1101  if(P_TOPRIGHT[1] < (c->ymin<<shift)) P_TOPRIGHT[1]= (c->ymin<<shift);
1102 
1103  P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
1104  P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
1105 
1106  c->pred_x = P_MEDIAN[0];
1107  c->pred_y = P_MEDIAN[1];
1108  }
1109 
1110  dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16);
1111 
1112  s->p_mv_table[xy][0] = mx<<shift;
1113  s->p_mv_table[xy][1] = my<<shift;
1114 
1115  return dmin;
1116 }
1117 
1118 static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
1119  int16_t (*mv_table)[2], int ref_index, int f_code)
1120 {
1121  MotionEstContext * const c= &s->me;
1122  int mx = 0, my = 0, dmin = 0;
1123  int P[10][2];
1124  const int shift= 1+s->quarter_sample;
1125  const int mot_stride = s->mb_stride;
1126  const int mot_xy = mb_y*mot_stride + mb_x;
1127  const uint8_t * const mv_penalty = c->mv_penalty[f_code] + MAX_DMV;
1128  int mv_scale;
1129 
1130  c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
1131  c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
1132  c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
1133  c->current_mv_penalty= mv_penalty;
1134 
1135  get_limits(s, 16*mb_x, 16*mb_y);
1136 
1137  if (s->motion_est != FF_ME_ZERO) {
1138  P_LEFT[0] = mv_table[mot_xy - 1][0];
1139  P_LEFT[1] = mv_table[mot_xy - 1][1];
1140 
1141  if (P_LEFT[0] > (c->xmax << shift)) P_LEFT[0] = (c->xmax << shift);
1142 
1143  /* special case for first line */
1144  if (!s->first_slice_line) {
1145  P_TOP[0] = mv_table[mot_xy - mot_stride ][0];
1146  P_TOP[1] = mv_table[mot_xy - mot_stride ][1];
1147  P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0];
1148  P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1];
1149  if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift);
1150  if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift);
1151  if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift);
1152 
1153  P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
1154  P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
1155  }
1156  c->pred_x = P_LEFT[0];
1157  c->pred_y = P_LEFT[1];
1158 
1159  if(mv_table == s->b_forw_mv_table){
1160  mv_scale= (s->pb_time<<16) / (s->pp_time<<shift);
1161  }else{
1162  mv_scale = ((s->pb_time - s->pp_time) * (1 << 16)) / (s->pp_time<<shift);
1163  }
1164 
1165  dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, ref_index, s->p_mv_table, mv_scale, 0, 16);
1166  }
1167 
1168  dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16);
1169 
1170  if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
1171  dmin= get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1);
1172 
1173 // s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
1174  mv_table[mot_xy][0]= mx;
1175  mv_table[mot_xy][1]= my;
1176 
1177  return dmin;
1178 }
1179 
1180 static inline int check_bidir_mv(MpegEncContext * s,
1181  int motion_fx, int motion_fy,
1182  int motion_bx, int motion_by,
1183  int pred_fx, int pred_fy,
1184  int pred_bx, int pred_by,
1185  int size, int h)
1186 {
1187  //FIXME optimize?
1188  //FIXME better f_code prediction (max mv & distance)
1189  //FIXME pointers
1190  MotionEstContext * const c= &s->me;
1191  const uint8_t * const mv_penalty_f = c->mv_penalty[s->f_code] + MAX_DMV; // f_code of the prev frame
1192  const uint8_t * const mv_penalty_b = c->mv_penalty[s->b_code] + MAX_DMV; // f_code of the prev frame
1193  int stride= c->stride;
1194  uint8_t *dest_y = c->scratchpad;
1195  const uint8_t *ptr;
1196  int dxy;
1197  int src_x, src_y;
1198  int fbmin;
1199  const uint8_t *const *src_data = c->src[0];
1200  const uint8_t *const *ref_data = c->ref[0];
1201  const uint8_t *const *ref2_data = c->ref[2];
1202 
1203  if(s->quarter_sample){
1204  dxy = ((motion_fy & 3) << 2) | (motion_fx & 3);
1205  src_x = motion_fx >> 2;
1206  src_y = motion_fy >> 2;
1207 
1208  ptr = ref_data[0] + (src_y * stride) + src_x;
1209  s->qdsp.put_qpel_pixels_tab[0][dxy](dest_y, ptr, stride);
1210 
1211  dxy = ((motion_by & 3) << 2) | (motion_bx & 3);
1212  src_x = motion_bx >> 2;
1213  src_y = motion_by >> 2;
1214 
1215  ptr = ref2_data[0] + (src_y * stride) + src_x;
1216  s->qdsp.avg_qpel_pixels_tab[size][dxy](dest_y, ptr, stride);
1217  }else{
1218  dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);
1219  src_x = motion_fx >> 1;
1220  src_y = motion_fy >> 1;
1221 
1222  ptr = ref_data[0] + (src_y * stride) + src_x;
1223  s->hdsp.put_pixels_tab[size][dxy](dest_y , ptr , stride, h);
1224 
1225  dxy = ((motion_by & 1) << 1) | (motion_bx & 1);
1226  src_x = motion_bx >> 1;
1227  src_y = motion_by >> 1;
1228 
1229  ptr = ref2_data[0] + (src_y * stride) + src_x;
1230  s->hdsp.avg_pixels_tab[size][dxy](dest_y , ptr , stride, h);
1231  }
1232 
1233  fbmin = (mv_penalty_f[motion_fx-pred_fx] + mv_penalty_f[motion_fy-pred_fy])*c->mb_penalty_factor
1234  +(mv_penalty_b[motion_bx-pred_bx] + mv_penalty_b[motion_by-pred_by])*c->mb_penalty_factor
1235  + s->mecc.mb_cmp[size](s, src_data[0], dest_y, stride, h); // FIXME new_pic
1236 
1237  if(c->avctx->mb_cmp&FF_CMP_CHROMA){
1238  }
1239  //FIXME CHROMA !!!
1240 
1241  return fbmin;
1242 }
1243 
1244 /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/
1245 static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
1246 {
1247  MotionEstContext * const c= &s->me;
1248  const int mot_stride = s->mb_stride;
1249  const int xy = mb_y *mot_stride + mb_x;
1250  int fbmin;
1251  int pred_fx= s->b_bidir_forw_mv_table[xy-1][0];
1252  int pred_fy= s->b_bidir_forw_mv_table[xy-1][1];
1253  int pred_bx= s->b_bidir_back_mv_table[xy-1][0];
1254  int pred_by= s->b_bidir_back_mv_table[xy-1][1];
1255  int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0];
1256  int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1];
1257  int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0];
1258  int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1];
1259  const int flags= c->sub_flags;
1260  const int qpel= flags&FLAG_QPEL;
1261  const int shift= 1+qpel;
1262  const int xmin= c->xmin * (1 << shift);
1263  const int ymin= c->ymin * (1 << shift);
1264  const int xmax= c->xmax<<shift;
1265  const int ymax= c->ymax<<shift;
1266 #define HASH(fx,fy,bx,by) ((fx)+17*(fy)+63*(bx)+117*(by))
1267 #define HASH8(fx,fy,bx,by) ((uint8_t)HASH(fx,fy,bx,by))
1268  int hashidx= HASH(motion_fx,motion_fy, motion_bx, motion_by);
1269  uint8_t map[256] = { 0 };
1270 
1271  map[hashidx&255] = 1;
1272 
1273  fbmin= check_bidir_mv(s, motion_fx, motion_fy,
1274  motion_bx, motion_by,
1275  pred_fx, pred_fy,
1276  pred_bx, pred_by,
1277  0, 16);
1278 
1279  if(s->avctx->bidir_refine){
1280  int end;
1281  static const uint8_t limittab[5]={0,8,32,64,80};
1282  const int limit= limittab[s->avctx->bidir_refine];
1283  static const int8_t vect[][4]={
1284 { 0, 0, 0, 1}, { 0, 0, 0,-1}, { 0, 0, 1, 0}, { 0, 0,-1, 0}, { 0, 1, 0, 0}, { 0,-1, 0, 0}, { 1, 0, 0, 0}, {-1, 0, 0, 0},
1285 
1286 { 0, 0, 1, 1}, { 0, 0,-1,-1}, { 0, 1, 1, 0}, { 0,-1,-1, 0}, { 1, 1, 0, 0}, {-1,-1, 0, 0}, { 1, 0, 0, 1}, {-1, 0, 0,-1},
1287 { 0, 1, 0, 1}, { 0,-1, 0,-1}, { 1, 0, 1, 0}, {-1, 0,-1, 0},
1288 { 0, 0,-1, 1}, { 0, 0, 1,-1}, { 0,-1, 1, 0}, { 0, 1,-1, 0}, {-1, 1, 0, 0}, { 1,-1, 0, 0}, { 1, 0, 0,-1}, {-1, 0, 0, 1},
1289 { 0,-1, 0, 1}, { 0, 1, 0,-1}, {-1, 0, 1, 0}, { 1, 0,-1, 0},
1290 
1291 { 0, 1, 1, 1}, { 0,-1,-1,-1}, { 1, 1, 1, 0}, {-1,-1,-1, 0}, { 1, 1, 0, 1}, {-1,-1, 0,-1}, { 1, 0, 1, 1}, {-1, 0,-1,-1},
1292 { 0,-1, 1, 1}, { 0, 1,-1,-1}, {-1, 1, 1, 0}, { 1,-1,-1, 0}, { 1, 1, 0,-1}, {-1,-1, 0, 1}, { 1, 0,-1, 1}, {-1, 0, 1,-1},
1293 { 0, 1,-1, 1}, { 0,-1, 1,-1}, { 1,-1, 1, 0}, {-1, 1,-1, 0}, {-1, 1, 0, 1}, { 1,-1, 0,-1}, { 1, 0, 1,-1}, {-1, 0,-1, 1},
1294 { 0, 1, 1,-1}, { 0,-1,-1, 1}, { 1, 1,-1, 0}, {-1,-1, 1, 0}, { 1,-1, 0, 1}, {-1, 1, 0,-1}, {-1, 0, 1, 1}, { 1, 0,-1,-1},
1295 
1296 { 1, 1, 1, 1}, {-1,-1,-1,-1},
1297 { 1, 1, 1,-1}, {-1,-1,-1, 1}, { 1, 1,-1, 1}, {-1,-1, 1,-1}, { 1,-1, 1, 1}, {-1, 1,-1,-1}, {-1, 1, 1, 1}, { 1,-1,-1,-1},
1298 { 1, 1,-1,-1}, {-1,-1, 1, 1}, { 1,-1,-1, 1}, {-1, 1, 1,-1}, { 1,-1, 1,-1}, {-1, 1,-1, 1},
1299  };
1300  static const uint8_t hash[]={
1301 HASH8( 0, 0, 0, 1), HASH8( 0, 0, 0,-1), HASH8( 0, 0, 1, 0), HASH8( 0, 0,-1, 0), HASH8( 0, 1, 0, 0), HASH8( 0,-1, 0, 0), HASH8( 1, 0, 0, 0), HASH8(-1, 0, 0, 0),
1302 
1303 HASH8( 0, 0, 1, 1), HASH8( 0, 0,-1,-1), HASH8( 0, 1, 1, 0), HASH8( 0,-1,-1, 0), HASH8( 1, 1, 0, 0), HASH8(-1,-1, 0, 0), HASH8( 1, 0, 0, 1), HASH8(-1, 0, 0,-1),
1304 HASH8( 0, 1, 0, 1), HASH8( 0,-1, 0,-1), HASH8( 1, 0, 1, 0), HASH8(-1, 0,-1, 0),
1305 HASH8( 0, 0,-1, 1), HASH8( 0, 0, 1,-1), HASH8( 0,-1, 1, 0), HASH8( 0, 1,-1, 0), HASH8(-1, 1, 0, 0), HASH8( 1,-1, 0, 0), HASH8( 1, 0, 0,-1), HASH8(-1, 0, 0, 1),
1306 HASH8( 0,-1, 0, 1), HASH8( 0, 1, 0,-1), HASH8(-1, 0, 1, 0), HASH8( 1, 0,-1, 0),
1307 
1308 HASH8( 0, 1, 1, 1), HASH8( 0,-1,-1,-1), HASH8( 1, 1, 1, 0), HASH8(-1,-1,-1, 0), HASH8( 1, 1, 0, 1), HASH8(-1,-1, 0,-1), HASH8( 1, 0, 1, 1), HASH8(-1, 0,-1,-1),
1309 HASH8( 0,-1, 1, 1), HASH8( 0, 1,-1,-1), HASH8(-1, 1, 1, 0), HASH8( 1,-1,-1, 0), HASH8( 1, 1, 0,-1), HASH8(-1,-1, 0, 1), HASH8( 1, 0,-1, 1), HASH8(-1, 0, 1,-1),
1310 HASH8( 0, 1,-1, 1), HASH8( 0,-1, 1,-1), HASH8( 1,-1, 1, 0), HASH8(-1, 1,-1, 0), HASH8(-1, 1, 0, 1), HASH8( 1,-1, 0,-1), HASH8( 1, 0, 1,-1), HASH8(-1, 0,-1, 1),
1311 HASH8( 0, 1, 1,-1), HASH8( 0,-1,-1, 1), HASH8( 1, 1,-1, 0), HASH8(-1,-1, 1, 0), HASH8( 1,-1, 0, 1), HASH8(-1, 1, 0,-1), HASH8(-1, 0, 1, 1), HASH8( 1, 0,-1,-1),
1312 
1313 HASH8( 1, 1, 1, 1), HASH8(-1,-1,-1,-1),
1314 HASH8( 1, 1, 1,-1), HASH8(-1,-1,-1, 1), HASH8( 1, 1,-1, 1), HASH8(-1,-1, 1,-1), HASH8( 1,-1, 1, 1), HASH8(-1, 1,-1,-1), HASH8(-1, 1, 1, 1), HASH8( 1,-1,-1,-1),
1315 HASH8( 1, 1,-1,-1), HASH8(-1,-1, 1, 1), HASH8( 1,-1,-1, 1), HASH8(-1, 1, 1,-1), HASH8( 1,-1, 1,-1), HASH8(-1, 1,-1, 1),
1316 };
1317 
1318 #define CHECK_BIDIR(fx,fy,bx,by)\
1319  if( !map[(hashidx+HASH(fx,fy,bx,by))&255]\
1320  &&(fx<=0 || motion_fx+fx<=xmax) && (fy<=0 || motion_fy+fy<=ymax) && (bx<=0 || motion_bx+bx<=xmax) && (by<=0 || motion_by+by<=ymax)\
1321  &&(fx>=0 || motion_fx+fx>=xmin) && (fy>=0 || motion_fy+fy>=ymin) && (bx>=0 || motion_bx+bx>=xmin) && (by>=0 || motion_by+by>=ymin)){\
1322  int score;\
1323  map[(hashidx+HASH(fx,fy,bx,by))&255] = 1;\
1324  score= check_bidir_mv(s, motion_fx+fx, motion_fy+fy, motion_bx+bx, motion_by+by, pred_fx, pred_fy, pred_bx, pred_by, 0, 16);\
1325  if(score < fbmin){\
1326  hashidx += HASH(fx,fy,bx,by);\
1327  fbmin= score;\
1328  motion_fx+=fx;\
1329  motion_fy+=fy;\
1330  motion_bx+=bx;\
1331  motion_by+=by;\
1332  end=0;\
1333  }\
1334  }
1335 #define CHECK_BIDIR2(a,b,c,d)\
1336 CHECK_BIDIR(a,b,c,d)\
1337 CHECK_BIDIR(-(a),-(b),-(c),-(d))
1338 
1339  do{
1340  int i;
1341  int borderdist=0;
1342  end=1;
1343 
1344  CHECK_BIDIR2(0,0,0,1)
1345  CHECK_BIDIR2(0,0,1,0)
1346  CHECK_BIDIR2(0,1,0,0)
1347  CHECK_BIDIR2(1,0,0,0)
1348 
1349  for(i=8; i<limit; i++){
1350  int fx= motion_fx+vect[i][0];
1351  int fy= motion_fy+vect[i][1];
1352  int bx= motion_bx+vect[i][2];
1353  int by= motion_by+vect[i][3];
1354  if(borderdist<=0){
1355  int a= (xmax - FFMAX(fx,bx))|(FFMIN(fx,bx) - xmin);
1356  int b= (ymax - FFMAX(fy,by))|(FFMIN(fy,by) - ymin);
1357  if((a|b) < 0)
1358  map[(hashidx+hash[i])&255] = 1;
1359  }
1360  if(!map[(hashidx+hash[i])&255]){
1361  int score;
1362  map[(hashidx+hash[i])&255] = 1;
1363  score= check_bidir_mv(s, fx, fy, bx, by, pred_fx, pred_fy, pred_bx, pred_by, 0, 16);
1364  if(score < fbmin){
1365  hashidx += hash[i];
1366  fbmin= score;
1367  motion_fx=fx;
1368  motion_fy=fy;
1369  motion_bx=bx;
1370  motion_by=by;
1371  end=0;
1372  borderdist--;
1373  if(borderdist<=0){
1374  int a= FFMIN(xmax - FFMAX(fx,bx), FFMIN(fx,bx) - xmin);
1375  int b= FFMIN(ymax - FFMAX(fy,by), FFMIN(fy,by) - ymin);
1376  borderdist= FFMIN(a,b);
1377  }
1378  }
1379  }
1380  }
1381  }while(!end);
1382  }
1383 
1384  s->b_bidir_forw_mv_table[xy][0]= motion_fx;
1385  s->b_bidir_forw_mv_table[xy][1]= motion_fy;
1386  s->b_bidir_back_mv_table[xy][0]= motion_bx;
1387  s->b_bidir_back_mv_table[xy][1]= motion_by;
1388 
1389  return fbmin;
1390 }
1391 
1392 static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
1393 {
1394  MotionEstContext * const c= &s->me;
1395  int P[10][2];
1396  const int mot_stride = s->mb_stride;
1397  const int mot_xy = mb_y*mot_stride + mb_x;
1398  const int shift= 1+s->quarter_sample;
1399  int dmin, i;
1400  const int time_pp= s->pp_time;
1401  const int time_pb= s->pb_time;
1402  int mx, my, xmin, xmax, ymin, ymax;
1403  int16_t (*mv_table)[2]= s->b_direct_mv_table;
1404 
1405  c->current_mv_penalty= c->mv_penalty[1] + MAX_DMV;
1406  ymin= xmin=(-32)>>shift;
1407  ymax= xmax= 31>>shift;
1408 
1409  if (IS_8X8(s->next_picture.mb_type[mot_xy])) {
1410  s->mv_type= MV_TYPE_8X8;
1411  }else{
1412  s->mv_type= MV_TYPE_16X16;
1413  }
1414 
1415  for(i=0; i<4; i++){
1416  int index= s->block_index[i];
1417  int min, max;
1418 
1419  c->co_located_mv[i][0] = s->next_picture.motion_val[0][index][0];
1420  c->co_located_mv[i][1] = s->next_picture.motion_val[0][index][1];
1421  c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));
1422  c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));
1423 // c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);
1424 // c->direct_basis_mv[1][i][1]= c->co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(shift+3);
1425 
1426  max= FFMAX(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift;
1427  min= FFMIN(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift;
1428  max+= 16*mb_x + 1; // +-1 is for the simpler rounding
1429  min+= 16*mb_x - 1;
1430  xmax= FFMIN(xmax, s->width - max);
1431  xmin= FFMAX(xmin, - 16 - min);
1432 
1433  max= FFMAX(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift;
1434  min= FFMIN(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift;
1435  max+= 16*mb_y + 1; // +-1 is for the simpler rounding
1436  min+= 16*mb_y - 1;
1437  ymax= FFMIN(ymax, s->height - max);
1438  ymin= FFMAX(ymin, - 16 - min);
1439 
1440  if(s->mv_type == MV_TYPE_16X16) break;
1441  }
1442 
1443  av_assert2(xmax <= 15 && ymax <= 15 && xmin >= -16 && ymin >= -16);
1444 
1445  if(xmax < 0 || xmin >0 || ymax < 0 || ymin > 0){
1446  s->b_direct_mv_table[mot_xy][0]= 0;
1447  s->b_direct_mv_table[mot_xy][1]= 0;
1448 
1449  return 256*256*256*64;
1450  }
1451 
1452  c->xmin= xmin;
1453  c->ymin= ymin;
1454  c->xmax= xmax;
1455  c->ymax= ymax;
1456  c->flags |= FLAG_DIRECT;
1457  c->sub_flags |= FLAG_DIRECT;
1458  c->pred_x=0;
1459  c->pred_y=0;
1460 
1461  P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin * (1 << shift), xmax << shift);
1462  P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin * (1 << shift), ymax << shift);
1463 
1464  /* special case for first line */
1465  if (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped
1466  P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin * (1 << shift), xmax << shift);
1467  P_TOP[1] = av_clip(mv_table[mot_xy - mot_stride ][1], ymin * (1 << shift), ymax << shift);
1468  P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1][0], xmin * (1 << shift), xmax << shift);
1469  P_TOPRIGHT[1] = av_clip(mv_table[mot_xy - mot_stride + 1][1], ymin * (1 << shift), ymax << shift);
1470 
1471  P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
1472  P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
1473  }
1474 
1475  dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, mv_table, 1<<(16-shift), 0, 16);
1476  if(c->sub_flags&FLAG_QPEL)
1477  dmin = qpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
1478  else
1479  dmin = hpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
1480 
1481  if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
1482  dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1);
1483 
1484  get_limits(s, 16*mb_x, 16*mb_y); //restore c->?min/max, maybe not needed
1485 
1486  mv_table[mot_xy][0]= mx;
1487  mv_table[mot_xy][1]= my;
1488  c->flags &= ~FLAG_DIRECT;
1489  c->sub_flags &= ~FLAG_DIRECT;
1490 
1491  return dmin;
1492 }
1493 
1495  int mb_x, int mb_y)
1496 {
1497  MotionEstContext * const c= &s->me;
1498  const int penalty_factor= c->mb_penalty_factor;
1499  int fmin, bmin, dmin, fbmin, bimin, fimin;
1500  int type=0;
1501  const int xy = mb_y*s->mb_stride + mb_x;
1502  init_ref(c, s->new_picture->data, s->last_picture.f->data,
1503  s->next_picture.f->data, 16 * mb_x, 16 * mb_y, 2);
1504 
1505  get_limits(s, 16*mb_x, 16*mb_y);
1506 
1507  c->skip=0;
1508 
1509  if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]) {
1510  int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0
1511 
1512  score= ((unsigned)(score*score + 128*256))>>16;
1513  c->mc_mb_var_sum_temp += score;
1514  s->mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE
1515  s->mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_DIRECT0;
1516 
1517  return;
1518  }
1519 
1520  if (s->codec_id == AV_CODEC_ID_MPEG4)
1521  dmin= direct_search(s, mb_x, mb_y);
1522  else
1523  dmin= INT_MAX;
1524 // FIXME penalty stuff for non-MPEG-4
1525  c->skip=0;
1526  fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) +
1527  3 * penalty_factor;
1528 
1529  c->skip=0;
1530  bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) +
1531  2 * penalty_factor;
1532  ff_dlog(s, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
1533 
1534  c->skip=0;
1535  fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor;
1536  ff_dlog(s, "%d %d %d %d\n", dmin, fmin, bmin, fbmin);
1537 
1538  if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
1539 //FIXME mb type penalty
1540  c->skip=0;
1541  c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
1542  fimin= interlaced_search(s, 0,
1543  s->b_field_mv_table[0], s->b_field_select_table[0],
1544  s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0);
1545  c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_DMV;
1546  bimin= interlaced_search(s, 2,
1547  s->b_field_mv_table[1], s->b_field_select_table[1],
1548  s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0);
1549  }else
1550  fimin= bimin= INT_MAX;
1551 
1552  {
1553  int score= fmin;
1555 
1556  if (dmin <= score){
1557  score = dmin;
1559  }
1560  if(bmin<score){
1561  score=bmin;
1563  }
1564  if(fbmin<score){
1565  score=fbmin;
1567  }
1568  if(fimin<score){
1569  score=fimin;
1571  }
1572  if(bimin<score){
1573  score=bimin;
1575  }
1576 
1577  score= ((unsigned)(score*score + 128*256))>>16;
1578  c->mc_mb_var_sum_temp += score;
1579  s->mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE
1580  }
1581 
1582  if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
1584  if(fimin < INT_MAX)
1586  if(bimin < INT_MAX)
1588  if(fimin < INT_MAX && bimin < INT_MAX){
1590  }
1591  //FIXME something smarter
1592  if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB
1593  if (s->codec_id == AV_CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT &&
1594  s->mpv_flags & FF_MPV_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy])
1596  }
1597 
1598  s->mb_type[mb_y*s->mb_stride + mb_x]= type;
1599 }
1600 
1601 /* find best f_code for ME which do unlimited searches */
1602 int ff_get_best_fcode(MpegEncContext * s, const int16_t (*mv_table)[2], int type)
1603 {
1604  if (s->motion_est != FF_ME_ZERO) {
1605  int score[8];
1606  int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2);
1607  const uint8_t * fcode_tab = s->fcode_tab;
1608  int best_fcode=-1;
1609  int best_score=-10000000;
1610 
1611  if(s->msmpeg4_version)
1612  range= FFMIN(range, 16);
1613  else if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)
1614  range= FFMIN(range, 256);
1615 
1616  for(i=0; i<8; i++) score[i]= s->mb_num*(8-i);
1617 
1618  for(y=0; y<s->mb_height; y++){
1619  int x;
1620  int xy= y*s->mb_stride;
1621  for(x=0; x<s->mb_width; x++, xy++){
1622  if(s->mb_type[xy] & type){
1623  int mx= mv_table[xy][0];
1624  int my= mv_table[xy][1];
1625  int fcode= FFMAX(fcode_tab[mx + MAX_MV],
1626  fcode_tab[my + MAX_MV]);
1627  int j;
1628 
1629  if (mx >= range || mx < -range ||
1630  my >= range || my < -range)
1631  continue;
1632 
1633  for(j=0; j<fcode && j<8; j++){
1634  if (s->pict_type == AV_PICTURE_TYPE_B ||
1635  s->mc_mb_var[xy] < s->mb_var[xy])
1636  score[j]-= 170;
1637  }
1638  }
1639  }
1640  }
1641 
1642  for(i=1; i<8; i++){
1643  if(score[i] > best_score){
1644  best_score= score[i];
1645  best_fcode= i;
1646  }
1647  }
1648 
1649  return best_fcode;
1650  }else{
1651  return 1;
1652  }
1653 }
1654 
1656 {
1657  MotionEstContext * const c= &s->me;
1658  const int f_code= s->f_code;
1659  int y, range;
1660  av_assert0(s->pict_type==AV_PICTURE_TYPE_P);
1661 
1662  range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code);
1663 
1664  av_assert0(range <= 16 || !s->msmpeg4_version);
1665  av_assert0(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL));
1666 
1667  if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
1668 
1669  if (s->avctx->flags & AV_CODEC_FLAG_4MV) {
1670  const int wrap= s->b8_stride;
1671 
1672  /* clip / convert to intra 8x8 type MVs */
1673  for(y=0; y<s->mb_height; y++){
1674  int xy= y*2*wrap;
1675  int i= y*s->mb_stride;
1676  int x;
1677 
1678  for(x=0; x<s->mb_width; x++){
1679  if(s->mb_type[i]&CANDIDATE_MB_TYPE_INTER4V){
1680  int block;
1681  for(block=0; block<4; block++){
1682  int off= (block& 1) + (block>>1)*wrap;
1683  int mx = s->current_picture.motion_val[0][ xy + off ][0];
1684  int my = s->current_picture.motion_val[0][ xy + off ][1];
1685 
1686  if( mx >=range || mx <-range
1687  || my >=range || my <-range){
1688  s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V;
1689  s->mb_type[i] |= type;
1690  s->current_picture.mb_type[i] = type;
1691  }
1692  }
1693  }
1694  xy+=2;
1695  i++;
1696  }
1697  }
1698  }
1699 }
1700 
1701 /**
1702  * @param truncate 1 for truncation, 0 for using intra
1703  */
1704 void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select,
1705  int16_t (*mv_table)[2], int f_code, int type, int truncate)
1706 {
1707  MotionEstContext * const c= &s->me;
1708  int y, h_range, v_range;
1709 
1710  // RAL: 8 in MPEG-1, 16 in MPEG-4
1711  int range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code);
1712 
1713  if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
1714 
1715  h_range= range;
1716  v_range= field_select_table ? range>>1 : range;
1717 
1718  /* clip / convert to intra 16x16 type MVs */
1719  for(y=0; y<s->mb_height; y++){
1720  int x;
1721  int xy= y*s->mb_stride;
1722  for(x=0; x<s->mb_width; x++){
1723  if (s->mb_type[xy] & type){ // RAL: "type" test added...
1724  if (!field_select_table || field_select_table[xy] == field_select) {
1725  if( mv_table[xy][0] >=h_range || mv_table[xy][0] <-h_range
1726  || mv_table[xy][1] >=v_range || mv_table[xy][1] <-v_range){
1727 
1728  if(truncate){
1729  if (mv_table[xy][0] > h_range-1) mv_table[xy][0]= h_range-1;
1730  else if(mv_table[xy][0] < -h_range ) mv_table[xy][0]= -h_range;
1731  if (mv_table[xy][1] > v_range-1) mv_table[xy][1]= v_range-1;
1732  else if(mv_table[xy][1] < -v_range ) mv_table[xy][1]= -v_range;
1733  }else{
1734  s->mb_type[xy] &= ~type;
1735  s->mb_type[xy] |= CANDIDATE_MB_TYPE_INTRA;
1736  mv_table[xy][0]=
1737  mv_table[xy][1]= 0;
1738  }
1739  }
1740  }
1741  }
1742  xy++;
1743  }
1744  }
1745 }
ff_h263_round_chroma
static int ff_h263_round_chroma(int x)
Definition: motion_est.h:98
CHECK_BIDIR2
#define CHECK_BIDIR2(a, b, c, d)
update_map_generation
static unsigned update_map_generation(MotionEstContext *c)
Definition: motion_est.c:54
cmp_direct_inline
static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel)
Definition: motion_est.c:109
IS_8X8
#define IS_8X8(a)
Definition: mpegutils.h:82
MV_TYPE_16X16
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:261
av_clip
#define av_clip
Definition: common.h:96
FMT_MPEG1
@ FMT_MPEG1
Definition: mpegutils.h:117
r
const char * r
Definition: vf_curves.c:126
fcode_tab
static uint8_t fcode_tab[MAX_MV *2+1]
Minimal fcode that a motion vector component would need.
Definition: ituh263enc.c:57
ff_fix_long_p_mvs
void ff_fix_long_p_mvs(MpegEncContext *s, int type)
Definition: motion_est.c:1655
cmp_simple
static int cmp_simple(MpegEncContext *s, const int x, const int y, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func)
Definition: motion_est.c:233
check_bidir_mv
static int check_bidir_mv(MpegEncContext *s, int motion_fx, int motion_fy, int motion_bx, int motion_by, int pred_fx, int pred_fy, int pred_bx, int pred_by, int size, int h)
Definition: motion_est.c:1180
MotionEstContext
Motion estimation context.
Definition: motion_est.h:47
mpegvideoenc.h
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
MAX_DMV
#define MAX_DMV
Definition: motion_est.h:37
CANDIDATE_MB_TYPE_INTER_I
#define CANDIDATE_MB_TYPE_INTER_I
Definition: mpegutils.h:107
cmp_qpel
static int cmp_qpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags)
Definition: motion_est.c:287
Minima::height
int height
Definition: motion_est.c:66
b
#define b
Definition: input.c:41
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1639
CANDIDATE_MB_TYPE_BACKWARD_I
#define CANDIDATE_MB_TYPE_BACKWARD_I
Definition: mpegutils.h:109
cmp_inline
static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel, int chroma)
Definition: motion_est.c:181
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
zero_cmp
static int zero_cmp(MpegEncContext *s, const uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h)
Definition: motion_est.c:299
CANDIDATE_MB_TYPE_SKIPPED
#define CANDIDATE_MB_TYPE_SKIPPED
Definition: mpegutils.h:100
FF_LAMBDA_SHIFT
#define FF_LAMBDA_SHIFT
Definition: avutil.h:225
CANDIDATE_MB_TYPE_INTER
#define CANDIDATE_MB_TYPE_INTER
Definition: mpegutils.h:98
minima_cmp
static int minima_cmp(const void *a, const void *b)
Definition: motion_est.c:71
AV_CODEC_FLAG_INTERLACED_ME
#define AV_CODEC_FLAG_INTERLACED_ME
interlaced motion estimation
Definition: avcodec.h:347
mpegutils.h
hash
uint8_t hash[HASH_SIZE]
Definition: movenc.c:57
AV_CODEC_FLAG_4MV
#define AV_CODEC_FLAG_4MV
4 MV per MB allowed / advanced prediction for H.263.
Definition: avcodec.h:224
P_LEFT
#define P_LEFT
Definition: motion_est.c:40
AV_CODEC_ID_H261
@ AV_CODEC_ID_H261
Definition: codec_id.h:55
CANDIDATE_MB_TYPE_FORWARD_I
#define CANDIDATE_MB_TYPE_FORWARD_I
Definition: mpegutils.h:108
get_flags
static int get_flags(MotionEstContext *c, int direct, int chroma)
Definition: motion_est.c:103
interlaced_search
static int interlaced_search(MpegEncContext *s, int ref_index, int16_t(*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my, int user_field_select)
Definition: motion_est.c:743
hpel_motion_search
static int hpel_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h)
Definition: motion_est_template.c:50
wrap
#define wrap(func)
Definition: neontest.h:65
CANDIDATE_MB_TYPE_BIDIR
#define CANDIDATE_MB_TYPE_BIDIR
Definition: mpegutils.h:105
CHECK_SAD_HALF_MV
#define CHECK_SAD_HALF_MV(suffix, x, y)
Definition: motion_est.c:390
mv_penalty
static uint8_t mv_penalty[MAX_FCODE+1][MAX_DMV *2+1]
Table of number of bits a motion vector component needs.
Definition: ituh263enc.c:52
P_MEDIAN
#define P_MEDIAN
Definition: motion_est.c:43
FF_CMP_CHROMA
#define FF_CMP_CHROMA
Definition: avcodec.h:864
type
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 type
Definition: writing_filters.txt:86
motion_est.h
Minima::y
int y
Definition: motion_est.c:67
FF_CMP_SSE
#define FF_CMP_SSE
Definition: avcodec.h:849
ff_sqrt
#define ff_sqrt
Definition: mathops.h:218
CANDIDATE_MB_TYPE_INTER4V
#define CANDIDATE_MB_TYPE_INTER4V
Definition: mpegutils.h:99
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
MAX_MV
#define MAX_MV
Definition: motion_est.h:35
get_limits
static void get_limits(MpegEncContext *s, int x, int y)
get fullpel ME search limits.
Definition: motion_est.c:529
cmp_hpel
static int cmp_hpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags)
Definition: motion_est.c:277
FF_CMP_BIT
#define FF_CMP_BIT
Definition: avcodec.h:853
mask
static const uint16_t mask[17]
Definition: lzw.c:38
s
#define s(width, name)
Definition: cbs_vp9.c:198
P_TOP
#define P_TOP
Definition: motion_est.c:41
no_sub_motion_search
static int no_sub_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h)
Definition: motion_est_template.c:155
ff_estimate_b_frame_motion
void ff_estimate_b_frame_motion(MpegEncContext *s, int mb_x, int mb_y)
Definition: motion_est.c:1494
FMT_H261
@ FMT_H261
Definition: mpegutils.h:118
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
limits.h
Minima
Definition: motion_est.c:65
get_penalty_factor
static int get_penalty_factor(int lambda, int lambda2, int type)
Definition: motion_est.c:865
init_interlaced_ref
static void init_interlaced_ref(MpegEncContext *s, int ref_index)
Definition: motion_est.c:730
cmp
static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags)
compares a block (either a full macroblock or a partition thereof) against a proposed motion-compensa...
Definition: motion_est.c:262
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:65
if
if(ret)
Definition: filter_design.txt:179
P_TOPRIGHT
#define P_TOPRIGHT
Definition: motion_est.c:42
P_MV1
#define P_MV1
Definition: motion_est.c:44
NULL
#define NULL
Definition: coverity.c:32
cmp_func
int(* cmp_func)(const void *, const void *)
Definition: vf_palettegen.c:115
ff_epzs_motion_search
int ff_epzs_motion_search(struct MpegEncContext *s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, const int16_t(*last_mv)[2], int ref_mv_scale, int size, int h)
Definition: motion_est_template.c:977
get_mb_score
static int get_mb_score(MpegEncContext *s, int mx, int my, int src_index, int ref_index, int size, int h, int add_rate)
Definition: motion_est_template.c:165
init_ref
static void init_ref(MotionEstContext *c, uint8_t *const src[3], uint8_t *const ref[3], uint8_t *const ref2[3], int x, int y, int ref_index)
Definition: motion_est.c:82
motion_est_template.c
mathops.h
Minima::x
int x
Definition: motion_est.c:67
ME_MAP_MV_BITS
#define ME_MAP_MV_BITS
Definition: motion_est.c:47
direct_search
static int direct_search(MpegEncContext *s, int mb_x, int mb_y)
Definition: motion_est.c:1392
FF_MB_DECISION_SIMPLE
#define FF_MB_DECISION_SIMPLE
uses mb_cmp
Definition: avcodec.h:926
epzs_motion_search2
static int epzs_motion_search2(MpegEncContext *s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, const int16_t(*last_mv)[2], int ref_mv_scale, const int size)
Definition: motion_est_template.c:993
FF_CMP_MEDIAN_SAD
#define FF_CMP_MEDIAN_SAD
Definition: avcodec.h:863
h263_mv4_search
static int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
Definition: motion_est.c:576
ME_MAP_SIZE
#define ME_MAP_SIZE
Definition: motion_est.h:38
index
int index
Definition: gxfenc.c:89
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
mv_scale
static av_always_inline void mv_scale(Mv *dst, const Mv *src, int td, int tb)
Definition: hevc_mvs.c:116
MV_TYPE_8X8
#define MV_TYPE_8X8
4 vectors (H.263, MPEG-4 4MV)
Definition: mpegvideo.h:262
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
AV_CODEC_FLAG_QPEL
#define AV_CODEC_FLAG_QPEL
Use qpel MC.
Definition: avcodec.h:232
FF_CMP_PSNR
#define FF_CMP_PSNR
Definition: avcodec.h:852
P
#define P
shift
static int shift(int a, int b)
Definition: bonk.c:262
ff_pre_estimate_p_frame_motion
int ff_pre_estimate_p_frame_motion(MpegEncContext *s, int mb_x, int mb_y)
Definition: motion_est.c:1065
FF_CMP_W53
#define FF_CMP_W53
Definition: avcodec.h:859
fmin
double fmin(double, double)
size
int size
Definition: twinvq_data.h:10344
LOAD_COMMON
#define LOAD_COMMON
Definition: motion_est_template.c:31
CANDIDATE_MB_TYPE_DIRECT0
#define CANDIDATE_MB_TYPE_DIRECT0
Definition: mpegutils.h:112
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2646
FF_CMP_SATD
#define FF_CMP_SATD
Definition: avcodec.h:850
FF_COMPLIANCE_NORMAL
#define FF_COMPLIANCE_NORMAL
Definition: defs.h:60
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
HASH8
#define HASH8(fx, fy, bx, by)
FF_CMP_SAD
#define FF_CMP_SAD
Definition: avcodec.h:848
qpel_motion_search
static int qpel_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h)
Definition: motion_est_template.c:207
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
bidir_refine
static int bidir_refine(MpegEncContext *s, int mb_x, int mb_y)
Definition: motion_est.c:1245
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:67
ME_MAP_SHIFT
#define ME_MAP_SHIFT
Definition: motion_est.c:46
FMT_H263
@ FMT_H263
Definition: mpegutils.h:119
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
FF_CMP_RD
#define FF_CMP_RD
Definition: avcodec.h:854
av_builtin_constant_p
#define av_builtin_constant_p
Definition: attributes.h:160
init_mv4_ref
static void init_mv4_ref(MotionEstContext *c)
Definition: motion_est.c:565
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FF_CMP_NSSE
#define FF_CMP_NSSE
Definition: avcodec.h:858
MAX_SAB_SIZE
#define MAX_SAB_SIZE
Definition: motion_est_template.c:680
ff_init_me
int ff_init_me(MpegEncContext *s)
Definition: motion_est.c:308
CANDIDATE_MB_TYPE_DIRECT
#define CANDIDATE_MB_TYPE_DIRECT
Definition: mpegutils.h:102
avcodec.h
limit
static double limit(double x)
Definition: vf_pseudocolor.c:142
zero_hpel
static void zero_hpel(uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h)
Definition: motion_est.c:305
stride
#define stride
Definition: h264pred_template.c:537
mid_pred
#define mid_pred
Definition: mathops.h:98
ret
ret
Definition: filter_design.txt:187
me_cmp_func
int(* me_cmp_func)(struct MpegEncContext *c, const uint8_t *blk1, const uint8_t *blk2, ptrdiff_t stride, int h)
Definition: me_cmp.h:50
FLAG_CHROMA
#define FLAG_CHROMA
Definition: motion_est.c:79
estimate_motion_b
static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, int16_t(*mv_table)[2], int ref_index, int f_code)
Definition: motion_est.c:1118
CANDIDATE_MB_TYPE_BIDIR_I
#define CANDIDATE_MB_TYPE_BIDIR_I
Definition: mpegutils.h:110
FLAG_QPEL
#define FLAG_QPEL
Definition: motion_est.c:78
ff_fix_long_mvs
void ff_fix_long_mvs(MpegEncContext *s, uint8_t *field_select_table, int field_select, int16_t(*mv_table)[2], int f_code, int type, int truncate)
Definition: motion_est.c:1704
AV_CODEC_ID_SNOW
@ AV_CODEC_ID_SNOW
Definition: codec_id.h:266
ff_estimate_p_frame_motion
void ff_estimate_p_frame_motion(MpegEncContext *s, int mb_x, int mb_y)
Definition: motion_est.c:890
CANDIDATE_MB_TYPE_INTRA
#define CANDIDATE_MB_TYPE_INTRA
Definition: mpegutils.h:97
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:281
FF_CMP_DCT
#define FF_CMP_DCT
Definition: avcodec.h:851
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
FF_MPV_FLAG_MV0
#define FF_MPV_FLAG_MV0
Definition: mpegvideoenc.h:44
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:862
CANDIDATE_MB_TYPE_FORWARD
#define CANDIDATE_MB_TYPE_FORWARD
Definition: mpegutils.h:103
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:280
ff_set_cmp
int ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type)
Definition: me_cmp.c:476
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
FF_CMP_DCT264
#define FF_CMP_DCT264
Definition: avcodec.h:862
cmp_fpel_internal
static int cmp_fpel_internal(MpegEncContext *s, const int x, const int y, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags)
Definition: motion_est.c:239
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
d
d
Definition: ffmpeg_filter.c:368
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
set_p_mv_tables
static void set_p_mv_tables(MpegEncContext *s, int mx, int my, int mv4)
Definition: motion_est.c:502
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2038
HASH
#define HASH(fx, fy, bx, by)
Minima::checked
int checked
Definition: motion_est.c:68
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:67
FLAG_DIRECT
#define FLAG_DIRECT
Definition: motion_est.c:80
sad_hpel_motion_search
static int sad_hpel_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int dmin, int src_index, int ref_index, int size, int h)
Definition: motion_est.c:397
cmp_internal
static int cmp_internal(MpegEncContext *s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags)
Definition: motion_est.c:249
CANDIDATE_MB_TYPE_BACKWARD
#define CANDIDATE_MB_TYPE_BACKWARD
Definition: mpegutils.h:104
ff_get_best_fcode
int ff_get_best_fcode(MpegEncContext *s, const int16_t(*mv_table)[2], int type)
Definition: motion_est.c:1602
FF_ME_ZERO
#define FF_ME_ZERO
Definition: motion_est.h:40
FF_CMP_W97
#define FF_CMP_W97
Definition: avcodec.h:860
min
float min
Definition: vorbis_enc_data.h:429