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