Revision 11ce8834 libavcodec/motion_est.c

View differences:

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(x-1, y  )
398
        if(y>xmin) CHECK_MV(x  , y-1)
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(x-1, y-1)
402
        if(x>xmin && y<ymax) CHECK_MV(x-1, y+1)
403
        if(x<xmax && y>ymin) CHECK_MV(x+1, y-1)
404
        if(x<xmax && y<ymax) CHECK_MV(x+1, y+1)
405
        if(x-1>xmin) CHECK_MV(x-2, y  )
406
        if(y-1>xmin) CHECK_MV(x  , y-2)
407
        if(x+1<xmax) CHECK_MV(x+2, y  )
408
        if(y+1<xmax) CHECK_MV(x  , y+2)
409
        if(x-1>xmin && y-1>ymin) CHECK_MV(x-2, y-2)
410
        if(x-1>xmin && y+1<ymax) CHECK_MV(x-2, y+2)
411
        if(x+1<xmax && y-1>ymin) CHECK_MV(x+2, y-2)
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