FFmpeg
motion_est_template.c
Go to the documentation of this file.
1 /*
2  * Motion estimation
3  * Copyright (c) 2002-2004 Michael Niedermayer
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * Motion estimation template.
25  */
26 
27 #include "libavutil/qsort.h"
28 #include "mpegvideo.h"
29 
30 //Let us hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
31 #define LOAD_COMMON\
32  uint32_t av_unused * const score_map= c->score_map;\
33  const int av_unused xmin= c->xmin;\
34  const int av_unused ymin= c->ymin;\
35  const int av_unused xmax= c->xmax;\
36  const int av_unused ymax= c->ymax;\
37  uint8_t *mv_penalty= c->current_mv_penalty;\
38  const int pred_x= c->pred_x;\
39  const int pred_y= c->pred_y;\
40 
41 #define CHECK_HALF_MV(dx, dy, x, y)\
42 {\
43  const int hx= 2*(x)+(dx);\
44  const int hy= 2*(y)+(dy);\
45  d= cmp_hpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);\
46  d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
47  COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
48 }
49 
51  int *mx_ptr, int *my_ptr, int dmin,
52  int src_index, int ref_index,
53  int size, int h)
54 {
55  MotionEstContext * const c= &s->me;
56  const int mx = *mx_ptr;
57  const int my = *my_ptr;
58  const int penalty_factor= c->sub_penalty_factor;
59  me_cmp_func cmp_sub, chroma_cmp_sub;
60  int bx=2*mx, by=2*my;
61 
63  int flags= c->sub_flags;
64 
65  //FIXME factorize
66 
67  cmp_sub = s->mecc.me_sub_cmp[size];
68  chroma_cmp_sub = s->mecc.me_sub_cmp[size + 1];
69 
70  if(c->skip){ //FIXME move out of hpel?
71  *mx_ptr = 0;
72  *my_ptr = 0;
73  return dmin;
74  }
75 
76  if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
77  dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
78  if(mx || my || size>0)
79  dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor;
80  }
81 
82  if (mx > xmin && mx < xmax &&
83  my > ymin && my < ymax) {
84  int d= dmin;
85  const int index= (my<<ME_MAP_SHIFT) + mx;
86  const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
87  + (mv_penalty[bx - pred_x] + mv_penalty[by-2 - pred_y])*c->penalty_factor;
88  const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]
89  + (mv_penalty[bx-2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor;
90  const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)]
91  + (mv_penalty[bx+2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor;
92  const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
93  + (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor;
94 
95 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
96  unsigned key;
97  unsigned map_generation= c->map_generation;
98  key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation;
99  av_assert2(c->map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
100  key= ((my+1)<<ME_MAP_MV_BITS) + (mx) + map_generation;
101  av_assert2(c->map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
102  key= ((my)<<ME_MAP_MV_BITS) + (mx+1) + map_generation;
103  av_assert2(c->map[(index+1)&(ME_MAP_SIZE-1)] == key);
104  key= ((my)<<ME_MAP_MV_BITS) + (mx-1) + map_generation;
105  av_assert2(c->map[(index-1)&(ME_MAP_SIZE-1)] == key);
106 #endif
107  if(t<=b){
108  CHECK_HALF_MV(0, 1, mx ,my-1)
109  if(l<=r){
110  CHECK_HALF_MV(1, 1, mx-1, my-1)
111  if(t+r<=b+l){
112  CHECK_HALF_MV(1, 1, mx , my-1)
113  }else{
114  CHECK_HALF_MV(1, 1, mx-1, my )
115  }
116  CHECK_HALF_MV(1, 0, mx-1, my )
117  }else{
118  CHECK_HALF_MV(1, 1, mx , my-1)
119  if(t+l<=b+r){
120  CHECK_HALF_MV(1, 1, mx-1, my-1)
121  }else{
122  CHECK_HALF_MV(1, 1, mx , my )
123  }
124  CHECK_HALF_MV(1, 0, mx , my )
125  }
126  }else{
127  if(l<=r){
128  if(t+l<=b+r){
129  CHECK_HALF_MV(1, 1, mx-1, my-1)
130  }else{
131  CHECK_HALF_MV(1, 1, mx , my )
132  }
133  CHECK_HALF_MV(1, 0, mx-1, my)
134  CHECK_HALF_MV(1, 1, mx-1, my)
135  }else{
136  if(t+r<=b+l){
137  CHECK_HALF_MV(1, 1, mx , my-1)
138  }else{
139  CHECK_HALF_MV(1, 1, mx-1, my)
140  }
141  CHECK_HALF_MV(1, 0, mx , my)
142  CHECK_HALF_MV(1, 1, mx , my)
143  }
144  CHECK_HALF_MV(0, 1, mx , my)
145  }
146  av_assert2(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2);
147  }
148 
149  *mx_ptr = bx;
150  *my_ptr = by;
151 
152  return dmin;
153 }
154 
156  int *mx_ptr, int *my_ptr, int dmin,
157  int src_index, int ref_index,
158  int size, int h)
159 {
160  (*mx_ptr) *= 2;
161  (*my_ptr) *= 2;
162  return dmin;
163 }
164 
165 static inline int get_mb_score(MpegEncContext *s, int mx, int my,
166  int src_index, int ref_index, int size,
167  int h, int add_rate)
168 {
169  MotionEstContext * const c= &s->me;
170  const int penalty_factor= c->mb_penalty_factor;
171  const int flags= c->mb_flags;
172  const int qpel= flags & FLAG_QPEL;
173  const int mask= 1+2*qpel;
174  me_cmp_func cmp_sub, chroma_cmp_sub;
175  int d;
176 
178 
179  //FIXME factorize
180 
181  cmp_sub = s->mecc.mb_cmp[size];
182  chroma_cmp_sub = s->mecc.mb_cmp[size + 1];
183 
184  d= cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
185  //FIXME check cbp before adding penalty for (0,0) vector
186  if(add_rate && (mx || my || size>0))
187  d += (mv_penalty[mx - pred_x] + mv_penalty[my - pred_y])*penalty_factor;
188 
189  return d;
190 }
191 
192 int ff_get_mb_score(MpegEncContext *s, int mx, int my, int src_index,
193  int ref_index, int size, int h, int add_rate)
194 {
195  return get_mb_score(s, mx, my, src_index, ref_index, size, h, add_rate);
196 }
197 
198 #define CHECK_QUARTER_MV(dx, dy, x, y)\
199 {\
200  const int hx= 4*(x)+(dx);\
201  const int hy= 4*(y)+(dy);\
202  d= cmp_qpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
203  d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\
204  COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
205 }
206 
208  int *mx_ptr, int *my_ptr, int dmin,
209  int src_index, int ref_index,
210  int size, int h)
211 {
212  MotionEstContext * const c= &s->me;
213  const int mx = *mx_ptr;
214  const int my = *my_ptr;
215  const int penalty_factor= c->sub_penalty_factor;
216  const unsigned map_generation = c->map_generation;
217  const int subpel_quality= c->avctx->me_subpel_quality;
218  uint32_t *map= c->map;
219  me_cmp_func cmpf, chroma_cmpf;
220  me_cmp_func cmp_sub, chroma_cmp_sub;
221 
223  int flags= c->sub_flags;
224 
225  cmpf = s->mecc.me_cmp[size];
226  chroma_cmpf = s->mecc.me_cmp[size + 1]; // FIXME: factorize
227  //FIXME factorize
228 
229  cmp_sub = s->mecc.me_sub_cmp[size];
230  chroma_cmp_sub = s->mecc.me_sub_cmp[size + 1];
231 
232  if(c->skip){ //FIXME somehow move up (benchmark)
233  *mx_ptr = 0;
234  *my_ptr = 0;
235  return dmin;
236  }
237 
238  if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
239  dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
240  if(mx || my || size>0)
241  dmin += (mv_penalty[4*mx - pred_x] + mv_penalty[4*my - pred_y])*penalty_factor;
242  }
243 
244  if (mx > xmin && mx < xmax &&
245  my > ymin && my < ymax) {
246  int bx=4*mx, by=4*my;
247  int d= dmin;
248  int i, nx, ny;
249  const int index= (my<<ME_MAP_SHIFT) + mx;
250  const int t= score_map[(index-(1<<ME_MAP_SHIFT) )&(ME_MAP_SIZE-1)];
251  const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)];
252  const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)];
253  const int b= score_map[(index+(1<<ME_MAP_SHIFT) )&(ME_MAP_SIZE-1)];
254  const int c= score_map[(index )&(ME_MAP_SIZE-1)];
255  int best[8];
256  int best_pos[8][2];
257 
258  memset(best, 64, sizeof(int)*8);
259  if(s->me.dia_size>=2){
260  const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
261  const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
262  const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];
263  const int br= score_map[(index+(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];
264 
265  for(ny= -3; ny <= 3; ny++){
266  for(nx= -3; nx <= 3; nx++){
267  //FIXME this could overflow (unlikely though)
268  const int64_t t2= nx*nx*(tr + tl - 2*t) + 4*nx*(tr-tl) + 32*t;
269  const int64_t c2= nx*nx*( r + l - 2*c) + 4*nx*( r- l) + 32*c;
270  const int64_t b2= nx*nx*(br + bl - 2*b) + 4*nx*(br-bl) + 32*b;
271  int score= (ny*ny*(b2 + t2 - 2*c2) + 4*ny*(b2 - t2) + 32*c2 + 512)>>10;
272  int i;
273 
274  if((nx&3)==0 && (ny&3)==0) continue;
275 
276  score += (mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor;
277 
278 // if(nx&1) score-=1024*c->penalty_factor;
279 // if(ny&1) score-=1024*c->penalty_factor;
280 
281  for(i=0; i<8; i++){
282  if(score < best[i]){
283  memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
284  memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
285  best[i]= score;
286  best_pos[i][0]= nx + 4*mx;
287  best_pos[i][1]= ny + 4*my;
288  break;
289  }
290  }
291  }
292  }
293  }else{
294  int tl;
295  //FIXME this could overflow (unlikely though)
296  const int cx = 4*(r - l);
297  const int cx2= r + l - 2*c;
298  const int cy = 4*(b - t);
299  const int cy2= b + t - 2*c;
300  int cxy;
301 
302  if(map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)] == ((my-1)<<ME_MAP_MV_BITS) + (mx-1) + map_generation){
303  tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];
304  }else{
305  tl= cmp(s, mx-1, my-1, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);//FIXME wrong if chroma me is different
306  }
307 
308  cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*c;
309 
310  av_assert2(16*cx2 + 4*cx + 32*c == 32*r);
311  av_assert2(16*cx2 - 4*cx + 32*c == 32*l);
312  av_assert2(16*cy2 + 4*cy + 32*c == 32*b);
313  av_assert2(16*cy2 - 4*cy + 32*c == 32*t);
314  av_assert2(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl);
315 
316  for(ny= -3; ny <= 3; ny++){
317  for(nx= -3; nx <= 3; nx++){
318  //FIXME this could overflow (unlikely though)
319  int score= ny*nx*cxy + nx*nx*cx2 + ny*ny*cy2 + nx*cx + ny*cy + 32*c; //FIXME factor
320  int i;
321 
322  if((nx&3)==0 && (ny&3)==0) continue;
323 
324  score += 32*(mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor;
325 // if(nx&1) score-=32*c->penalty_factor;
326  // if(ny&1) score-=32*c->penalty_factor;
327 
328  for(i=0; i<8; i++){
329  if(score < best[i]){
330  memmove(&best[i+1], &best[i], sizeof(int)*(7-i));
331  memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));
332  best[i]= score;
333  best_pos[i][0]= nx + 4*mx;
334  best_pos[i][1]= ny + 4*my;
335  break;
336  }
337  }
338  }
339  }
340  }
341  for(i=0; i<subpel_quality; i++){
342  nx= best_pos[i][0];
343  ny= best_pos[i][1];
344  CHECK_QUARTER_MV(nx&3, ny&3, nx>>2, ny>>2)
345  }
346 
347  av_assert2(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
348 
349  *mx_ptr = bx;
350  *my_ptr = by;
351  }else{
352  *mx_ptr =4*mx;
353  *my_ptr =4*my;
354  }
355 
356  return dmin;
357 }
358 
359 
360 #define CHECK_MV(x,y)\
361 {\
362  const unsigned key = ((unsigned)(y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
363  const int index= (((unsigned)(y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
364  av_assert2((x) >= xmin);\
365  av_assert2((x) <= xmax);\
366  av_assert2((y) >= ymin);\
367  av_assert2((y) <= ymax);\
368  if(map[index]!=key){\
369  d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
370  map[index]= key;\
371  score_map[index]= d;\
372  d += (mv_penalty[((x)*(1<<shift))-pred_x] + mv_penalty[((y)*(1<<shift))-pred_y])*penalty_factor;\
373  COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\
374  }\
375 }
376 
377 #define CHECK_CLIPPED_MV(ax,ay)\
378 {\
379  const int Lx= ax;\
380  const int Ly= ay;\
381  const int Lx2= FFMAX(xmin, FFMIN(Lx, xmax));\
382  const int Ly2= FFMAX(ymin, FFMIN(Ly, ymax));\
383  CHECK_MV(Lx2, Ly2)\
384 }
385 
386 #define CHECK_MV_DIR(x,y,new_dir)\
387 {\
388  const unsigned key = ((unsigned)(y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
389  const int index= (((unsigned)(y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
390  if(map[index]!=key){\
391  d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
392  map[index]= key;\
393  score_map[index]= d;\
394  d += (mv_penalty[(int)((unsigned)(x)<<shift)-pred_x] + mv_penalty[(int)((unsigned)(y)<<shift)-pred_y])*penalty_factor;\
395  if(d<dmin){\
396  best[0]=x;\
397  best[1]=y;\
398  dmin=d;\
399  next_dir= new_dir;\
400  }\
401  }\
402 }
403 
404 #define check(x,y,S,v)\
405 if( (x)<(xmin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\
406 if( (x)>(xmax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\
407 if( (y)<(ymin<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\
408 if( (y)>(ymax<<(S)) ) av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\
409 
410 #define LOAD_COMMON2\
411  uint32_t *map= c->map;\
412  const int qpel= flags&FLAG_QPEL;\
413  const int shift= 1+qpel;\
414 
415 static av_always_inline int small_diamond_search(MpegEncContext * s, int *best, int dmin,
416  int src_index, int ref_index, const int penalty_factor,
417  int size, int h, int flags)
418 {
419  MotionEstContext * const c= &s->me;
420  me_cmp_func cmpf, chroma_cmpf;
421  int next_dir=-1;
424  unsigned map_generation = c->map_generation;
425 
426  cmpf = s->mecc.me_cmp[size];
427  chroma_cmpf = s->mecc.me_cmp[size + 1];
428 
429  { /* ensure that the best point is in the MAP as h/qpel refinement needs it */
430  const unsigned key = ((unsigned)best[1]<<ME_MAP_MV_BITS) + best[0] + map_generation;
431  const int index= (((unsigned)best[1]<<ME_MAP_SHIFT) + best[0])&(ME_MAP_SIZE-1);
432  if (map[index] != key) { // this will be executed only very rarely
433  score_map[index]= cmp(s, best[0], best[1], 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
434  map[index]= key;
435  }
436  }
437 
438  for(;;){
439  int d;
440  const int dir= next_dir;
441  const int x= best[0];
442  const int y= best[1];
443  next_dir=-1;
444 
445  if(dir!=2 && x>xmin) CHECK_MV_DIR(x-1, y , 0)
446  if(dir!=3 && y>ymin) CHECK_MV_DIR(x , y-1, 1)
447  if(dir!=0 && x<xmax) CHECK_MV_DIR(x+1, y , 2)
448  if(dir!=1 && y<ymax) CHECK_MV_DIR(x , y+1, 3)
449 
450  if(next_dir==-1){
451  return dmin;
452  }
453  }
454 }
455 
456 static int funny_diamond_search(MpegEncContext * s, int *best, int dmin,
457  int src_index, int ref_index, const int penalty_factor,
458  int size, int h, int flags)
459 {
460  MotionEstContext * const c= &s->me;
461  me_cmp_func cmpf, chroma_cmpf;
462  int dia_size;
465  unsigned map_generation = c->map_generation;
466 
467  cmpf = s->mecc.me_cmp[size];
468  chroma_cmpf = s->mecc.me_cmp[size + 1];
469 
470  for(dia_size=1; dia_size<=4; dia_size++){
471  int dir;
472  const int x= best[0];
473  const int y= best[1];
474 
475  if(dia_size&(dia_size-1)) continue;
476 
477  if( x + dia_size > xmax
478  || x - dia_size < xmin
479  || y + dia_size > ymax
480  || y - dia_size < ymin)
481  continue;
482 
483  for(dir= 0; dir<dia_size; dir+=2){
484  int d;
485 
486  CHECK_MV(x + dir , y + dia_size - dir);
487  CHECK_MV(x + dia_size - dir, y - dir );
488  CHECK_MV(x - dir , y - dia_size + dir);
489  CHECK_MV(x - dia_size + dir, y + dir );
490  }
491 
492  if(x!=best[0] || y!=best[1])
493  dia_size=0;
494  }
495  return dmin;
496 }
497 
498 static int hex_search(MpegEncContext * s, int *best, int dmin,
499  int src_index, int ref_index, const int penalty_factor,
500  int size, int h, int flags, int dia_size)
501 {
502  MotionEstContext * const c= &s->me;
503  me_cmp_func cmpf, chroma_cmpf;
506  unsigned map_generation = c->map_generation;
507  int x,y,d;
508  const int dec= dia_size & (dia_size-1);
509 
510  cmpf = s->mecc.me_cmp[size];
511  chroma_cmpf = s->mecc.me_cmp[size + 1];
512 
513  for(;dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
514  do{
515  x= best[0];
516  y= best[1];
517 
518  CHECK_CLIPPED_MV(x -dia_size , y);
519  CHECK_CLIPPED_MV(x+ dia_size , y);
520  CHECK_CLIPPED_MV(x+( dia_size>>1), y+dia_size);
521  CHECK_CLIPPED_MV(x+( dia_size>>1), y-dia_size);
522  if(dia_size>1){
523  CHECK_CLIPPED_MV(x+(-dia_size>>1), y+dia_size);
524  CHECK_CLIPPED_MV(x+(-dia_size>>1), y-dia_size);
525  }
526  }while(best[0] != x || best[1] != y);
527  }
528 
529  return dmin;
530 }
531 
532 static int l2s_dia_search(MpegEncContext * s, int *best, int dmin,
533  int src_index, int ref_index, const int penalty_factor,
534  int size, int h, int flags)
535 {
536  MotionEstContext * const c= &s->me;
537  me_cmp_func cmpf, chroma_cmpf;
540  unsigned map_generation = c->map_generation;
541  int x,y,i,d;
542  int dia_size= c->dia_size&0xFF;
543  const int dec= dia_size & (dia_size-1);
544  static const int hex[8][2]={{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1},
545  { 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}};
546 
547  cmpf = s->mecc.me_cmp[size];
548  chroma_cmpf = s->mecc.me_cmp[size + 1];
549 
550  for(; dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
551  do{
552  x= best[0];
553  y= best[1];
554  for(i=0; i<8; i++){
555  CHECK_CLIPPED_MV(x+hex[i][0]*dia_size, y+hex[i][1]*dia_size);
556  }
557  }while(best[0] != x || best[1] != y);
558  }
559 
560  x= best[0];
561  y= best[1];
562  CHECK_CLIPPED_MV(x+1, y);
563  CHECK_CLIPPED_MV(x, y+1);
564  CHECK_CLIPPED_MV(x-1, y);
565  CHECK_CLIPPED_MV(x, y-1);
566 
567  return dmin;
568 }
569 
570 static int umh_search(MpegEncContext * s, int *best, int dmin,
571  int src_index, int ref_index, const int penalty_factor,
572  int size, int h, int flags)
573 {
574  MotionEstContext * const c= &s->me;
575  me_cmp_func cmpf, chroma_cmpf;
578  unsigned map_generation = c->map_generation;
579  int x,y,x2,y2, i, j, d;
580  const int dia_size= c->dia_size&0xFE;
581  static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2},
582  { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2},
583  {-2, 3}, { 0, 4}, { 2, 3},
584  {-2,-3}, { 0,-4}, { 2,-3},};
585 
586  cmpf = s->mecc.me_cmp[size];
587  chroma_cmpf = s->mecc.me_cmp[size + 1];
588 
589  x= best[0];
590  y= best[1];
591  for(x2=FFMAX(x-dia_size+1, xmin); x2<=FFMIN(x+dia_size-1,xmax); x2+=2){
592  CHECK_MV(x2, y);
593  }
594  for(y2=FFMAX(y-dia_size/2+1, ymin); y2<=FFMIN(y+dia_size/2-1,ymax); y2+=2){
595  CHECK_MV(x, y2);
596  }
597 
598  x= best[0];
599  y= best[1];
600  for(y2=FFMAX(y-2, ymin); y2<=FFMIN(y+2,ymax); y2++){
601  for(x2=FFMAX(x-2, xmin); x2<=FFMIN(x+2,xmax); x2++){
602  CHECK_MV(x2, y2);
603  }
604  }
605 
606 //FIXME prevent the CLIP stuff
607 
608  for(j=1; j<=dia_size/4; j++){
609  for(i=0; i<16; i++){
610  CHECK_CLIPPED_MV(x+hex[i][0]*j, y+hex[i][1]*j);
611  }
612  }
613 
614  return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, 2);
615 }
616 
617 static int full_search(MpegEncContext * s, int *best, int dmin,
618  int src_index, int ref_index, const int penalty_factor,
619  int size, int h, int flags)
620 {
621  MotionEstContext * const c= &s->me;
622  me_cmp_func cmpf, chroma_cmpf;
625  unsigned map_generation = c->map_generation;
626  int x,y, d;
627  const int dia_size= c->dia_size&0xFF;
628 
629  cmpf = s->mecc.me_cmp[size];
630  chroma_cmpf = s->mecc.me_cmp[size + 1];
631 
632  for(y=FFMAX(-dia_size, ymin); y<=FFMIN(dia_size,ymax); y++){
633  for(x=FFMAX(-dia_size, xmin); x<=FFMIN(dia_size,xmax); x++){
634  CHECK_MV(x, y);
635  }
636  }
637 
638  x= best[0];
639  y= best[1];
640  d= dmin;
641  CHECK_CLIPPED_MV(x , y);
642  CHECK_CLIPPED_MV(x+1, y);
643  CHECK_CLIPPED_MV(x, y+1);
644  CHECK_CLIPPED_MV(x-1, y);
645  CHECK_CLIPPED_MV(x, y-1);
646  best[0]= x;
647  best[1]= y;
648 
649  return d;
650 }
651 
652 #define SAB_CHECK_MV(ax,ay)\
653 {\
654  const unsigned key = ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
655  const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\
656  if(map[index]!=key){\
657  d= cmp(s, ax, ay, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
658  map[index]= key;\
659  score_map[index]= d;\
660  d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\
661  if(d < minima[minima_count-1].height){\
662  int j=0;\
663  \
664  while(d >= minima[j].height) j++;\
665 \
666  memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\
667 \
668  minima[j].checked= 0;\
669  minima[j].height= d;\
670  minima[j].x= ax;\
671  minima[j].y= ay;\
672  \
673  i=-1;\
674  continue;\
675  }\
676  }\
677 }
678 
679 #define MAX_SAB_SIZE ME_MAP_SIZE
680 static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,
681  int src_index, int ref_index, const int penalty_factor,
682  int size, int h, int flags)
683 {
684  MotionEstContext * const c= &s->me;
685  me_cmp_func cmpf, chroma_cmpf;
686  Minima minima[MAX_SAB_SIZE];
687  const int minima_count= FFABS(c->dia_size);
688  int i, j;
691  unsigned map_generation = c->map_generation;
692 
693  av_assert1(minima_count <= MAX_SAB_SIZE);
694 
695  cmpf = s->mecc.me_cmp[size];
696  chroma_cmpf = s->mecc.me_cmp[size + 1];
697 
698  /*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can
699  become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map
700  */
701  for(j=i=0; i<ME_MAP_SIZE && j<MAX_SAB_SIZE; i++){
702  uint32_t key= map[i];
703 
704  key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1));
705 
706  if ((key & (-(1 << (2 * ME_MAP_MV_BITS)))) != map_generation)
707  continue;
708 
709  minima[j].height= score_map[i];
710  minima[j].x= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS;
711  minima[j].y= key & ((1<<ME_MAP_MV_BITS)-1);
712  minima[j].x-= (1<<(ME_MAP_MV_BITS-1));
713  minima[j].y-= (1<<(ME_MAP_MV_BITS-1));
714 
715  // all entries in map should be in range except if the mv overflows their ME_MAP_MV_BITS bits space
716  if( minima[j].x > xmax || minima[j].x < xmin
717  || minima[j].y > ymax || minima[j].y < ymin)
718  continue;
719 
720  minima[j].checked=0;
721  if(minima[j].x || minima[j].y)
722  minima[j].height+= (mv_penalty[((minima[j].x)<<shift)-pred_x] + mv_penalty[((minima[j].y)<<shift)-pred_y])*penalty_factor;
723 
724  j++;
725  }
726 
727  AV_QSORT(minima, j, Minima, minima_cmp);
728 
729  for(; j<minima_count; j++){
730  minima[j].height=256*256*256*64;
731  minima[j].checked=0;
732  minima[j].x= minima[j].y=0;
733  }
734 
735  for(i=0; i<minima_count; i++){
736  const int x= minima[i].x;
737  const int y= minima[i].y;
738  int d;
739 
740  if(minima[i].checked) continue;
741 
742  if( x >= xmax || x <= xmin
743  || y >= ymax || y <= ymin)
744  continue;
745 
746  SAB_CHECK_MV(x-1, y)
747  SAB_CHECK_MV(x+1, y)
748  SAB_CHECK_MV(x , y-1)
749  SAB_CHECK_MV(x , y+1)
750 
751  minima[i].checked= 1;
752  }
753 
754  best[0]= minima[0].x;
755  best[1]= minima[0].y;
756  dmin= minima[0].height;
757 
758  if( best[0] < xmax && best[0] > xmin
759  && best[1] < ymax && best[1] > ymin){
760  int d;
761  // ensure that the reference samples for hpel refinement are in the map
762  CHECK_MV(best[0]-1, best[1])
763  CHECK_MV(best[0]+1, best[1])
764  CHECK_MV(best[0], best[1]-1)
765  CHECK_MV(best[0], best[1]+1)
766  }
767  return dmin;
768 }
769 
770 static int var_diamond_search(MpegEncContext * s, int *best, int dmin,
771  int src_index, int ref_index, const int penalty_factor,
772  int size, int h, int flags)
773 {
774  MotionEstContext * const c= &s->me;
775  me_cmp_func cmpf, chroma_cmpf;
776  int dia_size;
779  unsigned map_generation = c->map_generation;
780 
781  cmpf = s->mecc.me_cmp[size];
782  chroma_cmpf = s->mecc.me_cmp[size + 1];
783 
784  for(dia_size=1; dia_size<=c->dia_size; dia_size++){
785  int dir, start, end;
786  const int x= best[0];
787  const int y= best[1];
788 
789  start= FFMAX(0, y + dia_size - ymax);
790  end = FFMIN(dia_size, xmax - x + 1);
791  for(dir= start; dir<end; dir++){
792  int d;
793 
794 //check(x + dir,y + dia_size - dir,0, a0)
795  CHECK_MV(x + dir , y + dia_size - dir);
796  }
797 
798  start= FFMAX(0, x + dia_size - xmax);
799  end = FFMIN(dia_size, y - ymin + 1);
800  for(dir= start; dir<end; dir++){
801  int d;
802 
803 //check(x + dia_size - dir, y - dir,0, a1)
804  CHECK_MV(x + dia_size - dir, y - dir );
805  }
806 
807  start= FFMAX(0, -y + dia_size + ymin );
808  end = FFMIN(dia_size, x - xmin + 1);
809  for(dir= start; dir<end; dir++){
810  int d;
811 
812 //check(x - dir,y - dia_size + dir,0, a2)
813  CHECK_MV(x - dir , y - dia_size + dir);
814  }
815 
816  start= FFMAX(0, -x + dia_size + xmin );
817  end = FFMIN(dia_size, ymax - y + 1);
818  for(dir= start; dir<end; dir++){
819  int d;
820 
821 //check(x - dia_size + dir, y + dir,0, a3)
822  CHECK_MV(x - dia_size + dir, y + dir );
823  }
824 
825  if(x!=best[0] || y!=best[1])
826  dia_size=0;
827  }
828  return dmin;
829 }
830 
831 static av_always_inline int diamond_search(MpegEncContext * s, int *best, int dmin,
832  int src_index, int ref_index, const int penalty_factor,
833  int size, int h, int flags){
834  MotionEstContext * const c= &s->me;
835  if(c->dia_size==-1)
836  return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
837  else if(c->dia_size<-1)
838  return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
839  else if(c->dia_size<2)
840  return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
841  else if(c->dia_size>1024)
842  return full_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
843  else if(c->dia_size>768)
844  return umh_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
845  else if(c->dia_size>512)
846  return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, c->dia_size&0xFF);
847  else if(c->dia_size>256)
848  return l2s_dia_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
849  else
850  return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
851 }
852 
853 /**
854  @param P a list of candidate mvs to check before starting the
855  iterative search. If one of the candidates is close to the optimal mv, then
856  it takes fewer iterations. And it increases the chance that we find the
857  optimal mv.
858  */
859 static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx_ptr, int *my_ptr,
860  int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
861  int ref_mv_scale, int flags, int size, int h)
862 {
863  MotionEstContext * const c= &s->me;
864  int best[2]={0, 0}; /**< x and y coordinates of the best motion vector.
865  i.e. the difference between the position of the
866  block currently being encoded and the position of
867  the block chosen to predict it from. */
868  int d; ///< the score (cmp + penalty) of any given mv
869  int dmin; /**< the best value of d, i.e. the score
870  corresponding to the mv stored in best[]. */
871  unsigned map_generation;
872  int penalty_factor;
873  const int ref_mv_stride= s->mb_stride; //pass as arg FIXME
874  const int ref_mv_xy = s->mb_x + s->mb_y * ref_mv_stride; // add to last_mv before passing FIXME
875  me_cmp_func cmpf, chroma_cmpf;
876 
879 
880  if(c->pre_pass){
881  penalty_factor= c->pre_penalty_factor;
882  cmpf = s->mecc.me_pre_cmp[size];
883  chroma_cmpf = s->mecc.me_pre_cmp[size + 1];
884  }else{
885  penalty_factor= c->penalty_factor;
886  cmpf = s->mecc.me_cmp[size];
887  chroma_cmpf = s->mecc.me_cmp[size + 1];
888  }
889 
890  map_generation= update_map_generation(c);
891 
892  av_assert2(cmpf);
893  dmin= cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
894  map[0]= map_generation;
895  score_map[0]= dmin;
896 
897  //FIXME precalc first term below?
898  if ((s->pict_type == AV_PICTURE_TYPE_B && !(c->flags & FLAG_DIRECT)) ||
899  s->mpv_flags & FF_MPV_FLAG_MV0)
900  dmin += (mv_penalty[pred_x] + mv_penalty[pred_y])*penalty_factor;
901 
902  /* first line */
903  if (s->first_slice_line) {
904  CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
905  CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
906  (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
907  }else{
908  if(dmin<((h*h*s->avctx->mv0_threshold)>>8)
909  && ( P_LEFT[0] |P_LEFT[1]
910  |P_TOP[0] |P_TOP[1]
911  |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){
912  *mx_ptr= 0;
913  *my_ptr= 0;
914  c->skip=1;
915  return dmin;
916  }
917  CHECK_MV( P_MEDIAN[0] >>shift , P_MEDIAN[1] >>shift)
918  CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift) , (P_MEDIAN[1]>>shift)-1)
919  CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift) , (P_MEDIAN[1]>>shift)+1)
920  CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift)-1, (P_MEDIAN[1]>>shift) )
921  CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift)+1, (P_MEDIAN[1]>>shift) )
922  CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
923  (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
924  CHECK_MV(P_LEFT[0] >>shift, P_LEFT[1] >>shift)
925  CHECK_MV(P_TOP[0] >>shift, P_TOP[1] >>shift)
927  }
928  if(dmin>h*h*4){
929  if(c->pre_pass){
930  CHECK_CLIPPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16,
931  (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)
932  if(!s->first_slice_line)
933  CHECK_CLIPPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
934  (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
935  }else{
936  CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16,
937  (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
938  if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line
939  CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
940  (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
941  }
942  }
943 
944  if(c->avctx->last_predictor_count){
945  const int count= c->avctx->last_predictor_count;
946  const int xstart= FFMAX(0, s->mb_x - count);
947  const int ystart= FFMAX(0, s->mb_y - count);
948  const int xend= FFMIN(s->mb_width , s->mb_x + count + 1);
949  const int yend= FFMIN(s->mb_height, s->mb_y + count + 1);
950  int mb_y;
951 
952  for(mb_y=ystart; mb_y<yend; mb_y++){
953  int mb_x;
954  for(mb_x=xstart; mb_x<xend; mb_x++){
955  const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride;
956  int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16;
957  int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16;
958 
959  if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue;
960  CHECK_MV(mx,my)
961  }
962  }
963  }
964 
965 //check(best[0],best[1],0, b0)
966  dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
967 
968 //check(best[0],best[1],0, b1)
969  *mx_ptr= best[0];
970  *my_ptr= best[1];
971 
972  return dmin;
973 }
974 
975 //this function is dedicated to the brain damaged gcc
976 int ff_epzs_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr,
977  int P[10][2], int src_index, int ref_index,
978  int16_t (*last_mv)[2], int ref_mv_scale,
979  int size, int h)
980 {
981  MotionEstContext * const c= &s->me;
982 //FIXME convert other functions in the same way if faster
983  if(c->flags==0 && h==16 && size==0){
984  return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16);
985 // case FLAG_QPEL:
986 // return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL);
987  }else{
988  return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, c->flags, size, h);
989  }
990 }
991 
993  int *mx_ptr, int *my_ptr, int P[10][2],
994  int src_index, int ref_index, int16_t (*last_mv)[2],
995  int ref_mv_scale, const int size)
996 {
997  MotionEstContext * const c= &s->me;
998  int best[2]={0, 0};
999  int d, dmin;
1000  unsigned map_generation;
1001  const int penalty_factor= c->penalty_factor;
1002  const int h=8;
1003  const int ref_mv_stride= s->mb_stride;
1004  const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride;
1005  me_cmp_func cmpf, chroma_cmpf;
1006  LOAD_COMMON
1007  int flags= c->flags;
1008  LOAD_COMMON2
1009 
1010  cmpf = s->mecc.me_cmp[size];
1011  chroma_cmpf = s->mecc.me_cmp[size + 1];
1012 
1013  map_generation= update_map_generation(c);
1014 
1015  dmin = 1000000;
1016 
1017  /* first line */
1018  if (s->first_slice_line) {
1019  CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
1020  CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
1021  (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1022  CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift)
1023  }else{
1024  CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift)
1025  //FIXME try some early stop
1027  CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
1028  CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift)
1030  CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
1031  (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
1032  }
1033  if(dmin>64*4){
1034  CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16,
1035  (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
1036  if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line
1037  CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
1038  (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
1039  }
1040 
1041  dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags);
1042 
1043  *mx_ptr= best[0];
1044  *my_ptr= best[1];
1045 
1046  return dmin;
1047 }
update_map_generation
static unsigned update_map_generation(MotionEstContext *c)
Definition: motion_est.c:55
r
const char * r
Definition: vf_curves.c:114
umh_search
static int umh_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags)
Definition: motion_est_template.c:570
MotionEstContext
Motion estimation context.
Definition: motion_est.h:47
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
Minima::height
int height
Definition: motion_est.c:67
b
#define b
Definition: input.c:41
sab_diamond_search
static int sab_diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags)
Definition: motion_est_template.c:680
CHECK_HALF_MV
#define CHECK_HALF_MV(dx, dy, x, y)
Definition: motion_est_template.c:41
mpegvideo.h
minima_cmp
static int minima_cmp(const void *a, const void *b)
Definition: motion_est.c:72
P_LEFT
#define P_LEFT
Definition: motion_est.c:41
CHECK_MV_DIR
#define CHECK_MV_DIR(x, y, new_dir)
Definition: motion_est_template.c:386
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
ff_get_mb_score
int ff_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:192
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:47
P_MEDIAN
#define P_MEDIAN
Definition: motion_est.c:44
SAB_CHECK_MV
#define SAB_CHECK_MV(ax, ay)
Definition: motion_est_template.c:652
Minima::y
int y
Definition: motion_est.c:68
CHECK_QUARTER_MV
#define CHECK_QUARTER_MV(dx, dy, x, y)
Definition: motion_est_template.c:198
full_search
static int full_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags)
Definition: motion_est_template.c:617
epzs_motion_search_internal
static av_always_inline int epzs_motion_search_internal(MpegEncContext *s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t(*last_mv)[2], int ref_mv_scale, int flags, int size, int h)
Definition: motion_est_template.c:859
mask
static const uint16_t mask[17]
Definition: lzw.c:38
s
#define s(width, name)
Definition: cbs_vp9.c:257
P_TOP
#define P_TOP
Definition: motion_est.c:42
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
funny_diamond_search
static int funny_diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags)
Definition: motion_est_template.c:456
Minima
Definition: motion_est.c:66
key
const char * key
Definition: hwcontext_opencl.c:168
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:260
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
ff_epzs_motion_search
int ff_epzs_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr, int P[10][2], int src_index, int ref_index, int16_t(*last_mv)[2], int ref_mv_scale, int size, int h)
Definition: motion_est_template.c:976
P_TOPRIGHT
#define P_TOPRIGHT
Definition: motion_est.c:43
P_MV1
#define P_MV1
Definition: motion_est.c:45
MpegEncContext::mb_y
int mb_y
Definition: mpegvideo.h:288
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
Minima::x
int x
Definition: motion_est.c:68
ME_MAP_MV_BITS
#define ME_MAP_MV_BITS
Definition: motion_est.c:48
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
qsort.h
diamond_search
static av_always_inline int diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags)
Definition: motion_est_template.c:831
P
#define P
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
l2s_dia_search
static int l2s_dia_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags)
Definition: motion_est_template.c:532
size
int size
Definition: twinvq_data.h:11134
LOAD_COMMON
#define LOAD_COMMON
Definition: motion_est_template.c:31
b2
static double b2(void *priv, double x, double y)
Definition: vf_xfade.c:1333
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
var_diamond_search
static int var_diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags)
Definition: motion_est_template.c:770
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
CHECK_MV
#define CHECK_MV(x, y)
Definition: motion_est_template.c:360
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
MpegEncContext::last_mv
int last_mv[2][2][2]
last MV, used for MV prediction in MPEG-1 & B-frame MPEG-4
Definition: mpegvideo.h:278
ME_MAP_SHIFT
#define ME_MAP_SHIFT
Definition: motion_est.c:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AV_QSORT
#define AV_QSORT(p, num, type, cmp)
Quicksort This sort is fast, and fully inplace but not stable and it is possible to construct input t...
Definition: qsort.h:33
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
MpegEncContext::mb_x
int mb_x
Definition: mpegvideo.h:288
av_always_inline
#define av_always_inline
Definition: attributes.h:49
MAX_SAB_SIZE
#define MAX_SAB_SIZE
Definition: motion_est_template.c:679
hex_search
static int hex_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags, int dia_size)
Definition: motion_est_template.c:498
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, int16_t(*last_mv)[2], int ref_mv_scale, const int size)
Definition: motion_est_template.c:992
FF_MPV_FLAG_MV0
#define FF_MPV_FLAG_MV0
Definition: mpegvideo.h:593
FLAG_QPEL
#define FLAG_QPEL
Definition: motion_est.c:79
c2
static const uint64_t c2
Definition: murmur3.c:50
t2
#define t2
Definition: regdef.h:30
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:276
small_diamond_search
static av_always_inline int small_diamond_search(MpegEncContext *s, int *best, int dmin, int src_index, int ref_index, const int penalty_factor, int size, int h, int flags)
Definition: motion_est_template.c:415
shift
static int shift(int a, int b)
Definition: sonic.c:82
LOAD_COMMON2
#define LOAD_COMMON2
Definition: motion_est_template.c:410
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:85
me_cmp_func
int(* me_cmp_func)(struct MpegEncContext *c, uint8_t *blk1, uint8_t *blk2, ptrdiff_t stride, int h)
Definition: me_cmp.h:48
CHECK_CLIPPED_MV
#define CHECK_CLIPPED_MV(ax, ay)
Definition: motion_est_template.c:377
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
h
h
Definition: vp9dsp_template.c:2038
Minima::checked
int checked
Definition: motion_est.c:69
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:81
FLAG_DIRECT
#define FLAG_DIRECT
Definition: motion_est.c:81