comparison motion_est.c @ 1955:5dafb10e0252 libavcodec

reuse motion vectors/mb types/field select values of the source video, if the SSE for a macroblock which is predicted with these values is below me_threshold currently works only with mpeg1/2 source or some luck may need -sync 0 as otherwise framedrops could lead to extreemly long b frame sequences
author michael
date Fri, 23 Apr 2004 19:06:30 +0000
parents a3c60fa850dc
children 1d5abf80fa41
comparison
equal deleted inserted replaced
1954:e943363932d9 1955:5dafb10e0252
971 default: 971 default:
972 return dmin_sum+ 11*c->mb_penalty_factor; 972 return dmin_sum+ 11*c->mb_penalty_factor;
973 } 973 }
974 } 974 }
975 975
976 static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int p_type){
977 MotionEstContext * const c= &s->me;
978 Picture *p= s->current_picture_ptr;
979 int mb_xy= mb_x + mb_y*s->mb_stride;
980 int xy= 2*mb_x + 2*mb_y*s->b8_stride;
981 int mb_type= s->current_picture.mb_type[mb_xy];
982 int flags= c->flags;
983 int shift= (flags&FLAG_QPEL) + 1;
984 int mask= (1<<shift)-1;
985 int x, y;
986 int d=0;
987 me_cmp_func cmpf= s->dsp.sse[0];
988 me_cmp_func chroma_cmpf= s->dsp.sse[1];
989
990 assert(p_type==0 || !USES_LIST(mb_type, 1));
991 assert(IS_INTRA(mb_type) || USES_LIST(mb_type,0) || USES_LIST(mb_type,1));
992
993 if(IS_INTERLACED(mb_type)){
994 int xy2= xy + s->b8_stride;
995 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;
996 c->stride<<=1;
997 c->uvstride<<=1;
998 c->ref[1][0] = c->ref[0][0] + s->linesize;
999 c->ref[3][0] = c->ref[2][0] + s->linesize;
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)){
1010 int field_select0= p->ref_index[0][xy ];
1011 int field_select1= p->ref_index[0][xy2];
1012 assert(field_select0==0 ||field_select0==1);
1013 assert(field_select1==0 ||field_select1==1);
1014 if(p_type){
1015 s->p_field_select_table[0][mb_xy]= field_select0;
1016 s->p_field_select_table[1][mb_xy]= field_select1;
1017 *(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ];
1018 *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2];
1019 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER_I;
1020 }else{
1021 s->b_field_select_table[0][0][mb_xy]= field_select0;
1022 s->b_field_select_table[0][1][mb_xy]= field_select1;
1023 *(uint32_t*)s->b_field_mv_table[0][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ];
1024 *(uint32_t*)s->b_field_mv_table[0][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2];
1025 s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_FORWARD_I;
1026 }
1027
1028 x= p->motion_val[0][xy ][0];
1029 y= p->motion_val[0][xy ][1];
1030 d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0, 0, cmpf, chroma_cmpf, flags);
1031 x= p->motion_val[0][xy2][0];
1032 y= p->motion_val[0][xy2][1];
1033 d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1, 1, cmpf, chroma_cmpf, flags);
1034 }
1035 if(USES_LIST(mb_type, 1)){
1036 int field_select0= p->ref_index[1][xy ];
1037 int field_select1= p->ref_index[1][xy2];
1038 assert(field_select0==0 ||field_select0==1);
1039 assert(field_select1==0 ||field_select1==1);
1040 s->b_field_select_table[1][0][mb_xy]= field_select0;
1041 s->b_field_select_table[1][1][mb_xy]= field_select1;
1042 *(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[1][xy ];
1043 *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[1][xy2];
1044 if(USES_LIST(mb_type, 0)){
1045 s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BIDIR_I;
1046 }else{
1047 s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BACKWARD_I;
1048 }
1049
1050 x= p->motion_val[1][xy ][0];
1051 y= p->motion_val[1][xy ][1];
1052 d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0+2, 0, cmpf, chroma_cmpf, flags);
1053 x= p->motion_val[1][xy2][0];
1054 y= p->motion_val[1][xy2][1];
1055 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
1057 }
1058 c->stride>>=1;
1059 c->uvstride>>=1;
1060 }else{
1061 if(USES_LIST(mb_type, 0)){
1062 if(p_type){
1063 *(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;
1065 }else if(USES_LIST(mb_type, 1)){
1066 *(uint32_t*)s->b_bidir_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];
1067 *(uint32_t*)s->b_bidir_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy];
1068 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BIDIR;
1069 }else{
1070 *(uint32_t*)s->b_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy];
1071 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_FORWARD;
1072 }
1073 x= p->motion_val[0][xy][0];
1074 y= p->motion_val[0][xy][1];
1075 d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 0, 0, cmpf, chroma_cmpf, flags);
1076 }else if(USES_LIST(mb_type, 1)){
1077 *(uint32_t*)s->b_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy];
1078 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BACKWARD;
1079
1080 x= p->motion_val[1][xy][0];
1081 y= p->motion_val[1][xy][1];
1082 d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 2, 0, cmpf, chroma_cmpf, flags);
1083 }else
1084 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;
1085 }
1086 return d;
1087 }
1088
976 void ff_estimate_p_frame_motion(MpegEncContext * s, 1089 void ff_estimate_p_frame_motion(MpegEncContext * s,
977 int mb_x, int mb_y) 1090 int mb_x, int mb_y)
978 { 1091 {
979 MotionEstContext * const c= &s->me; 1092 MotionEstContext * const c= &s->me;
980 uint8_t *pix, *ppix; 1093 uint8_t *pix, *ppix;
996 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp); 1109 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
997 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; 1110 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
998 1111
999 get_limits(s, 16*mb_x, 16*mb_y); 1112 get_limits(s, 16*mb_x, 16*mb_y);
1000 s->me.skip=0; 1113 s->me.skip=0;
1114
1115 if(s->avctx->me_threshold){
1116 vard= (check_input_motion(s, mb_x, mb_y, 1)+128)>>8;
1117
1118 if(vard<s->avctx->me_threshold){
1119 pix = c->src[0][0];
1120 sum = s->dsp.pix_sum(pix, s->linesize);
1121 varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
1122
1123 pic->mb_var [s->mb_stride * mb_y + mb_x] = varc;
1124 pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard;
1125 pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
1126 s->mb_var_sum_temp += varc;
1127 s->mc_mb_var_sum_temp += vard;
1128 if (vard <= 64 || vard < varc) { //FIXME
1129 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
1130 }else{
1131 s->scene_change_score+= s->qscale;
1132 }
1133 return;
1134 }
1135 }
1001 1136
1002 switch(s->me_method) { 1137 switch(s->me_method) {
1003 case ME_ZERO: 1138 case ME_ZERO:
1004 default: 1139 default:
1005 no_motion_search(s, &mx, &my); 1140 no_motion_search(s, &mx, &my);
1553 int type=0; 1688 int type=0;
1554 init_ref(s, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2); 1689 init_ref(s, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2);
1555 init_mc(s, 0, s->me.flags); 1690 init_mc(s, 0, s->me.flags);
1556 1691
1557 s->me.skip=0; 1692 s->me.skip=0;
1693 if(s->avctx->me_threshold){
1694 int vard= (check_input_motion(s, mb_x, mb_y, 0)+128)>>8;
1695
1696 if(vard<s->avctx->me_threshold){
1697 // pix = c->src[0][0];
1698 // sum = s->dsp.pix_sum(pix, s->linesize);
1699 // varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
1700
1701 // pic->mb_var [s->mb_stride * mb_y + mb_x] = varc;
1702 s->current_picture.mc_mb_var[s->mb_stride * mb_y + mb_x] = vard;
1703 /* pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
1704 s->mb_var_sum_temp += varc;*/
1705 s->mc_mb_var_sum_temp += vard;
1706 /* if (vard <= 64 || vard < varc) {
1707 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
1708 }else{
1709 s->scene_change_score+= s->qscale;
1710 }*/
1711 return;
1712 }
1713 }
1714
1558 if (s->codec_id == CODEC_ID_MPEG4) 1715 if (s->codec_id == CODEC_ID_MPEG4)
1559 dmin= direct_search(s, mb_x, mb_y); 1716 dmin= direct_search(s, mb_x, mb_y);
1560 else 1717 else
1561 dmin= INT_MAX; 1718 dmin= INT_MAX;
1562 //FIXME penalty stuff for non mpeg4 1719 //FIXME penalty stuff for non mpeg4