Mercurial > libavcodec.hg
comparison motion_est.c @ 1086:d3b93dc997a3 libavcodec
user specified motion estimation range limit
h263 me range fixed (was smaller then needed)
author | michaelni |
---|---|
date | Thu, 27 Feb 2003 22:56:07 +0000 |
parents | b32afefe7d33 |
children | 1e39f273ecd6 |
comparison
equal
deleted
inserted
replaced
1085:9acf4b552047 | 1086:d3b93dc997a3 |
---|---|
789 s->motion_val[mot_xy+1][0]= mx; | 789 s->motion_val[mot_xy+1][0]= mx; |
790 s->motion_val[mot_xy+1][1]= my; | 790 s->motion_val[mot_xy+1][1]= my; |
791 } | 791 } |
792 } | 792 } |
793 | 793 |
794 static inline void get_limits(MpegEncContext *s, int *range, int *xmin, int *ymin, int *xmax, int *ymax, int f_code) | 794 /** |
795 { | 795 * get fullpel ME search limits. |
796 *range = 8 * (1 << (f_code - 1)); | 796 * @param range the approximate search range for the old ME code, unused for EPZS and newer |
797 /* XXX: temporary kludge to avoid overflow for msmpeg4 */ | 797 */ |
798 if (s->out_format == FMT_H263 && !s->h263_msmpeg4) | 798 static inline void get_limits(MpegEncContext *s, int *range, int *xmin, int *ymin, int *xmax, int *ymax) |
799 *range *= 2; | 799 { |
800 if(s->avctx->me_range) *range= s->avctx->me_range >> 1; | |
801 else *range= 16; | |
800 | 802 |
801 if (s->unrestricted_mv) { | 803 if (s->unrestricted_mv) { |
802 *xmin = -16; | 804 *xmin = -16; |
803 *ymin = -16; | 805 *ymin = -16; |
804 if (s->h263_plus) | |
805 *range *= 2; | |
806 if(s->avctx->codec->id!=CODEC_ID_MPEG4){ | 806 if(s->avctx->codec->id!=CODEC_ID_MPEG4){ |
807 *xmax = s->mb_width*16; | 807 *xmax = s->mb_width*16; |
808 *ymax = s->mb_height*16; | 808 *ymax = s->mb_height*16; |
809 }else { | 809 }else { |
810 *xmax = s->width; | 810 *xmax = s->width; |
814 *xmin = 0; | 814 *xmin = 0; |
815 *ymin = 0; | 815 *ymin = 0; |
816 *xmax = s->mb_width*16 - 16; | 816 *xmax = s->mb_width*16 - 16; |
817 *ymax = s->mb_height*16 - 16; | 817 *ymax = s->mb_height*16 - 16; |
818 } | 818 } |
819 | |
820 //FIXME try to limit x/y min/max if me_range is set | |
819 } | 821 } |
820 | 822 |
821 static inline int h263_mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, int ymax, int mx, int my, int shift) | 823 static inline int h263_mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, int ymax, int mx, int my, int shift) |
822 { | 824 { |
823 int block; | 825 int block; |
980 | 982 |
981 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); | 983 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); |
982 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); | 984 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); |
983 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); | 985 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); |
984 | 986 |
985 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code); | 987 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax); |
986 rel_xmin= xmin - mb_x*16; | 988 rel_xmin= xmin - mb_x*16; |
987 rel_xmax= xmax - mb_x*16; | 989 rel_xmax= xmax - mb_x*16; |
988 rel_ymin= ymin - mb_y*16; | 990 rel_ymin= ymin - mb_y*16; |
989 rel_ymax= ymax - mb_y*16; | 991 rel_ymax= ymax - mb_y*16; |
990 s->me.skip=0; | 992 s->me.skip=0; |
1149 | 1151 |
1150 assert(s->quarter_sample==0 || s->quarter_sample==1); | 1152 assert(s->quarter_sample==0 || s->quarter_sample==1); |
1151 | 1153 |
1152 s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp); | 1154 s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp); |
1153 | 1155 |
1154 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code); | 1156 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax); |
1155 rel_xmin= xmin - mb_x*16; | 1157 rel_xmin= xmin - mb_x*16; |
1156 rel_xmax= xmax - mb_x*16; | 1158 rel_xmax= xmax - mb_x*16; |
1157 rel_ymin= ymin - mb_y*16; | 1159 rel_ymin= ymin - mb_y*16; |
1158 rel_ymax= ymax - mb_y*16; | 1160 rel_ymax= ymax - mb_y*16; |
1159 s->me.skip=0; | 1161 s->me.skip=0; |
1210 | 1212 |
1211 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); | 1213 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); |
1212 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); | 1214 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); |
1213 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); | 1215 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); |
1214 | 1216 |
1215 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, f_code); | 1217 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax); |
1216 rel_xmin= xmin - mb_x*16; | 1218 rel_xmin= xmin - mb_x*16; |
1217 rel_xmax= xmax - mb_x*16; | 1219 rel_xmax= xmax - mb_x*16; |
1218 rel_ymin= ymin - mb_y*16; | 1220 rel_ymin= ymin - mb_y*16; |
1219 rel_ymax= ymax - mb_y*16; | 1221 rel_ymax= ymax - mb_y*16; |
1220 | 1222 |
1581 } | 1583 } |
1582 | 1584 |
1583 void ff_fix_long_p_mvs(MpegEncContext * s) | 1585 void ff_fix_long_p_mvs(MpegEncContext * s) |
1584 { | 1586 { |
1585 const int f_code= s->f_code; | 1587 const int f_code= s->f_code; |
1586 int y; | 1588 int y, range; |
1587 uint8_t * fcode_tab= s->fcode_tab; | 1589 |
1588 //int clip=0; | 1590 range = (((s->codec_id == CODEC_ID_MPEG1VIDEO) ? 8 : 16) << f_code); |
1589 //int noclip=0; | 1591 |
1592 if(s->msmpeg4_version) range= 16; | |
1593 | |
1594 if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range; | |
1595 | |
1590 /* clip / convert to intra 16x16 type MVs */ | 1596 /* clip / convert to intra 16x16 type MVs */ |
1591 for(y=0; y<s->mb_height; y++){ | 1597 for(y=0; y<s->mb_height; y++){ |
1592 int x; | 1598 int x; |
1593 int xy= (y+1)* (s->mb_width+2)+1; | 1599 int xy= (y+1)* (s->mb_width+2)+1; |
1594 int i= y*s->mb_width; | 1600 int i= y*s->mb_width; |
1595 for(x=0; x<s->mb_width; x++){ | 1601 for(x=0; x<s->mb_width; x++){ |
1596 if(s->mb_type[i]&MB_TYPE_INTER){ | 1602 if(s->mb_type[i]&MB_TYPE_INTER){ |
1597 if( fcode_tab[s->p_mv_table[xy][0] + MAX_MV] > f_code | 1603 if( s->p_mv_table[xy][0] >=range || s->p_mv_table[xy][0] <-range |
1598 || fcode_tab[s->p_mv_table[xy][0] + MAX_MV] == 0 | 1604 || s->p_mv_table[xy][1] >=range || s->p_mv_table[xy][1] <-range){ |
1599 || fcode_tab[s->p_mv_table[xy][1] + MAX_MV] > f_code | |
1600 || fcode_tab[s->p_mv_table[xy][1] + MAX_MV] == 0 ){ | |
1601 s->mb_type[i] &= ~MB_TYPE_INTER; | 1605 s->mb_type[i] &= ~MB_TYPE_INTER; |
1602 s->mb_type[i] |= MB_TYPE_INTRA; | 1606 s->mb_type[i] |= MB_TYPE_INTRA; |
1603 s->p_mv_table[xy][0] = 0; | 1607 s->p_mv_table[xy][0] = 0; |
1604 s->p_mv_table[xy][1] = 0; | 1608 s->p_mv_table[xy][1] = 0; |
1605 //clip++; | 1609 //clip++; |
1627 for(block=0; block<4; block++){ | 1631 for(block=0; block<4; block++){ |
1628 int off= (block& 1) + (block>>1)*wrap; | 1632 int off= (block& 1) + (block>>1)*wrap; |
1629 int mx= s->motion_val[ xy + off ][0]; | 1633 int mx= s->motion_val[ xy + off ][0]; |
1630 int my= s->motion_val[ xy + off ][1]; | 1634 int my= s->motion_val[ xy + off ][1]; |
1631 | 1635 |
1632 if( fcode_tab[mx + MAX_MV] > f_code | 1636 if( mx >=range || mx <-range |
1633 || fcode_tab[mx + MAX_MV] == 0 | 1637 || my >=range || my <-range){ |
1634 || fcode_tab[my + MAX_MV] > f_code | |
1635 || fcode_tab[my + MAX_MV] == 0 ){ | |
1636 s->mb_type[i] &= ~MB_TYPE_INTER4V; | 1638 s->mb_type[i] &= ~MB_TYPE_INTER4V; |
1637 s->mb_type[i] |= MB_TYPE_INTRA; | 1639 s->mb_type[i] |= MB_TYPE_INTRA; |
1638 } | 1640 } |
1639 } | 1641 } |
1640 } | 1642 } |
1646 } | 1648 } |
1647 | 1649 |
1648 void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type) | 1650 void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type) |
1649 { | 1651 { |
1650 int y; | 1652 int y; |
1651 uint8_t * fcode_tab= s->fcode_tab; | |
1652 | 1653 |
1653 // RAL: 8 in MPEG-1, 16 in MPEG-4 | 1654 // RAL: 8 in MPEG-1, 16 in MPEG-4 |
1654 int range = (((s->codec_id == CODEC_ID_MPEG1VIDEO) ? 8 : 16) << f_code); | 1655 int range = (((s->codec_id == CODEC_ID_MPEG1VIDEO) ? 8 : 16) << f_code); |
1656 | |
1657 if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range; | |
1655 | 1658 |
1656 /* clip / convert to intra 16x16 type MVs */ | 1659 /* clip / convert to intra 16x16 type MVs */ |
1657 for(y=0; y<s->mb_height; y++){ | 1660 for(y=0; y<s->mb_height; y++){ |
1658 int x; | 1661 int x; |
1659 int xy= (y+1)* (s->mb_width+2)+1; | 1662 int xy= (y+1)* (s->mb_width+2)+1; |
1660 int i= y*s->mb_width; | 1663 int i= y*s->mb_width; |
1661 for(x=0; x<s->mb_width; x++) | 1664 for(x=0; x<s->mb_width; x++){ |
1662 { | 1665 if (s->mb_type[i] & type){ // RAL: "type" test added... |
1663 if (s->mb_type[i] & type) // RAL: "type" test added... | 1666 if( mv_table[xy][0] >=range || mv_table[xy][0] <-range |
1664 { | 1667 || mv_table[xy][1] >=range || mv_table[xy][1] <-range){ |
1665 if (fcode_tab[mv_table[xy][0] + MAX_MV] > f_code || fcode_tab[mv_table[xy][0] + MAX_MV] == 0) | 1668 |
1666 { | 1669 if(s->codec_id == CODEC_ID_MPEG1VIDEO && 0){ |
1667 if(mv_table[xy][0]>0) | 1670 }else{ |
1668 mv_table[xy][0]= range-1; | 1671 if (mv_table[xy][0] > range-1) mv_table[xy][0]= range-1; |
1669 else | 1672 else if(mv_table[xy][0] < -range ) mv_table[xy][0]= -range; |
1670 mv_table[xy][0]= -range; | 1673 if (mv_table[xy][1] > range-1) mv_table[xy][1]= range-1; |
1674 else if(mv_table[xy][1] < -range ) mv_table[xy][1]= -range; | |
1671 } | 1675 } |
1672 if (fcode_tab[mv_table[xy][1] + MAX_MV] > f_code || fcode_tab[mv_table[xy][1] + MAX_MV] == 0) | 1676 } |
1673 { | |
1674 if(mv_table[xy][1]>0) | |
1675 mv_table[xy][1]= range-1; | |
1676 else | |
1677 mv_table[xy][1]= -range; | |
1678 } | |
1679 } | 1677 } |
1680 xy++; | 1678 xy++; |
1681 i++; | 1679 i++; |
1682 } | 1680 } |
1683 } | 1681 } |