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