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;