comparison motion_est.c @ 1968:19c2344e800a libavcodec

support reusing mb types and field select values of the source file, but use motion vectors just as additional predictors minor cleanup segfault fix
author michael
date Sun, 25 Apr 2004 02:09:47 +0000
parents 2fd0c3f311bf
children 38e77ac19836
comparison
equal deleted inserted replaced
1967:2b0fc6b25ab8 1968:19c2344e800a
857 c->src[1][2] = c->src[0][2] + s->uvlinesize; 857 c->src[1][2] = c->src[0][2] + s->uvlinesize;
858 } 858 }
859 } 859 }
860 860
861 static int interlaced_search(MpegEncContext *s, int ref_index, 861 static int interlaced_search(MpegEncContext *s, int ref_index,
862 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, int user_field_select)
863 { 863 {
864 MotionEstContext * const c= &s->me; 864 MotionEstContext * const c= &s->me;
865 const int size=0; 865 const int size=0;
866 const int h=8; 866 const int h=8;
867 int block; 867 int block;
886 int best_field= -1; 886 int best_field= -1;
887 887
888 for(field_select=0; field_select<2; field_select++){ 888 for(field_select=0; field_select<2; field_select++){
889 int dmin, mx_i, my_i; 889 int dmin, mx_i, my_i;
890 int16_t (*mv_table)[2]= mv_tables[block][field_select]; 890 int16_t (*mv_table)[2]= mv_tables[block][field_select];
891
892 if(user_field_select){
893 if(field_select_tables[block][xy] != field_select)
894 continue;
895 }
891 896
892 P_LEFT[0] = mv_table[xy - 1][0]; 897 P_LEFT[0] = mv_table[xy - 1][0];
893 P_LEFT[1] = mv_table[xy - 1][1]; 898 P_LEFT[1] = mv_table[xy - 1][1];
894 if(P_LEFT[0] > (c->xmax<<1)) P_LEFT[0] = (c->xmax<<1); 899 if(P_LEFT[0] > (c->xmax<<1)) P_LEFT[0] = (c->xmax<<1);
895 900
994 if(IS_INTERLACED(mb_type)){ 999 if(IS_INTERLACED(mb_type)){
995 int xy2= xy + s->b8_stride; 1000 int xy2= xy + s->b8_stride;
996 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA; 1001 s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;
997 c->stride<<=1; 1002 c->stride<<=1;
998 c->uvstride<<=1; 1003 c->uvstride<<=1;
999 init_interlaced_ref(s, 2);
1000 1004
1001 assert(s->flags & CODEC_FLAG_INTERLACED_ME); 1005 assert(s->flags & CODEC_FLAG_INTERLACED_ME);
1002 1006
1003 if(USES_LIST(mb_type, 0)){ 1007 if(USES_LIST(mb_type, 0)){
1004 int field_select0= p->ref_index[0][xy ]; 1008 int field_select0= p->ref_index[0][xy ];
1005 int field_select1= p->ref_index[0][xy2]; 1009 int field_select1= p->ref_index[0][xy2];
1006 assert(field_select0==0 ||field_select0==1); 1010 assert(field_select0==0 ||field_select0==1);
1007 assert(field_select1==0 ||field_select1==1); 1011 assert(field_select1==0 ||field_select1==1);
1012 init_interlaced_ref(s, 0);
1013
1008 if(p_type){ 1014 if(p_type){
1009 s->p_field_select_table[0][mb_xy]= field_select0; 1015 s->p_field_select_table[0][mb_xy]= field_select0;
1010 s->p_field_select_table[1][mb_xy]= field_select1; 1016 s->p_field_select_table[1][mb_xy]= field_select1;
1011 *(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ]; 1017 *(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ];
1012 *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2]; 1018 *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2];
1029 if(USES_LIST(mb_type, 1)){ 1035 if(USES_LIST(mb_type, 1)){
1030 int field_select0= p->ref_index[1][xy ]; 1036 int field_select0= p->ref_index[1][xy ];
1031 int field_select1= p->ref_index[1][xy2]; 1037 int field_select1= p->ref_index[1][xy2];
1032 assert(field_select0==0 ||field_select0==1); 1038 assert(field_select0==0 ||field_select0==1);
1033 assert(field_select1==0 ||field_select1==1); 1039 assert(field_select1==0 ||field_select1==1);
1040 init_interlaced_ref(s, 2);
1041
1034 s->b_field_select_table[1][0][mb_xy]= field_select0; 1042 s->b_field_select_table[1][0][mb_xy]= field_select0;
1035 s->b_field_select_table[1][1][mb_xy]= field_select1; 1043 s->b_field_select_table[1][1][mb_xy]= field_select1;
1036 *(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[1][xy ]; 1044 *(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[1][xy ];
1037 *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[1][xy2]; 1045 *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[1][xy2];
1038 if(USES_LIST(mb_type, 0)){ 1046 if(USES_LIST(mb_type, 0)){
1095 void ff_estimate_p_frame_motion(MpegEncContext * s, 1103 void ff_estimate_p_frame_motion(MpegEncContext * s,
1096 int mb_x, int mb_y) 1104 int mb_x, int mb_y)
1097 { 1105 {
1098 MotionEstContext * const c= &s->me; 1106 MotionEstContext * const c= &s->me;
1099 uint8_t *pix, *ppix; 1107 uint8_t *pix, *ppix;
1100 int sum, varc, vard, mx, my, dmin, xx, yy; 1108 int sum, varc, vard, mx, my, dmin;
1101 int P[10][2]; 1109 int P[10][2];
1102 const int shift= 1+s->quarter_sample; 1110 const int shift= 1+s->quarter_sample;
1103 int mb_type=0; 1111 int mb_type=0;
1104 Picture * const pic= &s->current_picture; 1112 Picture * const pic= &s->current_picture;
1105 1113
1115 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; 1123 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
1116 1124
1117 get_limits(s, 16*mb_x, 16*mb_y); 1125 get_limits(s, 16*mb_x, 16*mb_y);
1118 s->me.skip=0; 1126 s->me.skip=0;
1119 1127
1128 /* intra / predictive decision */
1129 pix = c->src[0][0];
1130 sum = s->dsp.pix_sum(pix, s->linesize);
1131 varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
1132
1133 pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
1134 pic->mb_var [s->mb_stride * mb_y + mb_x] = varc;
1135 s->mb_var_sum_temp += varc;
1136
1120 if(s->avctx->me_threshold){ 1137 if(s->avctx->me_threshold){
1121 vard= (check_input_motion(s, mb_x, mb_y, 1)+128)>>8; 1138 vard= (check_input_motion(s, mb_x, mb_y, 1)+128)>>8;
1122 1139
1123 if(vard<s->avctx->me_threshold){ 1140 if(vard<s->avctx->me_threshold){
1124 pix = c->src[0][0];
1125 sum = s->dsp.pix_sum(pix, s->linesize);
1126 varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
1127
1128 pic->mb_var [s->mb_stride * mb_y + mb_x] = varc;
1129 pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard; 1141 pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard;
1130 pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
1131 s->mb_var_sum_temp += varc;
1132 s->mc_mb_var_sum_temp += vard; 1142 s->mc_mb_var_sum_temp += vard;
1133 if (vard <= 64 || vard < varc) { //FIXME 1143 if (vard <= 64 || vard < varc) { //FIXME
1134 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); 1144 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
1135 }else{ 1145 }else{
1136 s->scene_change_score+= s->qscale; 1146 s->scene_change_score+= s->qscale;
1137 } 1147 }
1138 return; 1148 return;
1139 } 1149 }
1150 if(vard<s->avctx->mb_threshold)
1151 mb_type= s->mb_type[mb_x + mb_y*s->mb_stride];
1140 } 1152 }
1141 1153
1142 switch(s->me_method) { 1154 switch(s->me_method) {
1143 case ME_ZERO: 1155 case ME_ZERO:
1144 default: 1156 default:
1203 dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift); 1215 dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift);
1204 1216
1205 break; 1217 break;
1206 } 1218 }
1207 1219
1208 /* intra / predictive decision */
1209 xx = mb_x * 16;
1210 yy = mb_y * 16;
1211
1212 pix = c->src[0][0];
1213 /* At this point (mx,my) are full-pell and the relative displacement */ 1220 /* At this point (mx,my) are full-pell and the relative displacement */
1214 ppix = c->ref[0][0] + (my * s->linesize) + mx; 1221 ppix = c->ref[0][0] + (my * s->linesize) + mx;
1215 1222
1216 sum = s->dsp.pix_sum(pix, s->linesize);
1217
1218 varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;
1219 vard = (s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16)+128)>>8; 1223 vard = (s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16)+128)>>8;
1220 1224
1221 //printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);
1222 pic->mb_var [s->mb_stride * mb_y + mb_x] = varc;
1223 pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard; 1225 pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard;
1224 pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
1225 // pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; 1226 // pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;
1226 s->mb_var_sum_temp += varc;
1227 s->mc_mb_var_sum_temp += vard; 1227 s->mc_mb_var_sum_temp += vard;
1228 //printf("E%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);
1229 1228
1230 #if 0 1229 #if 0
1231 printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n", 1230 printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n",
1232 varc, s->avg_mb_var, sum, vard, mx - xx, my - yy); 1231 varc, s->avg_mb_var, sum, vard, mx - xx, my - yy);
1233 #endif 1232 #endif
1234 if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ 1233 if(mb_type){
1234 if (vard <= 64 || vard < varc)
1235 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
1236 else
1237 s->scene_change_score+= s->qscale;
1238
1239 if(mb_type == CANDIDATE_MB_TYPE_INTER){
1240 s->me.sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
1241 set_p_mv_tables(s, mx, my, 1);
1242 }else{
1243 mx <<=shift;
1244 my <<=shift;
1245 }
1246 if(mb_type == CANDIDATE_MB_TYPE_INTER4V){
1247 h263_mv4_search(s, mx, my, shift);
1248
1249 set_p_mv_tables(s, mx, my, 0);
1250 }
1251 if(mb_type == CANDIDATE_MB_TYPE_INTER_I){
1252 interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 1);
1253 }
1254 }else if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){
1235 if (vard <= 64 || vard < varc) 1255 if (vard <= 64 || vard < varc)
1236 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); 1256 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
1237 else 1257 else
1238 s->scene_change_score+= s->qscale; 1258 s->scene_change_score+= s->qscale;
1239 1259
1257 set_p_mv_tables(s, mx, my, 0); 1277 set_p_mv_tables(s, mx, my, 0);
1258 }else 1278 }else
1259 set_p_mv_tables(s, mx, my, 1); 1279 set_p_mv_tables(s, mx, my, 1);
1260 if((s->flags&CODEC_FLAG_INTERLACED_ME) 1280 if((s->flags&CODEC_FLAG_INTERLACED_ME)
1261 && !s->me.skip){ //FIXME varc/d checks 1281 && !s->me.skip){ //FIXME varc/d checks
1262 if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my) < INT_MAX) 1282 if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX)
1263 mb_type |= CANDIDATE_MB_TYPE_INTER_I; 1283 mb_type |= CANDIDATE_MB_TYPE_INTER_I;
1264 } 1284 }
1265 }else{ 1285 }else{
1266 int intra_score, i; 1286 int intra_score, i;
1267 mb_type= CANDIDATE_MB_TYPE_INTER; 1287 mb_type= CANDIDATE_MB_TYPE_INTER;
1278 dmin=dmin4; 1298 dmin=dmin4;
1279 } 1299 }
1280 } 1300 }
1281 if((s->flags&CODEC_FLAG_INTERLACED_ME) 1301 if((s->flags&CODEC_FLAG_INTERLACED_ME)
1282 && !s->me.skip){ //FIXME varc/d checks 1302 && !s->me.skip){ //FIXME varc/d checks
1283 int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my); 1303 int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0);
1284 if(dmin_i < dmin){ 1304 if(dmin_i < dmin){
1285 mb_type = CANDIDATE_MB_TYPE_INTER_I; 1305 mb_type = CANDIDATE_MB_TYPE_INTER_I;
1286 dmin= dmin_i; 1306 dmin= dmin_i;
1287 } 1307 }
1288 } 1308 }
1688 int mb_x, int mb_y) 1708 int mb_x, int mb_y)
1689 { 1709 {
1690 const int penalty_factor= s->me.mb_penalty_factor; 1710 const int penalty_factor= s->me.mb_penalty_factor;
1691 int fmin, bmin, dmin, fbmin, bimin, fimin; 1711 int fmin, bmin, dmin, fbmin, bimin, fimin;
1692 int type=0; 1712 int type=0;
1713 const int xy = mb_y*s->mb_stride + mb_x;
1693 init_ref(s, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2); 1714 init_ref(s, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2);
1715
1694 1716
1695 s->me.skip=0; 1717 s->me.skip=0;
1696 if(s->avctx->me_threshold){ 1718 if(s->avctx->me_threshold){
1697 int vard= (check_input_motion(s, mb_x, mb_y, 0)+128)>>8; 1719 int vard= (check_input_motion(s, mb_x, mb_y, 0)+128)>>8;
1698 1720
1711 }else{ 1733 }else{
1712 s->scene_change_score+= s->qscale; 1734 s->scene_change_score+= s->qscale;
1713 }*/ 1735 }*/
1714 return; 1736 return;
1715 } 1737 }
1738 if(vard<s->avctx->mb_threshold){
1739 type= s->mb_type[mb_y*s->mb_stride + mb_x];
1740 if(type == CANDIDATE_MB_TYPE_DIRECT){
1741 direct_search(s, mb_x, mb_y);
1742 }
1743 if(type == CANDIDATE_MB_TYPE_FORWARD || type == CANDIDATE_MB_TYPE_BIDIR){
1744 s->me.skip=0;
1745 ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code);
1746 }
1747 if(type == CANDIDATE_MB_TYPE_BACKWARD || type == CANDIDATE_MB_TYPE_BIDIR){
1748 s->me.skip=0;
1749 ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code);
1750 }
1751 if(type == CANDIDATE_MB_TYPE_FORWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){
1752 s->me.skip=0;
1753 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
1754 interlaced_search(s, 0,
1755 s->b_field_mv_table[0], s->b_field_select_table[0],
1756 s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 1);
1757 }
1758 if(type == CANDIDATE_MB_TYPE_BACKWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){
1759 s->me.skip=0;
1760 s->me.current_mv_penalty= s->me.mv_penalty[s->b_code] + MAX_MV;
1761 interlaced_search(s, 2,
1762 s->b_field_mv_table[1], s->b_field_select_table[1],
1763 s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 1);
1764 }
1765 return;
1766 }
1716 } 1767 }
1717 1768
1718 if (s->codec_id == CODEC_ID_MPEG4) 1769 if (s->codec_id == CODEC_ID_MPEG4)
1719 dmin= direct_search(s, mb_x, mb_y); 1770 dmin= direct_search(s, mb_x, mb_y);
1720 else 1771 else
1730 s->me.skip=0; 1781 s->me.skip=0;
1731 fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor; 1782 fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor;
1732 //printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin); 1783 //printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin);
1733 1784
1734 if(s->flags & CODEC_FLAG_INTERLACED_ME){ 1785 if(s->flags & CODEC_FLAG_INTERLACED_ME){
1735 const int xy = mb_y*s->mb_stride + mb_x;
1736
1737 //FIXME mb type penalty 1786 //FIXME mb type penalty
1738 s->me.skip=0; 1787 s->me.skip=0;
1739 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; 1788 s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
1740 fimin= interlaced_search(s, 0, 1789 fimin= interlaced_search(s, 0,
1741 s->b_field_mv_table[0], s->b_field_select_table[0], 1790 s->b_field_mv_table[0], s->b_field_select_table[0],
1742 s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); 1791 s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0);
1743 s->me.current_mv_penalty= s->me.mv_penalty[s->b_code] + MAX_MV; 1792 s->me.current_mv_penalty= s->me.mv_penalty[s->b_code] + MAX_MV;
1744 bimin= interlaced_search(s, 2, 1793 bimin= interlaced_search(s, 2,
1745 s->b_field_mv_table[1], s->b_field_select_table[1], 1794 s->b_field_mv_table[1], s->b_field_select_table[1],
1746 s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1]); 1795 s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0);
1747 }else 1796 }else
1748 fimin= bimin= INT_MAX; 1797 fimin= bimin= INT_MAX;
1749 1798
1750 { 1799 {
1751 int score= fmin; 1800 int score= fmin;