Mercurial > libavcodec.hg
comparison mpegvideo.c @ 255:db20b987c32d libavcodec
divx5-gmc support
q-pel mc support
neither is totally bugfree yet though :(
author | michaelni |
---|---|
date | Sat, 09 Mar 2002 13:01:16 +0000 |
parents | ddb1a0e94cf4 |
children | b8d11794f675 |
comparison
equal
deleted
inserted
replaced
254:b4fed8b24e3a | 255:db20b987c32d |
---|---|
539 return amax; | 539 return amax; |
540 else | 540 else |
541 return a; | 541 return a; |
542 } | 542 } |
543 | 543 |
544 static inline void gmc1_motion(MpegEncContext *s, | |
545 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, | |
546 int dest_offset, | |
547 UINT8 **ref_picture, int src_offset, | |
548 int h) | |
549 { | |
550 UINT8 *ptr; | |
551 int dxy, offset, mx, my, src_x, src_y, height, linesize; | |
552 int motion_x, motion_y; | |
553 | |
554 if(s->real_sprite_warping_points>1) printf("Oops, thats bad, contact the developers\n"); | |
555 motion_x= s->sprite_offset[0][0]; | |
556 motion_y= s->sprite_offset[0][1]; | |
557 src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1)); | |
558 src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1)); | |
559 motion_x<<=(3-s->sprite_warping_accuracy); | |
560 motion_y<<=(3-s->sprite_warping_accuracy); | |
561 src_x = clip(src_x, -16, s->width); | |
562 if (src_x == s->width) | |
563 motion_x =0; | |
564 src_y = clip(src_y, -16, s->height); | |
565 if (src_y == s->height) | |
566 motion_y =0; | |
567 | |
568 linesize = s->linesize; | |
569 ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset; | |
570 | |
571 dest_y+=dest_offset; | |
572 gmc1(dest_y , ptr , linesize, h, motion_x&15, motion_y&15, s->no_rounding); | |
573 gmc1(dest_y+8, ptr+8, linesize, h, motion_x&15, motion_y&15, s->no_rounding); | |
574 | |
575 motion_x= s->sprite_offset[1][0]; | |
576 motion_y= s->sprite_offset[1][1]; | |
577 src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1)); | |
578 src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1)); | |
579 motion_x<<=(3-s->sprite_warping_accuracy); | |
580 motion_y<<=(3-s->sprite_warping_accuracy); | |
581 src_x = clip(src_x, -8, s->width>>1); | |
582 if (src_x == s->width>>1) | |
583 motion_x =0; | |
584 src_y = clip(src_y, -8, s->height>>1); | |
585 if (src_y == s->height>>1) | |
586 motion_y =0; | |
587 | |
588 offset = (src_y * linesize>>1) + src_x + (src_offset>>1); | |
589 ptr = ref_picture[1] + offset; | |
590 gmc1(dest_cb + (dest_offset>>1), ptr, linesize>>1, h>>1, motion_x&15, motion_y&15, s->no_rounding); | |
591 ptr = ref_picture[2] + offset; | |
592 gmc1(dest_cr + (dest_offset>>1), ptr, linesize>>1, h>>1, motion_x&15, motion_y&15, s->no_rounding); | |
593 | |
594 return; | |
595 } | |
596 | |
544 /* apply one mpeg motion vector to the three components */ | 597 /* apply one mpeg motion vector to the three components */ |
545 static inline void mpeg_motion(MpegEncContext *s, | 598 static inline void mpeg_motion(MpegEncContext *s, |
546 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, | 599 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, |
547 int dest_offset, | 600 int dest_offset, |
548 UINT8 **ref_picture, int src_offset, | 601 UINT8 **ref_picture, int src_offset, |
549 int field_based, op_pixels_func *pix_op, | 602 int field_based, op_pixels_func *pix_op, |
550 int motion_x, int motion_y, int h) | 603 int motion_x, int motion_y, int h) |
551 { | 604 { |
552 UINT8 *ptr; | 605 UINT8 *ptr; |
553 int dxy, offset, mx, my, src_x, src_y, height, linesize; | 606 int dxy, offset, mx, my, src_x, src_y, height, linesize; |
554 | 607 if(s->quarter_sample) |
608 { | |
609 motion_x>>=1; | |
610 motion_y>>=1; | |
611 } | |
555 dxy = ((motion_y & 1) << 1) | (motion_x & 1); | 612 dxy = ((motion_y & 1) << 1) | (motion_x & 1); |
556 src_x = s->mb_x * 16 + (motion_x >> 1); | 613 src_x = s->mb_x * 16 + (motion_x >> 1); |
557 src_y = s->mb_y * (16 >> field_based) + (motion_y >> 1); | 614 src_y = s->mb_y * (16 >> field_based) + (motion_y >> 1); |
558 | 615 |
559 /* WARNING: do no forget half pels */ | 616 /* WARNING: do no forget half pels */ |
600 pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); | 657 pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); |
601 ptr = ref_picture[2] + offset; | 658 ptr = ref_picture[2] + offset; |
602 pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); | 659 pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); |
603 } | 660 } |
604 | 661 |
662 static inline void qpel_motion(MpegEncContext *s, | |
663 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, | |
664 int dest_offset, | |
665 UINT8 **ref_picture, int src_offset, | |
666 int field_based, op_pixels_func *pix_op, | |
667 qpel_mc_func *qpix_op, | |
668 int motion_x, int motion_y, int h) | |
669 { | |
670 UINT8 *ptr; | |
671 int dxy, offset, mx, my, src_x, src_y, height, linesize; | |
672 | |
673 dxy = ((motion_y & 3) << 2) | (motion_x & 3); | |
674 src_x = s->mb_x * 16 + (motion_x >> 2); | |
675 src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); | |
676 | |
677 height = s->height >> field_based; | |
678 src_x = clip(src_x, -16, s->width); | |
679 if (src_x == s->width) | |
680 dxy &= ~3; | |
681 src_y = clip(src_y, -16, height); | |
682 if (src_y == height) | |
683 dxy &= ~12; | |
684 linesize = s->linesize << field_based; | |
685 ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset; | |
686 dest_y += dest_offset; | |
687 //printf("%d %d %d\n", src_x, src_y, dxy); | |
688 qpix_op[dxy](dest_y , ptr , linesize, linesize, motion_x&3, motion_y&3); | |
689 qpix_op[dxy](dest_y + 8, ptr + 8, linesize, linesize, motion_x&3, motion_y&3); | |
690 qpix_op[dxy](dest_y + linesize*8 , ptr + linesize*8 , linesize, linesize, motion_x&3, motion_y&3); | |
691 qpix_op[dxy](dest_y + linesize*8 + 8, ptr + linesize*8 + 8, linesize, linesize, motion_x&3, motion_y&3); | |
692 | |
693 mx= (motion_x>>1) | (motion_x&1); | |
694 my= (motion_y>>1) | (motion_y&1); | |
695 | |
696 dxy = 0; | |
697 if ((mx & 3) != 0) | |
698 dxy |= 1; | |
699 if ((my & 3) != 0) | |
700 dxy |= 2; | |
701 mx = mx >> 2; | |
702 my = my >> 2; | |
703 | |
704 src_x = s->mb_x * 8 + mx; | |
705 src_y = s->mb_y * (8 >> field_based) + my; | |
706 src_x = clip(src_x, -8, s->width >> 1); | |
707 if (src_x == (s->width >> 1)) | |
708 dxy &= ~1; | |
709 src_y = clip(src_y, -8, height >> 1); | |
710 if (src_y == (height >> 1)) | |
711 dxy &= ~2; | |
712 | |
713 offset = (src_y * (linesize >> 1)) + src_x + (src_offset >> 1); | |
714 ptr = ref_picture[1] + offset; | |
715 pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); | |
716 ptr = ref_picture[2] + offset; | |
717 pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); | |
718 } | |
719 | |
720 | |
605 static inline void MPV_motion(MpegEncContext *s, | 721 static inline void MPV_motion(MpegEncContext *s, |
606 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, | 722 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, |
607 int dir, UINT8 **ref_picture, | 723 int dir, UINT8 **ref_picture, |
608 op_pixels_func *pix_op) | 724 op_pixels_func *pix_op, qpel_mc_func *qpix_op) |
609 { | 725 { |
610 int dxy, offset, mx, my, src_x, src_y, motion_x, motion_y; | 726 int dxy, offset, mx, my, src_x, src_y, motion_x, motion_y; |
611 int mb_x, mb_y, i; | 727 int mb_x, mb_y, i; |
612 UINT8 *ptr, *dest; | 728 UINT8 *ptr, *dest; |
613 | 729 |
614 mb_x = s->mb_x; | 730 mb_x = s->mb_x; |
615 mb_y = s->mb_y; | 731 mb_y = s->mb_y; |
616 | 732 |
617 switch(s->mv_type) { | 733 switch(s->mv_type) { |
618 case MV_TYPE_16X16: | 734 case MV_TYPE_16X16: |
619 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, | 735 if(s->mcsel){ |
620 ref_picture, 0, | 736 #if 0 |
621 0, pix_op, | 737 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, |
622 s->mv[dir][0][0], s->mv[dir][0][1], 16); | 738 ref_picture, 0, |
739 0, pix_op, | |
740 s->sprite_offset[0][0]>>3, | |
741 s->sprite_offset[0][1]>>3, | |
742 16); | |
743 #else | |
744 gmc1_motion(s, dest_y, dest_cb, dest_cr, 0, | |
745 ref_picture, 0, | |
746 16); | |
747 #endif | |
748 }else if(s->quarter_sample){ | |
749 qpel_motion(s, dest_y, dest_cb, dest_cr, 0, | |
750 ref_picture, 0, | |
751 0, pix_op, qpix_op, | |
752 s->mv[dir][0][0], s->mv[dir][0][1], 16); | |
753 }else{ | |
754 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, | |
755 ref_picture, 0, | |
756 0, pix_op, | |
757 s->mv[dir][0][0], s->mv[dir][0][1], 16); | |
758 } | |
623 break; | 759 break; |
624 case MV_TYPE_8X8: | 760 case MV_TYPE_8X8: |
625 for(i=0;i<4;i++) { | 761 for(i=0;i<4;i++) { |
626 motion_x = s->mv[dir][i][0]; | 762 motion_x = s->mv[dir][i][0]; |
627 motion_y = s->mv[dir][i][1]; | 763 motion_y = s->mv[dir][i][1]; |
738 void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | 874 void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) |
739 { | 875 { |
740 int mb_x, mb_y; | 876 int mb_x, mb_y; |
741 int dct_linesize, dct_offset; | 877 int dct_linesize, dct_offset; |
742 op_pixels_func *op_pix; | 878 op_pixels_func *op_pix; |
879 qpel_mc_func *op_qpix; | |
743 | 880 |
744 mb_x = s->mb_x; | 881 mb_x = s->mb_x; |
745 mb_y = s->mb_y; | 882 mb_y = s->mb_y; |
746 | 883 |
747 #ifdef FF_POSTPROCESS | 884 #ifdef FF_POSTPROCESS |
849 dct_offset = s->linesize * 8; | 986 dct_offset = s->linesize * 8; |
850 } | 987 } |
851 | 988 |
852 if (!s->mb_intra) { | 989 if (!s->mb_intra) { |
853 /* motion handling */ | 990 /* motion handling */ |
854 if (!s->no_rounding) | 991 if (!s->no_rounding){ |
855 op_pix = put_pixels_tab; | 992 op_pix = put_pixels_tab; |
856 else | 993 op_qpix= qpel_mc_rnd_tab; |
994 }else{ | |
857 op_pix = put_no_rnd_pixels_tab; | 995 op_pix = put_no_rnd_pixels_tab; |
996 op_qpix= qpel_mc_no_rnd_tab; | |
997 } | |
858 | 998 |
859 if (s->mv_dir & MV_DIR_FORWARD) { | 999 if (s->mv_dir & MV_DIR_FORWARD) { |
860 MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix); | 1000 MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix); |
861 if (!s->no_rounding) | 1001 if (!s->no_rounding) |
862 op_pix = avg_pixels_tab; | 1002 op_pix = avg_pixels_tab; |
863 else | 1003 else |
864 op_pix = avg_no_rnd_pixels_tab; | 1004 op_pix = avg_no_rnd_pixels_tab; |
865 } | 1005 } |
866 if (s->mv_dir & MV_DIR_BACKWARD) { | 1006 if (s->mv_dir & MV_DIR_BACKWARD) { |
867 MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix); | 1007 MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix); |
868 } | 1008 } |
869 | 1009 |
870 /* add dct residue */ | 1010 /* add dct residue */ |
871 add_dct(s, block[0], 0, dest_y, dct_linesize); | 1011 add_dct(s, block[0], 0, dest_y, dct_linesize); |
872 add_dct(s, block[1], 1, dest_y + 8, dct_linesize); | 1012 add_dct(s, block[1], 1, dest_y + 8, dct_linesize); |