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