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