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