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