Revision 11ce8834 libavcodec/motion_est.c
libavcodec/motion_est.c  

335  335 
#define Z_THRESHOLD 256 
336  336  
337  337 
#define CHECK_MV(x,y)\ 
338 
{\ 

338  339 
d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16);\ 
339  340 
d += (mv_penalty[((x)<<shift)pred_x] + mv_penalty[((y)<<shift)pred_y])*quant;\ 
340  341 
if(d<dmin){\ 
341  342 
best[0]=x;\ 
342  343 
best[1]=y;\ 
343  344 
dmin=d;\ 
344 
} 

345 
}\ 

346 
} 

345  347  
346  348 
#define CHECK_MV_DIR(x,y,new_dir)\ 
347  349 
{\ 
...  ...  
355  357 
}\ 
356  358 
} 
357  359  
360 
#define check(x,y,S,v)\ 

361 
if( (x)<(xmin<<(S)) ) printf("%d %d %d %d xmin" #v, (x), (y), s>mb_x, s>mb_y);\ 

362 
if( (x)>(xmax<<(S)) ) printf("%d %d %d %d xmax" #v, (x), (y), s>mb_x, s>mb_y);\ 

363 
if( (y)<(ymin<<(S)) ) printf("%d %d %d %d ymin" #v, (x), (y), s>mb_x, s>mb_y);\ 

364 
if( (y)>(ymax<<(S)) ) printf("%d %d %d %d ymax" #v, (x), (y), s>mb_x, s>mb_y);\ 

365  
366  
358  367 
static inline int small_diamond_search(MpegEncContext * s, int *best, int dmin, 
359  368 
UINT8 *new_pic, UINT8 *old_pic, int pic_stride, 
360  369 
int pred_x, int pred_y, UINT16 *mv_penalty, int quant, 
...  ...  
379  388 
return dmin; 
380  389 
} 
381  390 
} 
391  
392 
/* for(;;){ 

393 
int d; 

394 
const int x= best[0]; 

395 
const int y= best[1]; 

396 
const int last_min=dmin; 

397 
if(x>xmin) CHECK_MV(x1, y ) 

398 
if(y>xmin) CHECK_MV(x , y1) 

399 
if(x<xmax) CHECK_MV(x+1, y ) 

400 
if(y<xmax) CHECK_MV(x , y+1) 

401 
if(x>xmin && y>ymin) CHECK_MV(x1, y1) 

402 
if(x>xmin && y<ymax) CHECK_MV(x1, y+1) 

403 
if(x<xmax && y>ymin) CHECK_MV(x+1, y1) 

404 
if(x<xmax && y<ymax) CHECK_MV(x+1, y+1) 

405 
if(x1>xmin) CHECK_MV(x2, y ) 

406 
if(y1>xmin) CHECK_MV(x , y2) 

407 
if(x+1<xmax) CHECK_MV(x+2, y ) 

408 
if(y+1<xmax) CHECK_MV(x , y+2) 

409 
if(x1>xmin && y1>ymin) CHECK_MV(x2, y2) 

410 
if(x1>xmin && y+1<ymax) CHECK_MV(x2, y+2) 

411 
if(x+1<xmax && y1>ymin) CHECK_MV(x+2, y2) 

412 
if(x+1<xmax && y+1<ymax) CHECK_MV(x+2, y+2) 

413 
if(dmin==last_min) return dmin; 

414 
} 

415 
*/ 

416 
} 

417  
418 
static inline int snake_search(MpegEncContext * s, int *best, int dmin, 

419 
UINT8 *new_pic, UINT8 *old_pic, int pic_stride, 

420 
int pred_x, int pred_y, UINT16 *mv_penalty, int quant, 

421 
int xmin, int ymin, int xmax, int ymax, int shift) 

422 
{ 

423 
int dir=0; 

424 
int c=1; 

425 
static int x_dir[8]= {1,1,0,1,1,1, 0, 1}; 

426 
static int y_dir[8]= {0,1,1, 1, 0,1,1,1}; 

427 
int fails=0; 

428 
int last_d[2]={dmin, dmin}; 

429  
430 
/*static int good=0; 

431 
static int bad=0; 

432 
static int point=0; 

433  
434 
point++; 

435 
if(256*256*256*64%point==0) 

436 
{ 

437 
printf("%d %d %d\n", good, bad, point); 

438 
}*/ 

439  
440 
for(;;){ 

441 
int x= best[0]; 

442 
int y= best[1]; 

443 
int d; 

444 
x+=x_dir[dir]; 

445 
y+=y_dir[dir]; 

446 
if(x>=xmin && x<=xmax && y>=ymin && y<=ymax){ 

447 
d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16); 

448 
d += (mv_penalty[((x)<<shift)pred_x] + mv_penalty[((y)<<shift)pred_y])*quant; 

449 
}else{ 

450 
d = dmin + 10000; //FIXME smarter boundary handling 

451 
} 

452 
if(d<dmin){ 

453 
best[0]=x; 

454 
best[1]=y; 

455 
dmin=d; 

456  
457 
if(last_d[1]  last_d[0] > last_d[0]  d) c= c; 

458 
dir+=c; 

459  
460 
fails=0; 

461 
//good++; 

462 
last_d[1]=last_d[0]; 

463 
last_d[0]=d; 

464 
}else{ 

465 
//bad++; 

466 
if(fails){ 

467 
if(fails>=3) return dmin; 

468 
}else{ 

469 
c= c; 

470 
} 

471 
dir+=c*2; 

472 
fails++; 

473 
} 

474 
dir&=7; 

475 
} 

382  476 
} 
383  477  
384  478 
static int epzs_motion_search(MpegEncContext * s, 
...  ...  
397  491  
398  492 
new_pic = s>new_picture[0] + pic_xy; 
399  493 
old_pic = s>last_picture[0] + pic_xy; 
400 
//printf("%d %d %d %d\n", xmin, ymin, xmax, ymax); 

401 


494 


402  495 
dmin = pix_abs16x16(new_pic, old_pic, pic_stride, 16); 
403  496 
if(dmin<Z_THRESHOLD){ 
404  497 
*mx_ptr= 0; 
...  ...  
424  517 
} 
425  518 
CHECK_MV(P[0][0]>>shift, P[0][1]>>shift) 
426  519  
427 
dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride, 

428 
pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift); 

520 
//check(best[0],best[1],0, b0) 

521 
if(s>full_search==ME_EPZS) 

522 
dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride, 

523 
pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift); 

