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  if(s->no_rounding)
665  s->qdsp.put_no_rnd_qpel_pixels_tab[1][dxy](dest_y, ref, stride);
666  else
667  s->qdsp.put_qpel_pixels_tab[1][dxy](dest_y, ref, stride);
668  }else{
669  const uint8_t *ref = c->ref[block][0] + (mx4>>1) + (my4>>1)*stride;
670  dxy = ((my4 & 1) << 1) | (mx4 & 1);
671 
672  if(s->no_rounding)
673  s->hdsp.put_no_rnd_pixels_tab[1][dxy](dest_y , ref , stride, h);
674  else
675  s->hdsp.put_pixels_tab [1][dxy](dest_y , ref , stride, h);
676  }
677  dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*c->mb_penalty_factor;
678  }else
679  dmin_sum+= dmin4;
680 
681  if(s->quarter_sample){
682  mx4_sum+= mx4/2;
683  my4_sum+= my4/2;
684  }else{
685  mx4_sum+= mx4;
686  my4_sum+= my4;
687  }
688 
689  s->cur_pic.motion_val[0][s->block_index[block]][0] = mx4;
690  s->cur_pic.motion_val[0][s->block_index[block]][1] = my4;
691 
692  if(mx4 != mx || my4 != my) same=0;
693  }
694 
695  if(same)
696  return INT_MAX;
697 
698  if (c->me_sub_cmp[0] != c->mb_cmp[0]) {
699  dmin_sum += c->mb_cmp[0](s,
700  s->new_pic->data[0] +
701  s->mb_x * 16 + s->mb_y * 16 * stride,
702  c->scratchpad, stride, 16);
703  }
704 
705  if(c->avctx->mb_cmp&FF_CMP_CHROMA){
706  int dxy;
707  int mx, my;
708  int offset;
709 
710  mx= ff_h263_round_chroma(mx4_sum);
711  my= ff_h263_round_chroma(my4_sum);
712  dxy = ((my & 1) << 1) | (mx & 1);
713 
714  offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;
715 
716  if(s->no_rounding){
717  s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad , s->last_pic.data[1] + offset, s->uvlinesize, 8);
718  s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad + 8, s->last_pic.data[2] + offset, s->uvlinesize, 8);
719  }else{
720  s->hdsp.put_pixels_tab [1][dxy](c->scratchpad , s->last_pic.data[1] + offset, s->uvlinesize, 8);
721  s->hdsp.put_pixels_tab [1][dxy](c->scratchpad + 8, s->last_pic.data[2] + offset, s->uvlinesize, 8);
722  }
723 
724  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);
725  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);
726  }
727 
728  c->pred_x= mx;
729  c->pred_y= my;
730 
731  switch(c->avctx->mb_cmp&0xFF){
732  /*case FF_CMP_SSE:
733  return dmin_sum+ 32*s->qscale*s->qscale;*/
734  case FF_CMP_RD:
735  return dmin_sum;
736  default:
737  return dmin_sum+ 11*c->mb_penalty_factor;
738  }
739 }
740 
741 static inline void init_interlaced_ref(MpegEncContext *s, int ref_index){
742  MotionEstContext * const c= &s->me;
743 
744  c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->linesize;
745  c->src[1][0] = c->src[0][0] + s->linesize;
746  if(c->flags & FLAG_CHROMA){
747  c->ref[1+ref_index][1] = c->ref[0+ref_index][1] + s->uvlinesize;
748  c->ref[1+ref_index][2] = c->ref[0+ref_index][2] + s->uvlinesize;
749  c->src[1][1] = c->src[0][1] + s->uvlinesize;
750  c->src[1][2] = c->src[0][2] + s->uvlinesize;
751  }
752 }
753 
754 static int interlaced_search(MpegEncContext *s, int ref_index,
755  int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my, int user_field_select)
756 {
757  MotionEstContext * const c= &s->me;
758  const int size=0;
759  const int h=8;
760  int block;
761  int P[10][2];
762  const uint8_t * const mv_penalty = c->current_mv_penalty;
763  int same=1;
764  const int stride= 2*s->linesize;
765  int dmin_sum= 0;
766  const int mot_stride= s->mb_stride;
767  const int xy= s->mb_x + s->mb_y*mot_stride;
768 
769  c->ymin>>=1;
770  c->ymax>>=1;
771  c->stride<<=1;
772  c->uvstride<<=1;
773  init_interlaced_ref(s, ref_index);
774 
775  for(block=0; block<2; block++){
776  int field_select;
777  int best_dmin= INT_MAX;
778  int best_field= -1;
779 
780  for(field_select=0; field_select<2; field_select++){
781  int dmin, mx_i, my_i;
782  int16_t (*mv_table)[2]= mv_tables[block][field_select];
783 
784  if(user_field_select){
785  av_assert1(field_select==0 || field_select==1);
786  av_assert1(field_select_tables[block][xy]==0 || field_select_tables[block][xy]==1);
787  if(field_select_tables[block][xy] != field_select)
788  continue;
789  }
790 
791  P_LEFT[0] = mv_table[xy - 1][0];
792  P_LEFT[1] = mv_table[xy - 1][1];
793  if(P_LEFT[0] > (c->xmax<<1)) P_LEFT[0] = (c->xmax<<1);
794 
795  c->pred_x= P_LEFT[0];
796  c->pred_y= P_LEFT[1];
797 
798  if(!s->first_slice_line){
799  P_TOP[0] = mv_table[xy - mot_stride][0];
800  P_TOP[1] = mv_table[xy - mot_stride][1];
801  P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0];
802  P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1];
803  if(P_TOP[1] > (c->ymax<<1)) P_TOP[1] = (c->ymax<<1);
804  if (P_TOPRIGHT[0] < c->xmin * (1 << 1)) P_TOPRIGHT[0] = c->xmin * (1 << 1);
805  if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1);
806  if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->ymax<<1);
807 
808  P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
809  P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
810  }
811  P_MV1[0]= mx; //FIXME not correct if block != field_select
812  P_MV1[1]= my / 2;
813 
814  dmin = epzs_motion_search2(s, &mx_i, &my_i, P, block, field_select+ref_index, mv_table, (1<<16)>>1, 0);
815 
816  dmin= c->sub_motion_search(s, &mx_i, &my_i, dmin, block, field_select+ref_index, size, h);
817 
818  mv_table[xy][0]= mx_i;
819  mv_table[xy][1]= my_i;
820 
821  if (c->me_sub_cmp[0] != c->mb_cmp[0]) {
822  int dxy;
823 
824  //FIXME chroma ME
825  const uint8_t *ref = c->ref[field_select+ref_index][0] + (mx_i>>1) + (my_i>>1)*stride;
826  dxy = ((my_i & 1) << 1) | (mx_i & 1);
827 
828  if(s->no_rounding){
829  s->hdsp.put_no_rnd_pixels_tab[size][dxy](c->scratchpad, ref , stride, h);
830  }else{
831  s->hdsp.put_pixels_tab [size][dxy](c->scratchpad, ref , stride, h);
832  }
833  dmin = c->mb_cmp[size](s, c->src[block][0], c->scratchpad, stride, h);
834  dmin+= (mv_penalty[mx_i-c->pred_x] + mv_penalty[my_i-c->pred_y] + 1)*c->mb_penalty_factor;
835  }else
836  dmin+= c->mb_penalty_factor; //field_select bits
837 
838  dmin += field_select != block; //slightly prefer same field
839 
840  if(dmin < best_dmin){
841  best_dmin= dmin;
842  best_field= field_select;
843  }
844  }
845  {
846  int16_t (*mv_table)[2]= mv_tables[block][best_field];
847 
848  if(mv_table[xy][0] != mx) same=0; //FIXME check if these checks work and are any good at all
849  if(mv_table[xy][1]&1) same=0;
850  if(mv_table[xy][1]*2 != my) same=0;
851  if(best_field != block) same=0;
852  }
853 
854  field_select_tables[block][xy]= best_field;
855  dmin_sum += best_dmin;
856  }
857 
858  c->ymin *= 2;
859  c->ymax<<=1;
860  c->stride>>=1;
861  c->uvstride>>=1;
862 
863  if(same)
864  return INT_MAX;
865 
866  switch(c->avctx->mb_cmp&0xFF){
867  /*case FF_CMP_SSE:
868  return dmin_sum+ 32*s->qscale*s->qscale;*/
869  case FF_CMP_RD:
870  return dmin_sum;
871  default:
872  return dmin_sum+ 11*c->mb_penalty_factor;
873  }
874 }
875 
876 static inline int get_penalty_factor(int lambda, int lambda2, int type){
877  switch(type&0xFF){
878  default:
879  case FF_CMP_SAD:
880  return lambda>>FF_LAMBDA_SHIFT;
881  case FF_CMP_DCT:
882  return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
883  case FF_CMP_W53:
884  return (4*lambda)>>(FF_LAMBDA_SHIFT);
885  case FF_CMP_W97:
886  return (2*lambda)>>(FF_LAMBDA_SHIFT);
887  case FF_CMP_SATD:
888  case FF_CMP_DCT264:
889  return (2*lambda)>>FF_LAMBDA_SHIFT;
890  case FF_CMP_RD:
891  case FF_CMP_PSNR:
892  case FF_CMP_SSE:
893  case FF_CMP_NSSE:
894  return lambda2>>FF_LAMBDA_SHIFT;
895  case FF_CMP_BIT:
896  case FF_CMP_MEDIAN_SAD:
897  return 1;
898  }
899 }
900 
902  int mb_x, int mb_y)
903 {
904  MotionEstContext * const c= &s->me;
905  const uint8_t *pix, *ppix;
906  int sum, mx = 0, my = 0, dmin = 0;
907  int varc; ///< the variance of the block (sum of squared (p[y][x]-average))
908  int vard; ///< sum of squared differences with the estimated motion vector
909  int P[10][2];
910  const int shift= 1+s->quarter_sample;
911  int mb_type=0;
912 
913  init_ref(c, s->new_pic->data, s->last_pic.data, NULL, 16*mb_x, 16*mb_y, 0);
914 
915  av_assert0(s->quarter_sample==0 || s->quarter_sample==1);
916  av_assert0(s->linesize == c->stride);
917  av_assert0(s->uvlinesize == c->uvstride);
918 
919  c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
920  c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
921  c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
922  c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
923 
924  get_limits(s, 16*mb_x, 16*mb_y, 0);
925  c->skip=0;
926 
927  /* intra / predictive decision */
928  pix = c->src[0][0];
929  sum = s->mpvencdsp.pix_sum(pix, s->linesize);
930  varc = s->mpvencdsp.pix_norm1(pix, s->linesize) -
931  (((unsigned) sum * sum) >> 8) + 500;
932 
933  s->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
934  s->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;
935  c->mb_var_sum_temp += (varc+128)>>8;
936 
937  if (s->motion_est != FF_ME_ZERO) {
938  const int mot_stride = s->b8_stride;
939  const int mot_xy = s->block_index[0];
940 
941  P_LEFT[0] = s->cur_pic.motion_val[0][mot_xy - 1][0];
942  P_LEFT[1] = s->cur_pic.motion_val[0][mot_xy - 1][1];
943 
944  if (P_LEFT[0] > (c->xmax << shift))
945  P_LEFT[0] = c->xmax << shift;
946 
947  if (!s->first_slice_line) {
948  P_TOP[0] = s->cur_pic.motion_val[0][mot_xy - mot_stride ][0];
949  P_TOP[1] = s->cur_pic.motion_val[0][mot_xy - mot_stride ][1];
950  P_TOPRIGHT[0] = s->cur_pic.motion_val[0][mot_xy - mot_stride + 2][0];
951  P_TOPRIGHT[1] = s->cur_pic.motion_val[0][mot_xy - mot_stride + 2][1];
952  if (P_TOP[1] > (c->ymax << shift))
953  P_TOP[1] = c->ymax << shift;
954  if (P_TOPRIGHT[0] < (c->xmin * (1 << shift)))
955  P_TOPRIGHT[0] = c->xmin * (1 << shift);
956  if (P_TOPRIGHT[1] > (c->ymax * (1 << shift)))
957  P_TOPRIGHT[1] = c->ymax * (1 << shift);
958 
959  P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
960  P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
961 
962  if (s->out_format == FMT_H263) {
963  c->pred_x = P_MEDIAN[0];
964  c->pred_y = P_MEDIAN[1];
965  } else { /* MPEG-1 at least */
966  c->pred_x = P_LEFT[0];
967  c->pred_y = P_LEFT[1];
968  }
969  } else {
970  c->pred_x = P_LEFT[0];
971  c->pred_y = P_LEFT[1];
972  }
973  dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16);
974  }
975 
976  /* At this point (mx,my) are full-pell and the relative displacement */
977  ppix = c->ref[0][0] + (my * s->linesize) + mx;
978 
979  vard = c->sse(NULL, pix, ppix, s->linesize, 16);
980 
981  s->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;
982  c->mc_mb_var_sum_temp += (vard+128)>>8;
983 
984  if (c->avctx->mb_decision > FF_MB_DECISION_SIMPLE) {
985  int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
986  int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
987  c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
988 
989  if (vard*2 + 200*256 > varc && !s->intra_penalty)
990  mb_type|= CANDIDATE_MB_TYPE_INTRA;
991  if (varc*2 + 200*256 > vard || s->qscale > 24){
992 // if (varc*2 + 200*256 + 50*(s->lambda2>>FF_LAMBDA_SHIFT) > vard){
993  mb_type|= CANDIDATE_MB_TYPE_INTER;
994  c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
995  if (s->mpv_flags & FF_MPV_FLAG_MV0)
996  if(mx || my)
997  mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference
998  }else{
999  mx *= 1 << shift;
1000  my *= 1 << shift;
1001  }
1002  if ((s->avctx->flags & AV_CODEC_FLAG_4MV)
1003  && !c->skip && varc>50<<8 && vard>10<<8){
1004  if(h263_mv4_search(s, mx, my, shift) < INT_MAX)
1005  mb_type|=CANDIDATE_MB_TYPE_INTER4V;
1006 
1007  set_p_mv_tables(s, mx, my, 0);
1008  }else
1009  set_p_mv_tables(s, mx, my, 1);
1010  if ((s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
1011  && !c->skip){ //FIXME varc/d checks
1012  if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX)
1013  mb_type |= CANDIDATE_MB_TYPE_INTER_I;
1014  }
1015  }else{
1016  int intra_score, i;
1017  mb_type= CANDIDATE_MB_TYPE_INTER;
1018 
1019  dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
1020  if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
1021  dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1);
1022 
1023  if ((s->avctx->flags & AV_CODEC_FLAG_4MV)
1024  && !c->skip && varc>50<<8 && vard>10<<8){
1025  int dmin4= h263_mv4_search(s, mx, my, shift);
1026  if(dmin4 < dmin){
1027  mb_type= CANDIDATE_MB_TYPE_INTER4V;
1028  dmin=dmin4;
1029  }
1030  }
1031  if ((s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)
1032  && !c->skip){ //FIXME varc/d checks
1033  int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0);
1034  if(dmin_i < dmin){
1035  mb_type = CANDIDATE_MB_TYPE_INTER_I;
1036  dmin= dmin_i;
1037  }
1038  }
1039 
1041 
1042  /* get intra luma score */
1043  if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){
1044  intra_score= varc - 500;
1045  }else{
1046  unsigned mean = (sum+128)>>8;
1047  mean*= 0x01010101;
1048 
1049  for(i=0; i<16; i++){
1050  *(uint32_t*)(&c->scratchpad[i*s->linesize+ 0]) = mean;
1051  *(uint32_t*)(&c->scratchpad[i*s->linesize+ 4]) = mean;
1052  *(uint32_t*)(&c->scratchpad[i*s->linesize+ 8]) = mean;
1053  *(uint32_t*)(&c->scratchpad[i*s->linesize+12]) = mean;
1054  }
1055 
1056  intra_score= c->mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16);
1057  }
1058  intra_score += c->mb_penalty_factor*16 + s->intra_penalty;
1059 
1060  if(intra_score < dmin){
1061  mb_type= CANDIDATE_MB_TYPE_INTRA;
1062  s->cur_pic.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
1063  }else
1064  s->cur_pic.mb_type[mb_y*s->mb_stride + mb_x] = 0;
1065 
1066  {
1067  int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
1068  int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
1069  c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
1070  }
1071  }
1072 
1073  s->mb_type[mb_y*s->mb_stride + mb_x]= mb_type;
1074 }
1075 
1077  int mb_x, int mb_y)
1078 {
1079  MotionEstContext * const c= &s->me;
1080  int mx, my, dmin;
1081  int P[10][2];
1082  const int shift= 1+s->quarter_sample;
1083  const int xy= mb_x + mb_y*s->mb_stride;
1084  init_ref(c, s->new_pic->data, s->last_pic.data, NULL, 16*mb_x, 16*mb_y, 0);
1085 
1086  av_assert0(s->quarter_sample==0 || s->quarter_sample==1);
1087 
1088  c->pre_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp);
1089  c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
1090 
1091  get_limits(s, 16*mb_x, 16*mb_y, 0);
1092  c->skip=0;
1093 
1094  P_LEFT[0] = s->p_mv_table[xy + 1][0];
1095  P_LEFT[1] = s->p_mv_table[xy + 1][1];
1096 
1097  if(P_LEFT[0] < (c->xmin<<shift)) P_LEFT[0] = (c->xmin<<shift);
1098 
1099  /* special case for first line */
1100  if (s->first_slice_line) {
1101  c->pred_x= P_LEFT[0];
1102  c->pred_y= P_LEFT[1];
1103  P_TOP[0]= P_TOPRIGHT[0]= P_MEDIAN[0]=
1104  P_TOP[1]= P_TOPRIGHT[1]= P_MEDIAN[1]= 0; //FIXME
1105  } else {
1106  P_TOP[0] = s->p_mv_table[xy + s->mb_stride ][0];
1107  P_TOP[1] = s->p_mv_table[xy + s->mb_stride ][1];
1108  P_TOPRIGHT[0] = s->p_mv_table[xy + s->mb_stride - 1][0];
1109  P_TOPRIGHT[1] = s->p_mv_table[xy + s->mb_stride - 1][1];
1110  if(P_TOP[1] < (c->ymin<<shift)) P_TOP[1] = (c->ymin<<shift);
1111  if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
1112  if(P_TOPRIGHT[1] < (c->ymin<<shift)) P_TOPRIGHT[1]= (c->ymin<<shift);
1113 
1114  P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
1115  P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
1116 
1117  c->pred_x = P_MEDIAN[0];
1118  c->pred_y = P_MEDIAN[1];
1119  }
1120 
1121  dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16);
1122 
1123  s->p_mv_table[xy][0] = mx<<shift;
1124  s->p_mv_table[xy][1] = my<<shift;
1125 
1126  return dmin;
1127 }
1128 
1129 static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
1130  int16_t (*mv_table)[2], int ref_index, int f_code)
1131 {
1132  MotionEstContext * const c= &s->me;
1133  int mx = 0, my = 0, dmin = 0;
1134  int P[10][2];
1135  const int shift= 1+s->quarter_sample;
1136  const int mot_stride = s->mb_stride;
1137  const int mot_xy = mb_y*mot_stride + mb_x;
1138  const uint8_t * const mv_penalty = c->mv_penalty[f_code] + MAX_DMV;
1139  int mv_scale;
1140 
1141  c->current_mv_penalty= mv_penalty;
1142 
1143  get_limits(s, 16*mb_x, 16*mb_y, 1);
1144 
1145  if (s->motion_est != FF_ME_ZERO) {
1146  P_LEFT[0] = mv_table[mot_xy - 1][0];
1147  P_LEFT[1] = mv_table[mot_xy - 1][1];
1148 
1149  if (P_LEFT[0] > (c->xmax << shift)) P_LEFT[0] = (c->xmax << shift);
1150 
1151  /* special case for first line */
1152  if (!s->first_slice_line) {
1153  P_TOP[0] = mv_table[mot_xy - mot_stride ][0];
1154  P_TOP[1] = mv_table[mot_xy - mot_stride ][1];
1155  P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0];
1156  P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1];
1157  if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift);
1158  if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift);
1159  if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift);
1160 
1161  P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
1162  P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
1163  }
1164  c->pred_x = P_LEFT[0];
1165  c->pred_y = P_LEFT[1];
1166 
1167  if(mv_table == s->b_forw_mv_table){
1168  mv_scale= (s->pb_time<<16) / (s->pp_time<<shift);
1169  }else{
1170  mv_scale = ((s->pb_time - s->pp_time) * (1 << 16)) / (s->pp_time<<shift);
1171  }
1172 
1173  dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, ref_index, s->p_mv_table, mv_scale, 0, 16);
1174  }
1175 
1176  dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16);
1177 
1178  if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
1179  dmin= get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1);
1180 
1181 // s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
1182  mv_table[mot_xy][0]= mx;
1183  mv_table[mot_xy][1]= my;
1184 
1185  return dmin;
1186 }
1187 
1188 static inline int check_bidir_mv(MpegEncContext * s,
1189  int motion_fx, int motion_fy,
1190  int motion_bx, int motion_by,
1191  int pred_fx, int pred_fy,
1192  int pred_bx, int pred_by,
1193  int size, int h)
1194 {
1195  //FIXME optimize?
1196  //FIXME better f_code prediction (max mv & distance)
1197  //FIXME pointers
1198  MotionEstContext * const c= &s->me;
1199  const uint8_t * const mv_penalty_f = c->mv_penalty[s->f_code] + MAX_DMV; // f_code of the prev frame
1200  const uint8_t * const mv_penalty_b = c->mv_penalty[s->b_code] + MAX_DMV; // f_code of the prev frame
1201  int stride= c->stride;
1202  uint8_t *dest_y = c->scratchpad;
1203  const uint8_t *ptr;
1204  int dxy;
1205  int src_x, src_y;
1206  int fbmin;
1207  const uint8_t *const *src_data = c->src[0];
1208  const uint8_t *const *ref_data = c->ref[0];
1209  const uint8_t *const *ref2_data = c->ref[2];
1210 
1211  if(s->quarter_sample){
1212  dxy = ((motion_fy & 3) << 2) | (motion_fx & 3);
1213  src_x = motion_fx >> 2;
1214  src_y = motion_fy >> 2;
1215 
1216  ptr = ref_data[0] + (src_y * stride) + src_x;
1217  s->qdsp.put_qpel_pixels_tab[0][dxy](dest_y, ptr, stride);
1218 
1219  dxy = ((motion_by & 3) << 2) | (motion_bx & 3);
1220  src_x = motion_bx >> 2;
1221  src_y = motion_by >> 2;
1222 
1223  ptr = ref2_data[0] + (src_y * stride) + src_x;
1224  s->qdsp.avg_qpel_pixels_tab[size][dxy](dest_y, ptr, stride);
1225  }else{
1226  dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);
1227  src_x = motion_fx >> 1;
1228  src_y = motion_fy >> 1;
1229 
1230  ptr = ref_data[0] + (src_y * stride) + src_x;
1231  s->hdsp.put_pixels_tab[size][dxy](dest_y , ptr , stride, h);
1232 
1233  dxy = ((motion_by & 1) << 1) | (motion_bx & 1);
1234  src_x = motion_bx >> 1;
1235  src_y = motion_by >> 1;
1236 
1237  ptr = ref2_data[0] + (src_y * stride) + src_x;
1238  s->hdsp.avg_pixels_tab[size][dxy](dest_y , ptr , stride, h);
1239  }
1240 
1241  fbmin = (mv_penalty_f[motion_fx-pred_fx] + mv_penalty_f[motion_fy-pred_fy])*c->mb_penalty_factor
1242  +(mv_penalty_b[motion_bx-pred_bx] + mv_penalty_b[motion_by-pred_by])*c->mb_penalty_factor
1243  + c->mb_cmp[size](s, src_data[0], dest_y, stride, h); // FIXME new_pic
1244 
1245  if(c->avctx->mb_cmp&FF_CMP_CHROMA){
1246  }
1247  //FIXME CHROMA !!!
1248 
1249  return fbmin;
1250 }
1251 
1252 /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/
1253 static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
1254 {
1255  MotionEstContext * const c= &s->me;
1256  const int mot_stride = s->mb_stride;
1257  const int xy = mb_y *mot_stride + mb_x;
1258  int fbmin;
1259  int pred_fx= s->b_bidir_forw_mv_table[xy-1][0];
1260  int pred_fy= s->b_bidir_forw_mv_table[xy-1][1];
1261  int pred_bx= s->b_bidir_back_mv_table[xy-1][0];
1262  int pred_by= s->b_bidir_back_mv_table[xy-1][1];
1263  int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0];
1264  int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1];
1265  int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0];
1266  int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1];
1267  const int flags= c->sub_flags;
1268  const int qpel= flags&FLAG_QPEL;
1269  const int shift= 1+qpel;
1270  const int xmin= c->xmin * (1 << shift);
1271  const int ymin= c->ymin * (1 << shift);
1272  const int xmax= c->xmax<<shift;
1273  const int ymax= c->ymax<<shift;
1274 #define HASH(fx,fy,bx,by) ((fx)+17*(fy)+63*(bx)+117*(by))
1275 #define HASH8(fx,fy,bx,by) ((uint8_t)HASH(fx,fy,bx,by))
1276  int hashidx= HASH(motion_fx,motion_fy, motion_bx, motion_by);
1277  uint8_t map[256] = { 0 };
1278 
1279  map[hashidx&255] = 1;
1280 
1281  fbmin= check_bidir_mv(s, motion_fx, motion_fy,
1282  motion_bx, motion_by,
1283  pred_fx, pred_fy,
1284  pred_bx, pred_by,
1285  0, 16);
1286 
1287  if(s->avctx->bidir_refine){
1288  int end;
1289  static const uint8_t limittab[5]={0,8,32,64,80};
1290  const int limit= limittab[s->avctx->bidir_refine];
1291  static const int8_t vect[][4]={
1292 { 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},
1293 
1294 { 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},
1295 { 0, 1, 0, 1}, { 0,-1, 0,-1}, { 1, 0, 1, 0}, {-1, 0,-1, 0},
1296 { 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},
1297 { 0,-1, 0, 1}, { 0, 1, 0,-1}, {-1, 0, 1, 0}, { 1, 0,-1, 0},
1298 
1299 { 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},
1300 { 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},
1301 { 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},
1302 { 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},
1303 
1304 { 1, 1, 1, 1}, {-1,-1,-1,-1},
1305 { 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},
1306 { 1, 1,-1,-1}, {-1,-1, 1, 1}, { 1,-1,-1, 1}, {-1, 1, 1,-1}, { 1,-1, 1,-1}, {-1, 1,-1, 1},
1307  };
1308  static const uint8_t hash[]={
1309 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),
1310 
1311 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),
1312 HASH8( 0, 1, 0, 1), HASH8( 0,-1, 0,-1), HASH8( 1, 0, 1, 0), HASH8(-1, 0,-1, 0),
1313 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),
1314 HASH8( 0,-1, 0, 1), HASH8( 0, 1, 0,-1), HASH8(-1, 0, 1, 0), HASH8( 1, 0,-1, 0),
1315 
1316 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),
1317 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),
1318 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),
1319 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),
1320 
1321 HASH8( 1, 1, 1, 1), HASH8(-1,-1,-1,-1),
1322 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),
1323 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),
1324 };
1325 
1326 #define CHECK_BIDIR(fx,fy,bx,by)\
1327  if( !map[(hashidx+HASH(fx,fy,bx,by))&255]\
1328  &&(fx<=0 || motion_fx+fx<=xmax) && (fy<=0 || motion_fy+fy<=ymax) && (bx<=0 || motion_bx+bx<=xmax) && (by<=0 || motion_by+by<=ymax)\
1329  &&(fx>=0 || motion_fx+fx>=xmin) && (fy>=0 || motion_fy+fy>=ymin) && (bx>=0 || motion_bx+bx>=xmin) && (by>=0 || motion_by+by>=ymin)){\
1330  int score;\
1331  map[(hashidx+HASH(fx,fy,bx,by))&255] = 1;\
1332  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);\
1333  if(score < fbmin){\
1334  hashidx += HASH(fx,fy,bx,by);\
1335  fbmin= score;\
1336  motion_fx+=fx;\
1337  motion_fy+=fy;\
1338  motion_bx+=bx;\
1339  motion_by+=by;\
1340  end=0;\
1341  }\
1342  }
1343 #define CHECK_BIDIR2(a,b,c,d)\
1344 CHECK_BIDIR(a,b,c,d)\
1345 CHECK_BIDIR(-(a),-(b),-(c),-(d))
1346 
1347  do{
1348  int i;
1349  int borderdist=0;
1350  end=1;
1351 
1352  CHECK_BIDIR2(0,0,0,1)
1353  CHECK_BIDIR2(0,0,1,0)
1354  CHECK_BIDIR2(0,1,0,0)
1355  CHECK_BIDIR2(1,0,0,0)
1356 
1357  for(i=8; i<limit; i++){
1358  int fx= motion_fx+vect[i][0];
1359  int fy= motion_fy+vect[i][1];
1360  int bx= motion_bx+vect[i][2];
1361  int by= motion_by+vect[i][3];
1362  if(borderdist<=0){
1363  int a= (xmax - FFMAX(fx,bx))|(FFMIN(fx,bx) - xmin);
1364  int b= (ymax - FFMAX(fy,by))|(FFMIN(fy,by) - ymin);
1365  if((a|b) < 0)
1366  map[(hashidx+hash[i])&255] = 1;
1367  }
1368  if(!map[(hashidx+hash[i])&255]){
1369  int score;
1370  map[(hashidx+hash[i])&255] = 1;
1371  score= check_bidir_mv(s, fx, fy, bx, by, pred_fx, pred_fy, pred_bx, pred_by, 0, 16);
1372  if(score < fbmin){
1373  hashidx += hash[i];
1374  fbmin= score;
1375  motion_fx=fx;
1376  motion_fy=fy;
1377  motion_bx=bx;
1378  motion_by=by;
1379  end=0;
1380  borderdist--;
1381  if(borderdist<=0){
1382  int a= FFMIN(xmax - FFMAX(fx,bx), FFMIN(fx,bx) - xmin);
1383  int b= FFMIN(ymax - FFMAX(fy,by), FFMIN(fy,by) - ymin);
1384  borderdist= FFMIN(a,b);
1385  }
1386  }
1387  }
1388  }
1389  }while(!end);
1390  }
1391 
1392  s->b_bidir_forw_mv_table[xy][0]= motion_fx;
1393  s->b_bidir_forw_mv_table[xy][1]= motion_fy;
1394  s->b_bidir_back_mv_table[xy][0]= motion_bx;
1395  s->b_bidir_back_mv_table[xy][1]= motion_by;
1396 
1397  return fbmin;
1398 }
1399 
1400 static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
1401 {
1402  MotionEstContext * const c= &s->me;
1403  int P[10][2];
1404  const int mot_stride = s->mb_stride;
1405  const int mot_xy = mb_y*mot_stride + mb_x;
1406  const int shift= 1+s->quarter_sample;
1407  int dmin, i;
1408  const int time_pp= s->pp_time;
1409  const int time_pb= s->pb_time;
1410  int mx, my, xmin, xmax, ymin, ymax;
1411  int16_t (*mv_table)[2]= s->b_direct_mv_table;
1412 
1413  c->current_mv_penalty= c->mv_penalty[1] + MAX_DMV;
1414  ymin= xmin=(-32)>>shift;
1415  ymax= xmax= 31>>shift;
1416 
1417  if (IS_8X8(s->next_pic.mb_type[mot_xy])) {
1418  s->mv_type= MV_TYPE_8X8;
1419  }else{
1420  s->mv_type= MV_TYPE_16X16;
1421  }
1422 
1423  for(i=0; i<4; i++){
1424  int index= s->block_index[i];
1425  int min, max;
1426 
1427  c->co_located_mv[i][0] = s->next_pic.motion_val[0][index][0];
1428  c->co_located_mv[i][1] = s->next_pic.motion_val[0][index][1];
1429  c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));
1430  c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));
1431 // c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);
1432 // c->direct_basis_mv[1][i][1]= c->co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(shift+3);
1433 
1434  max= FFMAX(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift;
1435  min= FFMIN(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift;
1436  max+= 16*mb_x + 1; // +-1 is for the simpler rounding
1437  min+= 16*mb_x - 1;
1438  xmax= FFMIN(xmax, s->width - max);
1439  xmin= FFMAX(xmin, - 16 - min);
1440 
1441  max= FFMAX(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift;
1442  min= FFMIN(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift;
1443  max+= 16*mb_y + 1; // +-1 is for the simpler rounding
1444  min+= 16*mb_y - 1;
1445  ymax= FFMIN(ymax, s->height - max);
1446  ymin= FFMAX(ymin, - 16 - min);
1447 
1448  if(s->mv_type == MV_TYPE_16X16) break;
1449  }
1450 
1451  av_assert2(xmax <= 15 && ymax <= 15 && xmin >= -16 && ymin >= -16);
1452 
1453  if(xmax < 0 || xmin >0 || ymax < 0 || ymin > 0){
1454  s->b_direct_mv_table[mot_xy][0]= 0;
1455  s->b_direct_mv_table[mot_xy][1]= 0;
1456 
1457  return 256*256*256*64-1;
1458  }
1459 
1460  c->xmin= xmin;
1461  c->ymin= ymin;
1462  c->xmax= xmax;
1463  c->ymax= ymax;
1464  c->flags |= FLAG_DIRECT;
1465  c->sub_flags |= FLAG_DIRECT;
1466  c->pred_x=0;
1467  c->pred_y=0;
1468 
1469  P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin * (1 << shift), xmax << shift);
1470  P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin * (1 << shift), ymax << shift);
1471 
1472  /* special case for first line */
1473  if (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped
1474  P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin * (1 << shift), xmax << shift);
1475  P_TOP[1] = av_clip(mv_table[mot_xy - mot_stride ][1], ymin * (1 << shift), ymax << shift);
1476  P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1][0], xmin * (1 << shift), xmax << shift);
1477  P_TOPRIGHT[1] = av_clip(mv_table[mot_xy - mot_stride + 1][1], ymin * (1 << shift), ymax << shift);
1478 
1479  P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
1480  P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
1481  }
1482 
1483  dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, mv_table, 1<<(16-shift), 0, 16);
1484  if(c->sub_flags&FLAG_QPEL)
1485  dmin = qpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
1486  else
1487  dmin = hpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
1488 
1489  if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
1490  dmin= get_mb_score(s, mx, my, 0, 0, 0, 16, 1);
1491 
1492  get_limits(s, 16*mb_x, 16*mb_y, 1); //restore c->?min/max, maybe not needed
1493 
1494  mv_table[mot_xy][0]= mx;
1495  mv_table[mot_xy][1]= my;
1496  c->flags &= ~FLAG_DIRECT;
1497  c->sub_flags &= ~FLAG_DIRECT;
1498 
1499  return dmin;
1500 }
1501 
1503  int mb_x, int mb_y)
1504 {
1505  MotionEstContext * const c= &s->me;
1506  int fmin, bmin, dmin, fbmin, bimin, fimin;
1507  int type=0;
1508  const int xy = mb_y*s->mb_stride + mb_x;
1509  init_ref(c, s->new_pic->data, s->last_pic.data,
1510  s->next_pic.data, 16 * mb_x, 16 * mb_y, 2);
1511 
1512  get_limits(s, 16*mb_x, 16*mb_y, 1);
1513 
1514  c->skip=0;
1515 
1516  if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_pic.mbskip_table[xy]) {
1517  int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0
1518 
1519  score= ((unsigned)(score*score + 128*256))>>16;
1520  c->mc_mb_var_sum_temp += score;
1521  s->mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE
1522  s->mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_DIRECT0;
1523 
1524  return;
1525  }
1526 
1527  c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
1528  c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
1529  c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
1530 
1531  if (s->codec_id == AV_CODEC_ID_MPEG4)
1532  dmin= direct_search(s, mb_x, mb_y);
1533  else
1534  dmin= INT_MAX;
1535 
1536 // FIXME penalty stuff for non-MPEG-4
1537  c->skip=0;
1538  fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) +
1539  3 * c->mb_penalty_factor;
1540 
1541  c->skip=0;
1542  bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) +
1543  2 * c->mb_penalty_factor;
1544  ff_dlog(s, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
1545 
1546  c->skip=0;
1547  fbmin= bidir_refine(s, mb_x, mb_y) + c->mb_penalty_factor;
1548  ff_dlog(s, "%d %d %d %d\n", dmin, fmin, bmin, fbmin);
1549 
1550  if (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME) {
1551 //FIXME mb type penalty
1552  c->skip=0;
1553  c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV;
1554  fimin= interlaced_search(s, 0,
1555  s->b_field_mv_table[0], s->b_field_select_table[0],
1556  s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0);
1557  c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_DMV;
1558  bimin= interlaced_search(s, 2,
1559  s->b_field_mv_table[1], s->b_field_select_table[1],
1560  s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0);
1561  }else
1562  fimin= bimin= INT_MAX;
1563 
1564  {
1565  int score= fmin;
1567 
1568  if (dmin <= score){
1569  score = dmin;
1571  }
1572  if(bmin<score){
1573  score=bmin;
1575  }
1576  if(fbmin<score){
1577  score=fbmin;
1579  }
1580  if(fimin<score){
1581  score=fimin;
1583  }
1584  if(bimin<score){
1585  score=bimin;
1587  }
1588 
1589  score= ((unsigned)(score*score + 128*256))>>16;
1590  c->mc_mb_var_sum_temp += score;
1591  s->mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE
1592  }
1593 
1594  if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
1596  if(fimin < INT_MAX)
1598  if(bimin < INT_MAX)
1600  if(fimin < INT_MAX && bimin < INT_MAX){
1602  }
1603  //FIXME something smarter
1604  if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB
1605  if (s->codec_id == AV_CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT &&
1606  s->mpv_flags & FF_MPV_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy])
1608  }
1609 
1610  s->mb_type[mb_y*s->mb_stride + mb_x]= type;
1611 }
1612 
1613 /* find best f_code for ME which do unlimited searches */
1614 int ff_get_best_fcode(MpegEncContext * s, const int16_t (*mv_table)[2], int type)
1615 {
1616  if (s->motion_est != FF_ME_ZERO) {
1617  int score[8];
1618  int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2);
1619  const uint8_t * fcode_tab = s->fcode_tab;
1620  int best_fcode=-1;
1621  int best_score=-10000000;
1622 
1623  if (s->msmpeg4_version != MSMP4_UNUSED)
1624  range= FFMIN(range, 16);
1625  else if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)
1626  range= FFMIN(range, 256);
1627 
1628  for(i=0; i<8; i++) score[i]= s->mb_num*(8-i);
1629 
1630  for(y=0; y<s->mb_height; y++){
1631  int x;
1632  int xy= y*s->mb_stride;
1633  for(x=0; x<s->mb_width; x++, xy++){
1634  if(s->mb_type[xy] & type){
1635  int mx= mv_table[xy][0];
1636  int my= mv_table[xy][1];
1637  int fcode= FFMAX(fcode_tab[mx + MAX_MV],
1638  fcode_tab[my + MAX_MV]);
1639  int j;
1640 
1641  if (mx >= range || mx < -range ||
1642  my >= range || my < -range)
1643  continue;
1644 
1645  for(j=0; j<fcode && j<8; j++){
1646  if (s->pict_type == AV_PICTURE_TYPE_B ||
1647  s->mc_mb_var[xy] < s->mb_var[xy])
1648  score[j]-= 170;
1649  }
1650  }
1651  }
1652  }
1653 
1654  for(i=1; i<8; i++){
1655  if(score[i] > best_score){
1656  best_score= score[i];
1657  best_fcode= i;
1658  }
1659  }
1660 
1661  return best_fcode;
1662  }else{
1663  return 1;
1664  }
1665 }
1666 
1668 {
1669  MotionEstContext * const c= &s->me;
1670  const int f_code= s->f_code;
1671  int y, range;
1672  av_assert0(s->pict_type==AV_PICTURE_TYPE_P);
1673 
1674  range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version != MSMP4_UNUSED) ? 8 : 16) << f_code);
1675 
1676  av_assert0(range <= 16 || s->msmpeg4_version == MSMP4_UNUSED);
1677  av_assert0(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL));
1678 
1679  if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
1680 
1681  if (s->avctx->flags & AV_CODEC_FLAG_4MV) {
1682  const int wrap= s->b8_stride;
1683 
1684  /* clip / convert to intra 8x8 type MVs */
1685  for(y=0; y<s->mb_height; y++){
1686  int xy= y*2*wrap;
1687  int i= y*s->mb_stride;
1688  int x;
1689 
1690  for(x=0; x<s->mb_width; x++){
1691  if(s->mb_type[i]&CANDIDATE_MB_TYPE_INTER4V){
1692  int block;
1693  for(block=0; block<4; block++){
1694  int off= (block& 1) + (block>>1)*wrap;
1695  int mx = s->cur_pic.motion_val[0][ xy + off ][0];
1696  int my = s->cur_pic.motion_val[0][ xy + off ][1];
1697 
1698  if( mx >=range || mx <-range
1699  || my >=range || my <-range){
1700  s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V;
1701  s->mb_type[i] |= type;
1702  s->cur_pic.mb_type[i] = type;
1703  }
1704  }
1705  }
1706  xy+=2;
1707  i++;
1708  }
1709  }
1710  }
1711 }
1712 
1713 /**
1714  * @param truncate 1 for truncation, 0 for using intra
1715  */
1716 void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select,
1717  int16_t (*mv_table)[2], int f_code, int type, int truncate)
1718 {
1719  MotionEstContext * const c= &s->me;
1720  int y, h_range, v_range;
1721 
1722  // RAL: 8 in MPEG-1, 16 in MPEG-4
1723  int range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version != MSMP4_UNUSED) ? 8 : 16) << f_code);
1724 
1725  if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
1726 
1727  h_range= range;
1728  v_range= field_select_table ? range>>1 : range;
1729 
1730  /* clip / convert to intra 16x16 type MVs */
1731  for(y=0; y<s->mb_height; y++){
1732  int x;
1733  int xy= y*s->mb_stride;
1734  for(x=0; x<s->mb_width; x++){
1735  if (s->mb_type[xy] & type){ // RAL: "type" test added...
1736  if (!field_select_table || field_select_table[xy] == field_select) {
1737  if( mv_table[xy][0] >=h_range || mv_table[xy][0] <-h_range
1738  || mv_table[xy][1] >=v_range || mv_table[xy][1] <-v_range){
1739 
1740  if(truncate){
1741  if (mv_table[xy][0] > h_range-1) mv_table[xy][0]= h_range-1;
1742  else if(mv_table[xy][0] < -h_range ) mv_table[xy][0]= -h_range;
1743  if (mv_table[xy][1] > v_range-1) mv_table[xy][1]= v_range-1;
1744  else if(mv_table[xy][1] < -v_range ) mv_table[xy][1]= -v_range;
1745  }else{
1746  s->mb_type[xy] &= ~type;
1747  s->mb_type[xy] |= CANDIDATE_MB_TYPE_INTRA;
1748  mv_table[xy][0]=
1749  mv_table[xy][1]= 0;
1750  }
1751  }
1752  }
1753  }
1754  xy++;
1755  }
1756  }
1757 }
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:84
CANDIDATE_MB_TYPE_BIDIR
#define CANDIDATE_MB_TYPE_BIDIR
Definition: mpegvideoenc.h:48
MV_TYPE_16X16
#define MV_TYPE_16X16
1 vector for the whole mb
Definition: mpegvideo.h:265
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
fcode_tab
static uint8_t fcode_tab[MAX_MV *2+1]
Minimal fcode that a motion vector component would need.
Definition: ituh263enc.c:58
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:1667
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:1188
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:41
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
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:938
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:894
CANDIDATE_MB_TYPE_BACKWARD_I
#define CANDIDATE_MB_TYPE_BACKWARD_I
Definition: mpegvideoenc.h:52
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:754
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
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:53
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:43
FF_CMP_CHROMA
#define FF_CMP_CHROMA
Definition: avcodec.h:917
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:902
ff_sqrt
#define ff_sqrt
Definition: mathops.h:216
CANDIDATE_MB_TYPE_DIRECT
#define CANDIDATE_MB_TYPE_DIRECT
Definition: mpegvideoenc.h:45
CANDIDATE_MB_TYPE_INTER_I
#define CANDIDATE_MB_TYPE_INTER_I
Definition: mpegvideoenc.h:50
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:906
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:1502
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:876
init_interlaced_ref
static void init_interlaced_ref(MpegEncContext *s, int ref_index)
Definition: motion_est.c:741
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:46
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:51
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:47
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:1400
FF_MB_DECISION_SIMPLE
#define FF_MB_DECISION_SIMPLE
uses mb_cmp
Definition: avcodec.h:969
AVCodecContext::me_cmp
int me_cmp
motion estimation comparison function
Definition: avcodec.h:882
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:916
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:266
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:905
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:1076
FF_CMP_W53
#define FF_CMP_W53
Definition: avcodec.h:912
CANDIDATE_MB_TYPE_DIRECT0
#define CANDIDATE_MB_TYPE_DIRECT0
Definition: mpegvideoenc.h:55
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:40
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:903
AVCodecContext::me_sub_cmp
int me_sub_cmp
subpixel motion estimation comparison function
Definition: avcodec.h:888
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
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:901
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:53
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:42
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:1253
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:907
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:924
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FF_CMP_NSSE
#define FF_CMP_NSSE
Definition: avcodec.h:911
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:537
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:1129
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:1716
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:901
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:904
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
FF_MPV_FLAG_MV0
#define FF_MPV_FLAG_MV0
Definition: mpegvideoenc.h:63
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:945
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:915
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:1614
FF_ME_ZERO
#define FF_ME_ZERO
Definition: motion_est.h:41
FF_CMP_W97
#define FF_CMP_W97
Definition: avcodec.h:913
min
float min
Definition: vorbis_enc_data.h:429