comparison motion_est.c @ 1962:1d5abf80fa41 libavcodec

minor motion estimation cleanup 4mv motion vector passthrough
author michael
date Sat, 24 Apr 2004 03:36:37 +0000
parents 5dafb10e0252
children 2fd0c3f311bf
comparison
equal deleted inserted replaced
1961:603d4a0e974c 1962:1d5abf80fa41
98 98
99 static int get_flags(MpegEncContext *s, int direct, int chroma){ 99 static int get_flags(MpegEncContext *s, int direct, int chroma){
100 return ((s->flags&CODEC_FLAG_QPEL) ? FLAG_QPEL : 0) 100 return ((s->flags&CODEC_FLAG_QPEL) ? FLAG_QPEL : 0)
101 + (direct ? FLAG_DIRECT : 0) 101 + (direct ? FLAG_DIRECT : 0)
102 + (chroma ? FLAG_CHROMA : 0); 102 + (chroma ? FLAG_CHROMA : 0);
103 }
104
105 static inline void init_mc(MpegEncContext *s, int size, int flags){
106 MotionEstContext * const c= &s->me;
107
108 /*FIXME s->no_rounding b_type*/
109 if(flags & FLAG_CHROMA){
110 if(s->no_rounding) c->chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1];
111 else c->chroma_hpel_put= &s->dsp.put_pixels_tab[size+1];
112 }
113
114 if(flags & FLAG_QPEL){
115 c->qpel_avg= &s->dsp.avg_qpel_pixels_tab[size];
116 if(s->no_rounding) c->qpel_put= &s->dsp.put_no_rnd_qpel_pixels_tab[size];
117 else c->qpel_put= &s->dsp.put_qpel_pixels_tab[size];
118 }else{
119 c->hpel_avg= &s->dsp.avg_pixels_tab[size];
120 if(s->no_rounding) c->hpel_put= &s->dsp.put_no_rnd_pixels_tab[size];
121 else c->hpel_put= &s->dsp.put_pixels_tab[size];
122 }
123 c->temp= c->scratchpad;
124 } 103 }
125 104
126 static always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby, 105 static always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
127 const int size, const int h, int ref_index, int src_index, 106 const int size, const int h, int ref_index, int src_index,
128 me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ 107 me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
259 return (s->qscale*s->qscale*185 + 64)>>7; 238 return (s->qscale*s->qscale*185 + 64)>>7;
260 } 239 }
261 } 240 }
262 241
263 void ff_init_me(MpegEncContext *s){ 242 void ff_init_me(MpegEncContext *s){
243 MotionEstContext * const c= &s->me;
244
264 ff_set_cmp(&s->dsp, s->dsp.me_pre_cmp, s->avctx->me_pre_cmp); 245 ff_set_cmp(&s->dsp, s->dsp.me_pre_cmp, s->avctx->me_pre_cmp);
265 ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp); 246 ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp);
266 ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp); 247 ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp);
267 ff_set_cmp(&s->dsp, s->dsp.mb_cmp, s->avctx->mb_cmp); 248 ff_set_cmp(&s->dsp, s->dsp.mb_cmp, s->avctx->mb_cmp);
268 249
269 s->me.flags = get_flags(s, 0, s->avctx->me_cmp &FF_CMP_CHROMA); 250 s->me.flags = get_flags(s, 0, s->avctx->me_cmp &FF_CMP_CHROMA);
270 s->me.sub_flags= get_flags(s, 0, s->avctx->me_sub_cmp&FF_CMP_CHROMA); 251 s->me.sub_flags= get_flags(s, 0, s->avctx->me_sub_cmp&FF_CMP_CHROMA);
271 s->me.mb_flags = get_flags(s, 0, s->avctx->mb_cmp &FF_CMP_CHROMA); 252 s->me.mb_flags = get_flags(s, 0, s->avctx->mb_cmp &FF_CMP_CHROMA);
272 253
254 /*FIXME s->no_rounding b_type*/
273 if(s->flags&CODEC_FLAG_QPEL){ 255 if(s->flags&CODEC_FLAG_QPEL){
274 s->me.sub_motion_search= qpel_motion_search; 256 s->me.sub_motion_search= qpel_motion_search;
257 c->qpel_avg= s->dsp.avg_qpel_pixels_tab;
258 if(s->no_rounding) c->qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab;
259 else c->qpel_put= s->dsp.put_qpel_pixels_tab;
275 }else{ 260 }else{
276 if(s->avctx->me_sub_cmp&FF_CMP_CHROMA) 261 if(s->avctx->me_sub_cmp&FF_CMP_CHROMA)
277 s->me.sub_motion_search= hpel_motion_search; 262 s->me.sub_motion_search= hpel_motion_search;
278 else if( s->avctx->me_sub_cmp == FF_CMP_SAD 263 else if( s->avctx->me_sub_cmp == FF_CMP_SAD
279 && s->avctx-> me_cmp == FF_CMP_SAD 264 && s->avctx-> me_cmp == FF_CMP_SAD
280 && s->avctx-> mb_cmp == FF_CMP_SAD) 265 && s->avctx-> mb_cmp == FF_CMP_SAD)
281 s->me.sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles 266 s->me.sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles
282 else 267 else
283 s->me.sub_motion_search= hpel_motion_search; 268 s->me.sub_motion_search= hpel_motion_search;
269 c->hpel_avg= s->dsp.avg_pixels_tab;
270 if(s->no_rounding) c->hpel_put= s->dsp.put_no_rnd_pixels_tab;
271 else c->hpel_put= s->dsp.put_pixels_tab;
284 } 272 }
285 if(s->linesize){ 273 if(s->linesize){
286 s->me.stride = s->linesize; 274 s->me.stride = s->linesize;
287 s->me.uvstride= s->uvlinesize; 275 s->me.uvstride= s->uvlinesize;
288 }else{ 276 }else{
289 s->me.stride = 16*s->mb_width + 32; 277 s->me.stride = 16*s->mb_width + 32;
290 s->me.uvstride= 8*s->mb_width + 16; 278 s->me.uvstride= 8*s->mb_width + 16;
291 } 279 }
280
281 c->temp= c->scratchpad;
292 } 282 }
293 283
294 #if 0 284 #if 0
295 static int pix_dev(uint8_t * pix, int line_size, int mean) 285 static int pix_dev(uint8_t * pix, int line_size, int mean)
296 { 286 {
704 s->me.xmax = - x + s->mb_width *16 - 16; 694 s->me.xmax = - x + s->mb_width *16 - 16;
705 s->me.ymax = - y + s->mb_height*16 - 16; 695 s->me.ymax = - y + s->mb_height*16 - 16;
706 } 696 }
707 } 697 }
708 698
699 static inline void init_mv4_ref(MpegEncContext *s){
700 MotionEstContext * const c= &s->me;
701 const int stride= s->linesize;
702
703 c->ref[1][0] = c->ref[0][0] + 8;
704 c->ref[2][0] = c->ref[0][0] + 8*stride;
705 c->ref[3][0] = c->ref[2][0] + 8;
706 c->src[1][0] = c->src[0][0] + 8;
707 c->src[2][0] = c->src[0][0] + 8*stride;
708 c->src[3][0] = c->src[2][0] + 8;
709 }
710
709 static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) 711 static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
710 { 712 {
711 MotionEstContext * const c= &s->me; 713 MotionEstContext * const c= &s->me;
712 const int size= 1; 714 const int size= 1;
713 const int h=8; 715 const int h=8;
717 int same=1; 719 int same=1;
718 const int stride= s->linesize; 720 const int stride= s->linesize;
719 const int uvstride= s->uvlinesize; 721 const int uvstride= s->uvlinesize;
720 uint8_t *mv_penalty= s->me.current_mv_penalty; 722 uint8_t *mv_penalty= s->me.current_mv_penalty;
721 723
722 c->ref[1][0] = c->ref[0][0] + 8; 724 init_mv4_ref(s);
723 c->ref[2][0] = c->ref[0][0] + 8*stride;
724 c->ref[3][0] = c->ref[2][0] + 8;
725 c->src[1][0] = c->src[0][0] + 8;
726 c->src[2][0] = c->src[0][0] + 8*stride;
727 c->src[3][0] = c->src[2][0] + 8;
728 init_mc(s, size, c->flags);
729 725
730 for(block=0; block<4; block++){ 726 for(block=0; block<4; block++){
731 int mx4, my4; 727 int mx4, my4;
732 int pred_x4, pred_y4; 728 int pred_x4, pred_y4;
733 int dmin4; 729 int dmin4;
847 default: 843 default:
848 return dmin_sum+ 11*s->me.mb_penalty_factor; 844 return dmin_sum+ 11*s->me.mb_penalty_factor;
849 } 845 }
850 } 846 }
851 847
848 static inline void init_interlaced_ref(MpegEncContext *s, int ref_index){
849 MotionEstContext * const c= &s->me;
850
851 c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->linesize;
852 c->src[1][0] = c->src[0][0] + s->linesize;
853 if(c->flags & FLAG_CHROMA){
854 c->ref[1+ref_index][1] = c->ref[0+ref_index][1] + s->uvlinesize;
855 c->ref[1+ref_index][2] = c->ref[0+ref_index][2] + s->uvlinesize;
856 c->src[1][1] = c->src[0][1] + s->uvlinesize;
857 c->src[1][2] = c->src[0][2] + s->uvlinesize;
858 }
859 }
860
852 static int interlaced_search(MpegEncContext *s, int ref_index, 861 static int interlaced_search(MpegEncContext *s, int ref_index,
853 int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my) 862 int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my)
854 { 863 {
855 MotionEstContext * const c= &s->me; 864 MotionEstContext * const c= &s->me;
856 const int size=0; 865 const int size=0;
867 876
868 c->ymin>>=1; 877 c->ymin>>=1;
869 c->ymax>>=1; 878 c->ymax>>=1;
870 c->stride<<=1; 879 c->stride<<=1;
871 c->uvstride<<=1; 880 c->uvstride<<=1;
872 c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->linesize; 881 init_interlaced_ref(s, ref_index);
873 c->src[1][0] = c->src[0][0] + s->linesize;
874 if(c->flags & FLAG_CHROMA){
875 c->ref[1+ref_index][1] = c->ref[0+ref_index][1] + s->uvlinesize;
876 c->ref[1+ref_index][2] = c->ref[0+ref_index][2] + s->uvlinesize;
877 c->src[1][1] = c->src[0][1] + s->uvlinesize;
878 c->src[1][2] = c->src[0][2] + s->uvlinesize;
879 }
880 init_mc(s, size, c->flags);
881 882
882 for(block=0; block<2; block++){ 883 for(block=0; block<2; block++){
883 int field_select; 884 int field_select;
884 int best_dmin= INT_MAX; 885 int best_dmin= INT_MAX;
885 int best_field= -1; 886 int best_field= -1;
980 int xy= 2*mb_x + 2*mb_y*s->b8_stride; 981 int xy= 2*mb_x + 2*mb_y*s->b8_stride;
981 int mb_type= s->current_picture.mb_type[mb_xy]; 982 int mb_type= s->current_picture.mb_type[mb_xy];
982 int flags= c->flags; 983 int flags= c->flags;
983 int shift= (flags&FLAG_QPEL) + 1; 984 int shift= (flags&FLAG_QPEL) + 1;
984 int mask= (1<<shift)-1; 985 int mask= (1<<shift)-1;
985 int x, y; 986 int x, y, i;
986 int d=0; 987 int d=0;
987 me_cmp_func cmpf= s->dsp.sse[0]; 988 me_cmp_func cmpf= s->dsp.sse[0];
988 me_cmp_func chroma_cmpf= s->dsp.sse[1]; 989 me_cmp_func chroma_cmpf= s->dsp.sse[1];
989 990
990 assert(p_type==0 || !USES_LIST(mb_type, 1)); 991 assert(p_type==0 || !USES_LIST(mb_type, 1));
993 if(IS_INTERLACED(mb_type)){ 994 if(IS_INTERLACED(mb_type)){
994 int xy2= xy + s->b8_stride; 995 int xy2= xy + s->b8_stride;
995 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA; 996 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;
996 c->stride<<=1; 997 c->stride<<=1;
997 c->uvstride<<=1; 998 c->uvstride<<=1;
998 c->ref[1][0] = c->ref[0][0] + s->linesize; 999 init_interlaced_ref(s, 2);
999 c->ref[3][0] = c->ref[2][0] + s->linesize; 1000
1000 c->src[1][0] = c->src[0][0] + s->linesize;
1001 if(c->flags & FLAG_CHROMA){
1002 c->ref[1][1] = c->ref[0][1] + s->uvlinesize;
1003 c->ref[1][2] = c->ref[0][2] + s->uvlinesize;
1004 c->ref[3][1] = c->ref[2][1] + s->uvlinesize;
1005 c->ref[3][2] = c->ref[2][2] + s->uvlinesize;
1006 c->src[1][1] = c->src[0][1] + s->uvlinesize;
1007 c->src[1][2] = c->src[0][2] + s->uvlinesize;
1008 }
1009 if(USES_LIST(mb_type, 0)){ 1001 if(USES_LIST(mb_type, 0)){
1010 int field_select0= p->ref_index[0][xy ]; 1002 int field_select0= p->ref_index[0][xy ];
1011 int field_select1= p->ref_index[0][xy2]; 1003 int field_select1= p->ref_index[0][xy2];
1012 assert(field_select0==0 ||field_select0==1); 1004 assert(field_select0==0 ||field_select0==1);
1013 assert(field_select1==0 ||field_select1==1); 1005 assert(field_select1==0 ||field_select1==1);
1055 d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1+2, 1, cmpf, chroma_cmpf, flags); 1047 d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1+2, 1, cmpf, chroma_cmpf, flags);
1056 //FIXME bidir scores 1048 //FIXME bidir scores
1057 } 1049 }
1058 c->stride>>=1; 1050 c->stride>>=1;
1059 c->uvstride>>=1; 1051 c->uvstride>>=1;
1052 }else if(IS_8X8(mb_type)){
1053 cmpf= s->dsp.sse[1];
1054 chroma_cmpf= s->dsp.sse[1];
1055 init_mv4_ref(s);
1056 for(i=0; i<4; i++){
1057 xy= s->block_index[i];
1058 x= p->motion_val[0][xy][0];
1059 y= p->motion_val[0][xy][1];
1060 d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 1, 8, i, i, cmpf, chroma_cmpf, flags);
1061 }
1062 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER4V;
1060 }else{ 1063 }else{
1061 if(USES_LIST(mb_type, 0)){ 1064 if(USES_LIST(mb_type, 0)){
1062 if(p_type){ 1065 if(p_type){
1063 *(uint32_t*)s->p_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy]; 1066 *(uint32_t*)s->p_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];
1064 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER; 1067 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER;
1096 const int shift= 1+s->quarter_sample; 1099 const int shift= 1+s->quarter_sample;
1097 int mb_type=0; 1100 int mb_type=0;
1098 Picture * const pic= &s->current_picture; 1101 Picture * const pic= &s->current_picture;
1099 1102
1100 init_ref(s, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0); 1103 init_ref(s, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);
1101 init_mc(s, 0, c->flags);
1102 1104
1103 assert(s->quarter_sample==0 || s->quarter_sample==1); 1105 assert(s->quarter_sample==0 || s->quarter_sample==1);
1104 assert(s->linesize == s->me.stride); 1106 assert(s->linesize == s->me.stride);
1105 assert(s->uvlinesize == s->me.uvstride); 1107 assert(s->uvlinesize == s->me.uvstride);
1106 1108
1350 int mx, my, dmin; 1352 int mx, my, dmin;
1351 int P[10][2]; 1353 int P[10][2];
1352 const int shift= 1+s->quarter_sample; 1354 const int shift= 1+s->quarter_sample;
1353 const int xy= mb_x + mb_y*s->mb_stride; 1355 const int xy= mb_x + mb_y*s->mb_stride;
1354 init_ref(s, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0); 1356 init_ref(s, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0);
1355 init_mc(s, 0, c->flags);
1356 1357
1357 assert(s->quarter_sample==0 || s->quarter_sample==1); 1358 assert(s->quarter_sample==0 || s->quarter_sample==1);
1358 1359
1359 s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp); 1360 s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp);
1360 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; 1361 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
1685 { 1686 {
1686 const int penalty_factor= s->me.mb_penalty_factor; 1687 const int penalty_factor= s->me.mb_penalty_factor;
1687 int fmin, bmin, dmin, fbmin, bimin, fimin; 1688 int fmin, bmin, dmin, fbmin, bimin, fimin;
1688 int type=0; 1689 int type=0;
1689 init_ref(s, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2); 1690 init_ref(s, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2);
1690 init_mc(s, 0, s->me.flags);
1691 1691
1692 s->me.skip=0; 1692 s->me.skip=0;
1693 if(s->avctx->me_threshold){ 1693 if(s->avctx->me_threshold){
1694 int vard= (check_input_motion(s, mb_x, mb_y, 0)+128)>>8; 1694 int vard= (check_input_motion(s, mb_x, mb_y, 0)+128)>>8;
1695 1695