524 
else 

525 
dmin= snake_search(s, best, dmin, new_pic, old_pic, pic_stride, 

526 
pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift); 

527 
//check(best[0],best[1],0, b1) 

429  528 
*mx_ptr= best[0]; 
430  529 
*my_ptr= best[1]; 
431  530  
432  531 
// printf("%d %d %d \n", best[0], best[1], dmin); 
433  
434  532 
return dmin; 
435  533 
} 
436  534  
...  ...  
563  661 
rel_ymax= ymax  s>mb_y*16; 
564  662 
if(s>out_format == FMT_H263){ 
565  663 
static const int off[4]= {2, 1, 1, 1}; 
566 
const int mot_stride = s>block_wrap[0];


567 
const int mot_xy = s>block_index[0];


664 
const int mot_stride = s>mb_width*2 + 2;


665 
const int mot_xy = (s>mb_y*2 + 1)*mot_stride + s>mb_x*2 + 1;


568  666 

569  667 
P[0][0] = s>motion_val[mot_xy ][0]; 
570  668 
P[0][1] = s>motion_val[mot_xy ][1]; 
...  ...  
618  716 
P[4][1]= mid_pred(P[1][1], P[2][1], P[3][1]); 
619  717 
} 
620  718 
} 
621 
dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax); 

719 
dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax); 

720 


622  721 
mx+= s>mb_x*16; 
623  722 
my+= s>mb_y*16; 
624  723 
break; 
...  ...  
654  753 
mx = 16 * s>mb_x; 
655  754 
my = 16 * s>mb_y; 
656  755 
} 
756 
// check(mx + 32*s>mb_x, my + 32*s>mb_y, 1, end) 

757 


657  758 
*mx_ptr = mx; 
658  759 
*my_ptr = my; 
659  760 
return 0; 
Also available in: Unified diff