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