Mercurial > libavcodec.hg
comparison motion_est.c @ 948:371bc36a9c5c libavcodec
shape adaptive diamonds for EPZS
user specified amount of MV predictors from the last frame
b frame MV predictor scaling fixed
author | michaelni |
---|---|
date | Wed, 01 Jan 2003 14:36:20 +0000 |
parents | caa77cd960c0 |
children | d4d714493faa |
comparison
equal
deleted
inserted
replaced
947:9be53be2d1a9 | 948:371bc36a9c5c |
---|---|
29 //#undef NDEBUG | 29 //#undef NDEBUG |
30 //#include <assert.h> | 30 //#include <assert.h> |
31 | 31 |
32 #define SQ(a) ((a)*(a)) | 32 #define SQ(a) ((a)*(a)) |
33 | 33 |
34 #define P_LAST P[0] | |
35 #define P_LEFT P[1] | 34 #define P_LEFT P[1] |
36 #define P_TOP P[2] | 35 #define P_TOP P[2] |
37 #define P_TOPRIGHT P[3] | 36 #define P_TOPRIGHT P[3] |
38 #define P_MEDIAN P[4] | 37 #define P_MEDIAN P[4] |
39 #define P_LAST_LEFT P[5] | |
40 #define P_LAST_RIGHT P[6] | |
41 #define P_LAST_TOP P[7] | |
42 #define P_LAST_BOTTOM P[8] | |
43 #define P_MV1 P[9] | 38 #define P_MV1 P[9] |
44 | 39 |
45 static inline int sad_hpel_motion_search(MpegEncContext * s, | 40 static inline int sad_hpel_motion_search(MpegEncContext * s, |
46 int *mx_ptr, int *my_ptr, int dmin, | 41 int *mx_ptr, int *my_ptr, int dmin, |
47 int xmin, int ymin, int xmax, int ymax, | 42 int xmin, int ymin, int xmax, int ymax, |
56 memset(s->me.map, 0, sizeof(uint32_t)*ME_MAP_SIZE); | 51 memset(s->me.map, 0, sizeof(uint32_t)*ME_MAP_SIZE); |
57 } | 52 } |
58 return s->me.map_generation; | 53 return s->me.map_generation; |
59 } | 54 } |
60 | 55 |
61 | 56 /* shape adaptive search stuff */ |
57 typedef struct Minima{ | |
58 int height; | |
59 int x, y; | |
60 int checked; | |
61 }Minima; | |
62 | |
63 static int minima_cmp(const void *a, const void *b){ | |
64 Minima *da = (Minima *) a; | |
65 Minima *db = (Minima *) b; | |
66 | |
67 return da->height - db->height; | |
68 } | |
62 | 69 |
63 /* SIMPLE */ | 70 /* SIMPLE */ |
64 #define RENAME(a) simple_ ## a | 71 #define RENAME(a) simple_ ## a |
65 | 72 |
66 #define CMP(d, x, y, size)\ | 73 #define CMP(d, x, y, size)\ |
790 const int rel_xmin4= xmin - block_x*8; | 797 const int rel_xmin4= xmin - block_x*8; |
791 const int rel_xmax4= xmax - block_x*8 + 8; | 798 const int rel_xmax4= xmax - block_x*8 + 8; |
792 const int rel_ymin4= ymin - block_y*8; | 799 const int rel_ymin4= ymin - block_y*8; |
793 const int rel_ymax4= ymax - block_y*8 + 8; | 800 const int rel_ymax4= ymax - block_y*8 + 8; |
794 #endif | 801 #endif |
795 P_LAST[0] = s->motion_val[mot_xy ][0]; | |
796 P_LAST[1] = s->motion_val[mot_xy ][1]; | |
797 P_LEFT[0] = s->motion_val[mot_xy - 1][0]; | 802 P_LEFT[0] = s->motion_val[mot_xy - 1][0]; |
798 P_LEFT[1] = s->motion_val[mot_xy - 1][1]; | 803 P_LEFT[1] = s->motion_val[mot_xy - 1][1]; |
799 P_LAST_RIGHT[0] = s->motion_val[mot_xy + 1][0]; | |
800 P_LAST_RIGHT[1] = s->motion_val[mot_xy + 1][1]; | |
801 P_LAST_BOTTOM[0]= s->motion_val[mot_xy + 1*mot_stride][0]; | |
802 P_LAST_BOTTOM[1]= s->motion_val[mot_xy + 1*mot_stride][1]; | |
803 | 804 |
804 if(P_LEFT[0] > (rel_xmax4<<shift)) P_LEFT[0] = (rel_xmax4<<shift); | 805 if(P_LEFT[0] > (rel_xmax4<<shift)) P_LEFT[0] = (rel_xmax4<<shift); |
805 if(P_LAST_RIGHT[0] < (rel_xmin4<<shift)) P_LAST_RIGHT[0] = (rel_xmin4<<shift); | |
806 if(P_LAST_BOTTOM[1]< (rel_ymin4<<shift)) P_LAST_BOTTOM[1]= (rel_ymin4<<shift); | |
807 | 806 |
808 /* special case for first line */ | 807 /* special case for first line */ |
809 if ((s->mb_y == 0 || s->first_slice_line) && block<2) { | 808 if ((s->mb_y == 0 || s->first_slice_line) && block<2) { |
810 pred_x4= P_LEFT[0]; | 809 pred_x4= P_LEFT[0]; |
811 pred_y4= P_LEFT[1]; | 810 pred_y4= P_LEFT[1]; |
832 } | 831 } |
833 P_MV1[0]= mx; | 832 P_MV1[0]= mx; |
834 P_MV1[1]= my; | 833 P_MV1[1]= my; |
835 | 834 |
836 dmin4 = s->me.motion_search[1](s, block, &mx4, &my4, P, pred_x4, pred_y4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4, | 835 dmin4 = s->me.motion_search[1](s, block, &mx4, &my4, P, pred_x4, pred_y4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4, |
837 &s->last_picture, mv_penalty); | 836 &s->last_picture, s->p_mv_table, (1<<16)>>shift, mv_penalty); |
838 | 837 |
839 dmin4= s->me.sub_motion_search(s, &mx4, &my4, dmin4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4, | 838 dmin4= s->me.sub_motion_search(s, &mx4, &my4, dmin4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4, |
840 pred_x4, pred_y4, &s->last_picture, block, 1, mv_penalty); | 839 pred_x4, pred_y4, &s->last_picture, block, 1, mv_penalty); |
841 | 840 |
842 s->motion_val[ s->block_index[block] ][0]= mx4; | 841 s->motion_val[ s->block_index[block] ][0]= mx4; |
900 case ME_EPZS: | 899 case ME_EPZS: |
901 { | 900 { |
902 const int mot_stride = s->block_wrap[0]; | 901 const int mot_stride = s->block_wrap[0]; |
903 const int mot_xy = s->block_index[0]; | 902 const int mot_xy = s->block_index[0]; |
904 | 903 |
905 P_LAST[0] = s->motion_val[mot_xy ][0]; | |
906 P_LAST[1] = s->motion_val[mot_xy ][1]; | |
907 P_LEFT[0] = s->motion_val[mot_xy - 1][0]; | 904 P_LEFT[0] = s->motion_val[mot_xy - 1][0]; |
908 P_LEFT[1] = s->motion_val[mot_xy - 1][1]; | 905 P_LEFT[1] = s->motion_val[mot_xy - 1][1]; |
909 P_LAST_RIGHT[0] = s->motion_val[mot_xy + 2][0]; | |
910 P_LAST_RIGHT[1] = s->motion_val[mot_xy + 2][1]; | |
911 P_LAST_BOTTOM[0]= s->motion_val[mot_xy + 2*mot_stride][0]; | |
912 P_LAST_BOTTOM[1]= s->motion_val[mot_xy + 2*mot_stride][1]; | |
913 | 906 |
914 if(P_LEFT[0] > (rel_xmax<<shift)) P_LEFT[0] = (rel_xmax<<shift); | 907 if(P_LEFT[0] > (rel_xmax<<shift)) P_LEFT[0] = (rel_xmax<<shift); |
915 if(P_LAST_RIGHT[0] < (rel_xmin<<shift)) P_LAST_RIGHT[0] = (rel_xmin<<shift); | |
916 if(P_LAST_BOTTOM[1]< (rel_ymin<<shift)) P_LAST_BOTTOM[1]= (rel_ymin<<shift); | |
917 | 908 |
918 /* special case for first line */ | 909 /* special case for first line */ |
919 if ((mb_y == 0 || s->first_slice_line)) { | 910 if ((mb_y == 0 || s->first_slice_line)) { |
920 pred_x= P_LEFT[0]; | 911 pred_x= P_LEFT[0]; |
921 pred_y= P_LEFT[1]; | 912 pred_y= P_LEFT[1]; |
939 pred_y= P_LEFT[1]; | 930 pred_y= P_LEFT[1]; |
940 } | 931 } |
941 } | 932 } |
942 } | 933 } |
943 dmin = s->me.motion_search[0](s, 0, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax, | 934 dmin = s->me.motion_search[0](s, 0, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax, |
944 &s->last_picture, mv_penalty); | 935 &s->last_picture, s->p_mv_table, (1<<16)>>shift, mv_penalty); |
945 | 936 |
946 break; | 937 break; |
947 } | 938 } |
948 | 939 |
949 /* intra / predictive decision */ | 940 /* intra / predictive decision */ |
1044 const int shift= 1+s->quarter_sample; | 1035 const int shift= 1+s->quarter_sample; |
1045 const int mot_stride = s->mb_width + 2; | 1036 const int mot_stride = s->mb_width + 2; |
1046 const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1; | 1037 const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1; |
1047 uint8_t * const ref_picture= picture->data[0]; | 1038 uint8_t * const ref_picture= picture->data[0]; |
1048 uint16_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV; | 1039 uint16_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV; |
1040 int mv_scale; | |
1049 | 1041 |
1050 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); | 1042 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); |
1051 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); | 1043 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); |
1052 | 1044 |
1053 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, f_code); | 1045 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, f_code); |
1080 my-= mb_y*16; | 1072 my-= mb_y*16; |
1081 break; | 1073 break; |
1082 case ME_X1: | 1074 case ME_X1: |
1083 case ME_EPZS: | 1075 case ME_EPZS: |
1084 { | 1076 { |
1085 | |
1086 P_LAST[0] = mv_table[mot_xy ][0]; | |
1087 P_LAST[1] = mv_table[mot_xy ][1]; | |
1088 P_LEFT[0] = mv_table[mot_xy - 1][0]; | 1077 P_LEFT[0] = mv_table[mot_xy - 1][0]; |
1089 P_LEFT[1] = mv_table[mot_xy - 1][1]; | 1078 P_LEFT[1] = mv_table[mot_xy - 1][1]; |
1090 P_LAST_RIGHT[0] = mv_table[mot_xy + 1][0]; | |
1091 P_LAST_RIGHT[1] = mv_table[mot_xy + 1][1]; | |
1092 P_LAST_BOTTOM[0] = mv_table[mot_xy + mot_stride][0]; | |
1093 P_LAST_BOTTOM[1] = mv_table[mot_xy + mot_stride][1]; | |
1094 | 1079 |
1095 if(P_LEFT[0] > (rel_xmax<<shift)) P_LEFT[0] = (rel_xmax<<shift); | 1080 if(P_LEFT[0] > (rel_xmax<<shift)) P_LEFT[0] = (rel_xmax<<shift); |
1096 if(P_LAST_RIGHT[0] < (rel_xmin<<shift)) P_LAST_RIGHT[0] = (rel_xmin<<shift); | |
1097 if(P_LAST_BOTTOM[1]< (rel_ymin<<shift)) P_LAST_BOTTOM[1]= (rel_ymin<<shift); | |
1098 | 1081 |
1099 /* special case for first line */ | 1082 /* special case for first line */ |
1100 if ((mb_y == 0 || s->first_slice_line)) { | 1083 if ((mb_y == 0 || s->first_slice_line)) { |
1101 } else { | 1084 } else { |
1102 P_TOP[0] = mv_table[mot_xy - mot_stride ][0]; | 1085 P_TOP[0] = mv_table[mot_xy - mot_stride ][0]; |
1111 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); | 1094 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); |
1112 } | 1095 } |
1113 pred_x= P_LEFT[0]; | 1096 pred_x= P_LEFT[0]; |
1114 pred_y= P_LEFT[1]; | 1097 pred_y= P_LEFT[1]; |
1115 } | 1098 } |
1099 | |
1100 if(mv_table == s->b_forw_mv_table){ | |
1101 mv_scale= (s->pb_time<<16) / (s->pp_time<<shift); | |
1102 }else{ | |
1103 mv_scale= ((s->pb_time - s->pp_time)<<16) / (s->pp_time<<shift); | |
1104 } | |
1105 | |
1116 dmin = s->me.motion_search[0](s, 0, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax, | 1106 dmin = s->me.motion_search[0](s, 0, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax, |
1117 picture, mv_penalty); | 1107 picture, s->p_mv_table, mv_scale, mv_penalty); |
1118 | 1108 |
1119 break; | 1109 break; |
1120 } | 1110 } |
1121 | 1111 |
1122 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, rel_xmin, rel_ymin, rel_xmax, rel_ymax, | 1112 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, rel_xmin, rel_ymin, rel_xmax, rel_ymax, |
1230 const int time_pb= s->pb_time; | 1220 const int time_pb= s->pb_time; |
1231 int mx, my, xmin, xmax, ymin, ymax; | 1221 int mx, my, xmin, xmax, ymin, ymax; |
1232 int16_t (*mv_table)[2]= s->b_direct_mv_table; | 1222 int16_t (*mv_table)[2]= s->b_direct_mv_table; |
1233 uint16_t * const mv_penalty= s->me.mv_penalty[1] + MAX_MV; | 1223 uint16_t * const mv_penalty= s->me.mv_penalty[1] + MAX_MV; |
1234 | 1224 |
1235 P_LAST[0] = mv_table[mot_xy ][0]; | |
1236 P_LAST[1] = mv_table[mot_xy ][1]; | |
1237 P_LEFT[0] = mv_table[mot_xy - 1][0]; | 1225 P_LEFT[0] = mv_table[mot_xy - 1][0]; |
1238 P_LEFT[1] = mv_table[mot_xy - 1][1]; | 1226 P_LEFT[1] = mv_table[mot_xy - 1][1]; |
1239 P_LAST_RIGHT[0] = mv_table[mot_xy + 1][0]; | 1227 |
1240 P_LAST_RIGHT[1] = mv_table[mot_xy + 1][1]; | |
1241 P_LAST_BOTTOM[0] = mv_table[mot_xy + mot_stride][0]; | |
1242 P_LAST_BOTTOM[1] = mv_table[mot_xy + mot_stride][1]; | |
1243 /* | |
1244 if(P_LEFT[0] > (rel_xmax<<shift)) P_LEFT[0] = (rel_xmax<<shift); | |
1245 if(P_LAST_RIGHT[0] < (rel_xmin<<shift)) P_LAST_RIGHT[0] = (rel_xmin<<shift); | |
1246 if(P_LAST_BOTTOM[1]< (rel_ymin<<shift)) P_LAST_BOTTOM[1]= (rel_ymin<<shift); | |
1247 */ | |
1248 /* special case for first line */ | 1228 /* special case for first line */ |
1249 if ((mb_y == 0 || s->first_slice_line)) { | 1229 if ((mb_y == 0 || s->first_slice_line)) { |
1250 } else { | 1230 } else { |
1251 P_TOP[0] = mv_table[mot_xy - mot_stride ][0]; | 1231 P_TOP[0] = mv_table[mot_xy - mot_stride ][0]; |
1252 P_TOP[1] = mv_table[mot_xy - mot_stride ][1]; | 1232 P_TOP[1] = mv_table[mot_xy - mot_stride ][1]; |
1303 return 256*256*256*64; | 1283 return 256*256*256*64; |
1304 } | 1284 } |
1305 | 1285 |
1306 if(s->flags&CODEC_FLAG_QPEL){ | 1286 if(s->flags&CODEC_FLAG_QPEL){ |
1307 dmin = simple_direct_qpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax, | 1287 dmin = simple_direct_qpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax, |
1308 &s->last_picture, mv_penalty); | 1288 &s->last_picture, mv_table, 1<<14, mv_penalty); |
1309 dmin = simple_direct_qpel_qpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, | 1289 dmin = simple_direct_qpel_qpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, |
1310 0, 0, &s->last_picture, 0, 0, mv_penalty); | 1290 0, 0, &s->last_picture, 0, 0, mv_penalty); |
1311 }else{ | 1291 }else{ |
1312 dmin = simple_direct_hpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax, | 1292 dmin = simple_direct_hpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax, |
1313 &s->last_picture, mv_penalty); | 1293 &s->last_picture, mv_table, 1<<15, mv_penalty); |
1314 dmin = simple_direct_hpel_hpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, | 1294 dmin = simple_direct_hpel_hpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, |
1315 0, 0, &s->last_picture, 0, 0, mv_penalty); | 1295 0, 0, &s->last_picture, 0, 0, mv_penalty); |
1316 } | 1296 } |
1317 | 1297 |
1318 s->b_direct_mv_table[mot_xy][0]= mx; | 1298 s->b_direct_mv_table[mot_xy][0]= mx; |