comparison motion_est.c @ 280:3dc1ca4ba717 libavcodec

fixing epzs & mpeg1 (hopefully now really ...)
author michaelni
date Fri, 22 Mar 2002 16:51:44 +0000
parents 5cb2978e701f
children 1fc96b02142e
comparison
equal deleted inserted replaced
279:ae5c33165d5c 280:3dc1ca4ba717
368 const int x= best[0]; 368 const int x= best[0];
369 const int y= best[1]; 369 const int y= best[1];
370 next_dir=-1; 370 next_dir=-1;
371 371
372 //printf("%d", dir); 372 //printf("%d", dir);
373 if(dir!=2 && x-1>=xmin) CHECK_MV_DIR(x-1, y , 0) 373 if(dir!=2 && x>xmin) CHECK_MV_DIR(x-1, y , 0)
374 if(dir!=3 && y-1>=ymin) CHECK_MV_DIR(x , y-1, 1) 374 if(dir!=3 && y>ymin) CHECK_MV_DIR(x , y-1, 1)
375 if(dir!=0 && x+1<=xmax) CHECK_MV_DIR(x+1, y , 2) 375 if(dir!=0 && x<xmax) CHECK_MV_DIR(x+1, y , 2)
376 if(dir!=1 && y+1<=ymax) CHECK_MV_DIR(x , y+1, 3) 376 if(dir!=1 && y<ymax) CHECK_MV_DIR(x , y+1, 3)
377 377
378 if(next_dir==-1){ 378 if(next_dir==-1){
379 return dmin; 379 return dmin;
380 } 380 }
381 } 381 }
382 } 382 }
383 383
384 static int epzs_motion_search(MpegEncContext * s, 384 static int epzs_motion_search(MpegEncContext * s,
385 int *mx_ptr, int *my_ptr, 385 int *mx_ptr, int *my_ptr,
386 int *px_ptr, int *py_ptr, 386 int P[5][2], int pred_x, int pred_y,
387 int xmin, int ymin, int xmax, int ymax) 387 int xmin, int ymin, int xmax, int ymax)
388 { 388 {
389 INT16 P_left[2], P_top[2], P_topright[2], P_last[2];
390 static const int off[4]= {2, 1, 1, -1};
391 int best[2]={0, 0}; 389 int best[2]={0, 0};
392 int d, dmin; 390 int d, dmin;
393 UINT8 *new_pic, *old_pic; 391 UINT8 *new_pic, *old_pic;
394 const int pic_stride= s->linesize; 392 const int pic_stride= s->linesize;
395 const int pic_xy= (s->mb_y*pic_stride + s->mb_x)*16; 393 const int pic_xy= (s->mb_y*pic_stride + s->mb_x)*16;
396 const int mot_stride = s->block_wrap[0];
397 const int mot_xy = s->block_index[0];
398 UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame 394 UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
399 int quant= s->qscale; // qscale of the prev frame 395 int quant= s->qscale; // qscale of the prev frame
400 int pred_x, pred_y;
401 const int shift= 1+s->quarter_sample; 396 const int shift= 1+s->quarter_sample;
402 397
403 new_pic = s->new_picture[0] + pic_xy; 398 new_pic = s->new_picture[0] + pic_xy;
404 old_pic = s->last_picture[0] + pic_xy; 399 old_pic = s->last_picture[0] + pic_xy;
405 400 //printf("%d %d %d %d\n", xmin, ymin, xmax, ymax);
406 xmin-=s->mb_x*16;
407 xmax-=s->mb_x*16;
408 ymin-=s->mb_y*16;
409 ymax-=s->mb_y*16;
410 401
411 dmin = pix_abs16x16(new_pic, old_pic, pic_stride, 16); 402 dmin = pix_abs16x16(new_pic, old_pic, pic_stride, 16);
412 if(dmin<Z_THRESHOLD){ 403 if(dmin<Z_THRESHOLD){
413 *mx_ptr= 0; 404 *mx_ptr= 0;
414 *my_ptr= 0; 405 *my_ptr= 0;
415 //printf("Z"); 406 //printf("Z");
416 return dmin; 407 return dmin;
417 } 408 }
418 409
419 P_last[0] = s->motion_val[mot_xy ][0]; 410 /* first line */
420 P_last[1] = s->motion_val[mot_xy ][1];
421 P_left[0] = s->motion_val[mot_xy - 1][0];
422 P_left[1] = s->motion_val[mot_xy - 1][1];
423 if(P_left[0] > (xmax<<shift)) P_left[0]= (xmax<<shift);
424
425 /* special case for first line */
426 if ((s->mb_y == 0 || s->first_slice_line || s->first_gob_line)) { 411 if ((s->mb_y == 0 || s->first_slice_line || s->first_gob_line)) {
427 *px_ptr= pred_x = P_left[0]; 412 CHECK_MV(P[1][0]>>shift, P[1][1]>>shift)
428 *py_ptr= pred_y = P_left[1]; 413 }else{
429 CHECK_MV(pred_x>>shift, pred_y>>shift) 414 CHECK_MV(P[4][0]>>shift, P[4][1]>>shift)
430 if(dmin<Z_THRESHOLD){ 415 if(dmin<Z_THRESHOLD){
431 *mx_ptr= pred_x>>shift; 416 *mx_ptr= P[4][0]>>shift;
432 *my_ptr= pred_y>>shift; 417 *my_ptr= P[4][1]>>shift;
433 //printf("M"); 418 //printf("M\n");
434 return dmin; 419 return dmin;
435 } 420 }
436 } else { 421 CHECK_MV(P[1][0]>>shift, P[1][1]>>shift)
437 P_top [0] = s->motion_val[mot_xy - mot_stride ][0]; 422 CHECK_MV(P[2][0]>>shift, P[2][1]>>shift)
438 P_top [1] = s->motion_val[mot_xy - mot_stride ][1]; 423 CHECK_MV(P[3][0]>>shift, P[3][1]>>shift)
439 P_topright[0] = s->motion_val[mot_xy - mot_stride + off[0] ][0]; 424 }
440 P_topright[1] = s->motion_val[mot_xy - mot_stride + off[0] ][1]; 425 CHECK_MV(P[0][0]>>shift, P[0][1]>>shift)
441 if(P_top [1] > (ymax<<shift)) P_top [1]= (ymax<<shift);
442 if(P_topright[0] < (xmin<<shift)) P_topright[0]= (xmin<<shift);
443 if(P_topright[1] > (ymax<<shift)) P_topright[1]= (ymax<<shift);
444
445 *px_ptr= pred_x = mid_pred(P_left[0], P_top[0], P_topright[0]);
446 *py_ptr= pred_y = mid_pred(P_left[1], P_top[1], P_topright[1]);
447
448 CHECK_MV(pred_x>>shift, pred_y>>shift)
449 if(dmin<Z_THRESHOLD){
450 *mx_ptr= pred_x>>shift;
451 *my_ptr= pred_y>>shift;
452 //printf("M");
453 return dmin;
454 }
455
456 CHECK_MV(P_left [0]>>shift, P_left [1]>>shift)
457 CHECK_MV(P_top [0]>>shift, P_top [1]>>shift)
458 CHECK_MV(P_topright[0]>>shift, P_topright[1]>>shift)
459 CHECK_MV(P_last [0]>>shift, P_last [1]>>shift)
460 }
461 426
462 dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride, 427 dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride,
463 pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift); 428 pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift);
464 *mx_ptr= best[0]; 429 *mx_ptr= best[0];
465 *my_ptr= best[1]; 430 *my_ptr= best[1];
466 431
467 // printf("%d %d %d \n", best[0], best[1], dmin); 432 // printf("%d %d %d \n", best[0], best[1], dmin);
468 433
469 return dmin; 434 return dmin;
470 } 435 }
543 int *mx_ptr, int *my_ptr) 508 int *mx_ptr, int *my_ptr)
544 { 509 {
545 UINT8 *pix, *ppix; 510 UINT8 *pix, *ppix;
546 int sum, varc, vard, mx, my, range, dmin, xx, yy; 511 int sum, varc, vard, mx, my, range, dmin, xx, yy;
547 int xmin, ymin, xmax, ymax; 512 int xmin, ymin, xmax, ymax;
513 int rel_xmin, rel_ymin, rel_xmax, rel_ymax;
548 int pred_x=0, pred_y=0; 514 int pred_x=0, pred_y=0;
515 int P[5][2];
516 const int shift= 1+s->quarter_sample;
549 517
550 range = 8 * (1 << (s->f_code - 1)); 518 range = 8 * (1 << (s->f_code - 1));
551 /* XXX: temporary kludge to avoid overflow for msmpeg4 */ 519 /* XXX: temporary kludge to avoid overflow for msmpeg4 */
552 if (s->out_format == FMT_H263 && !s->h263_msmpeg4) 520 if (s->out_format == FMT_H263 && !s->h263_msmpeg4)
553 range = range * 2; 521 range = range * 2;
587 case ME_PHODS: 555 case ME_PHODS:
588 dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax); 556 dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax);
589 break; 557 break;
590 case ME_X1: // just reserving some space for experiments ... 558 case ME_X1: // just reserving some space for experiments ...
591 case ME_EPZS: 559 case ME_EPZS:
592 dmin = epzs_motion_search(s, &mx, &my, &pred_x, &pred_y, xmin, ymin, xmax, ymax); 560 rel_xmin= xmin - s->mb_x*16;
561 rel_xmax= xmax - s->mb_x*16;
562 rel_ymin= ymin - s->mb_y*16;
563 rel_ymax= ymax - s->mb_y*16;
564 if(s->out_format == FMT_H263){
565 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];
568
569 P[0][0] = s->motion_val[mot_xy ][0];
570 P[0][1] = s->motion_val[mot_xy ][1];
571 P[1][0] = s->motion_val[mot_xy - 1][0];
572 P[1][1] = s->motion_val[mot_xy - 1][1];
573 if(P[1][0] > (rel_xmax<<shift)) P[1][0]= (rel_xmax<<shift);
574
575 /* special case for first line */
576 if ((s->mb_y == 0 || s->first_slice_line || s->first_gob_line)) {
577 pred_x = P[1][0];
578 pred_y = P[1][1];
579 } else {
580 P[2][0] = s->motion_val[mot_xy - mot_stride ][0];
581 P[2][1] = s->motion_val[mot_xy - mot_stride ][1];
582 P[3][0] = s->motion_val[mot_xy - mot_stride + off[0] ][0];
583 P[3][1] = s->motion_val[mot_xy - mot_stride + off[0] ][1];
584 if(P[2][1] > (rel_ymax<<shift)) P[2][1]= (rel_ymax<<shift);
585 if(P[3][0] < (rel_xmin<<shift)) P[3][0]= (rel_xmin<<shift);
586 if(P[3][1] > (rel_ymax<<shift)) P[3][1]= (rel_ymax<<shift);
587
588 P[4][0]= pred_x = mid_pred(P[1][0], P[2][0], P[3][0]);
589 P[4][1]= pred_y = mid_pred(P[1][1], P[2][1], P[3][1]);
590 }
591 }else {
592 const int xy= s->mb_y*s->mb_width + s->mb_x;
593 pred_x= s->last_mv[0][0][0];
594 pred_y= s->last_mv[0][0][1];
595
596 P[0][0]= s->mv_table[0][xy ];
597 P[0][1]= s->mv_table[1][xy ];
598 if(s->mb_x == 0){
599 P[1][0]= 0;
600 P[1][1]= 0;
601 }else{
602 P[1][0]= s->mv_table[0][xy-1];
603 P[1][1]= s->mv_table[1][xy-1];
604 if(P[1][0] > (rel_xmax<<shift)) P[1][0]= (rel_xmax<<shift);
605 }
606
607 if (!(s->mb_y == 0 || s->first_slice_line || s->first_gob_line)) {
608 P[2][0] = s->mv_table[0][xy - s->mb_width];
609 P[2][1] = s->mv_table[1][xy - s->mb_width];
610 P[3][0] = s->mv_table[0][xy - s->mb_width+1];
611 P[3][1] = s->mv_table[1][xy - s->mb_width+1];
612 if(P[2][1] > (rel_ymax<<shift)) P[2][1]= (rel_ymax<<shift);
613 if(P[3][0] > (rel_xmax<<shift)) P[3][0]= (rel_xmax<<shift);
614 if(P[3][0] < (rel_xmin<<shift)) P[3][0]= (rel_xmin<<shift);
615 if(P[3][1] > (rel_ymax<<shift)) P[3][1]= (rel_ymax<<shift);
616
617 P[4][0]= mid_pred(P[1][0], P[2][0], P[3][0]);
618 P[4][1]= mid_pred(P[1][1], P[2][1], P[3][1]);
619 }
620 }
621 dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax);
593 mx+= s->mb_x*16; 622 mx+= s->mb_x*16;
594 my+= s->mb_y*16; 623 my+= s->mb_y*16;
595 break; 624 break;
596 } 625 }
597 626