Mercurial > libavcodec.hg
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 |