comparison motion_est.c @ 1013:5d4c95f323d0 libavcodec

finetuneing thresholds/factors nicer mb decission a few minor improvements & fixes
author michaelni
date Sun, 19 Jan 2003 17:55:13 +0000
parents 3b7fcfb9c551
children 48349e11c9b2
comparison
equal deleted inserted replaced
1012:7a5038ec769b 1013:5d4c95f323d0
303 fprintf(stderr,"internal error in cmp function selection\n"); 303 fprintf(stderr,"internal error in cmp function selection\n");
304 } 304 }
305 }; 305 };
306 306
307 static inline int get_penalty_factor(MpegEncContext *s, int type){ 307 static inline int get_penalty_factor(MpegEncContext *s, int type){
308 308 switch(type&0xFF){
309 switch(type){
310 default: 309 default:
311 case FF_CMP_SAD: 310 case FF_CMP_SAD:
312 return s->qscale; 311 return s->qscale*2;
313 case FF_CMP_DCT: 312 case FF_CMP_DCT:
313 return s->qscale*3;
314 case FF_CMP_SATD: 314 case FF_CMP_SATD:
315 return s->qscale*6;
315 case FF_CMP_SSE: 316 case FF_CMP_SSE:
316 case FF_CMP_PSNR: 317 return s->qscale*s->qscale*2;
317 return s->qscale*8;
318 case FF_CMP_BIT: 318 case FF_CMP_BIT:
319 return 1; 319 return 1;
320 case FF_CMP_RD: 320 case FF_CMP_RD:
321 return (s->qscale*s->qscale*105 + 64)>>7; 321 case FF_CMP_PSNR:
322 return (s->qscale*s->qscale*185 + 64)>>7;
322 } 323 }
323 } 324 }
324 325
325 void ff_init_me(MpegEncContext *s){ 326 void ff_init_me(MpegEncContext *s){
326 set_cmp(s, s->dsp.me_pre_cmp, s->avctx->me_pre_cmp); 327 set_cmp(s, s->dsp.me_pre_cmp, s->avctx->me_pre_cmp);
334 else 335 else
335 s->me.sub_motion_search= simple_qpel_motion_search; 336 s->me.sub_motion_search= simple_qpel_motion_search;
336 }else{ 337 }else{
337 if(s->avctx->me_sub_cmp&FF_CMP_CHROMA) 338 if(s->avctx->me_sub_cmp&FF_CMP_CHROMA)
338 s->me.sub_motion_search= simple_chroma_hpel_motion_search; 339 s->me.sub_motion_search= simple_chroma_hpel_motion_search;
339 else if(s->avctx->me_sub_cmp == FF_CMP_SAD && s->avctx->me_cmp == FF_CMP_SAD) 340 else if( s->avctx->me_sub_cmp == FF_CMP_SAD
341 && s->avctx-> me_cmp == FF_CMP_SAD
342 && s->avctx-> mb_cmp == FF_CMP_SAD)
340 s->me.sub_motion_search= sad_hpel_motion_search; 343 s->me.sub_motion_search= sad_hpel_motion_search;
341 else 344 else
342 s->me.sub_motion_search= simple_hpel_motion_search; 345 s->me.sub_motion_search= simple_hpel_motion_search;
343 } 346 }
344 347
352 355
353 if(s->avctx->me_pre_cmp&FF_CMP_CHROMA){ 356 if(s->avctx->me_pre_cmp&FF_CMP_CHROMA){
354 s->me.pre_motion_search= simple_chroma_epzs_motion_search; 357 s->me.pre_motion_search= simple_chroma_epzs_motion_search;
355 }else{ 358 }else{
356 s->me.pre_motion_search= simple_epzs_motion_search; 359 s->me.pre_motion_search= simple_epzs_motion_search;
360 }
361
362 if(s->flags&CODEC_FLAG_QPEL){
363 if(s->avctx->mb_cmp&FF_CMP_CHROMA)
364 s->me.get_mb_score= simple_chroma_qpel_get_mb_score;
365 else
366 s->me.get_mb_score= simple_qpel_get_mb_score;
367 }else{
368 if(s->avctx->mb_cmp&FF_CMP_CHROMA)
369 s->me.get_mb_score= simple_chroma_hpel_get_mb_score;
370 else
371 s->me.get_mb_score= simple_hpel_get_mb_score;
357 } 372 }
358 } 373 }
359 374
360 static int pix_dev(UINT8 * pix, int line_size, int mean) 375 static int pix_dev(UINT8 * pix, int line_size, int mean)
361 { 376 {
786 *xmax = s->mb_width*16 - 16; 801 *xmax = s->mb_width*16 - 16;
787 *ymax = s->mb_height*16 - 16; 802 *ymax = s->mb_height*16 - 16;
788 } 803 }
789 } 804 }
790 805
791 static inline int mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, int ymax, int mx, int my, int shift) 806 static inline int h263_mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, int ymax, int mx, int my, int shift)
792 { 807 {
793 int block; 808 int block;
794 int P[10][2]; 809 int P[10][2];
795 uint8_t *ref_picture= s->last_picture.data[0]; 810 int dmin_sum=0, mx4_sum=0, my4_sum=0;
796 int dmin_sum=0;
797 uint16_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; 811 uint16_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
798 812
799 for(block=0; block<4; block++){ 813 for(block=0; block<4; block++){
800 int mx4, my4; 814 int mx4, my4;
801 int pred_x4, pred_y4; 815 int pred_x4, pred_y4;
836 if(P_TOPRIGHT[1] > (rel_ymax4<<shift)) P_TOPRIGHT[1]= (rel_ymax4<<shift); 850 if(P_TOPRIGHT[1] > (rel_ymax4<<shift)) P_TOPRIGHT[1]= (rel_ymax4<<shift);
837 851
838 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); 852 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
839 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); 853 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
840 854
841 if(s->out_format == FMT_H263){ 855 // if(s->out_format == FMT_H263){
842 pred_x4 = P_MEDIAN[0]; 856 pred_x4 = P_MEDIAN[0];
843 pred_y4 = P_MEDIAN[1]; 857 pred_y4 = P_MEDIAN[1];
858 #if 0
844 }else { /* mpeg1 at least */ 859 }else { /* mpeg1 at least */
845 pred_x4= P_LEFT[0]; 860 pred_x4= P_LEFT[0];
846 pred_y4= P_LEFT[1]; 861 pred_y4= P_LEFT[1];
847 } 862 }
863 #endif
848 } 864 }
849 P_MV1[0]= mx; 865 P_MV1[0]= mx;
850 P_MV1[1]= my; 866 P_MV1[1]= my;
851 867
852 dmin4 = s->me.motion_search[1](s, block, &mx4, &my4, P, pred_x4, pred_y4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4, 868 dmin4 = s->me.motion_search[1](s, block, &mx4, &my4, P, pred_x4, pred_y4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4,
853 &s->last_picture, s->p_mv_table, (1<<16)>>shift, mv_penalty); 869 &s->last_picture, s->p_mv_table, (1<<16)>>shift, mv_penalty);
854 870
855 dmin4= s->me.sub_motion_search(s, &mx4, &my4, dmin4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4, 871 dmin4= s->me.sub_motion_search(s, &mx4, &my4, dmin4, rel_xmin4, rel_ymin4, rel_xmax4, rel_ymax4,
856 pred_x4, pred_y4, &s->last_picture, block, 1, mv_penalty); 872 pred_x4, pred_y4, &s->last_picture, block, 1, mv_penalty);
857 873
874 if(s->dsp.me_sub_cmp != s->dsp.mb_cmp){
875 int dxy;
876 const int offset= ((block&1) + (block>>1)*s->linesize)*8;
877 uint8_t *dest_y = s->me.scratchpad + offset;
878
879 if(s->quarter_sample){
880 uint8_t *ref= s->last_picture.data[0] + (s->mb_x*16 + (mx4>>2)) + (s->mb_y*16 + (my4>>2))*s->linesize + offset;
881 dxy = ((my4 & 3) << 2) | (mx4 & 3);
882
883 if(s->no_rounding)
884 s->dsp.put_no_rnd_qpel_pixels_tab[0][dxy](dest_y , ref , s->linesize);
885 else
886 s->dsp.put_qpel_pixels_tab [0][dxy](dest_y , ref , s->linesize);
887 }else{
888 uint8_t *ref= s->last_picture.data[0] + (s->mb_x*16 + (mx4>>1)) + (s->mb_y*16 + (my4>>1))*s->linesize + offset;
889 dxy = ((my4 & 1) << 1) | (mx4 & 1);
890
891 if(s->no_rounding)
892 s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y , ref , s->linesize, 16);
893 else
894 s->dsp.put_pixels_tab [0][dxy](dest_y , ref , s->linesize, 16);
895 }
896 dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*s->me.mb_penalty_factor;
897 }else
898 dmin_sum+= dmin4;
899
900 if(s->quarter_sample){
901 mx4_sum+= mx4/2;
902 my4_sum+= my4/2;
903 }else{
904 mx4_sum+= mx4;
905 my4_sum+= my4;
906 }
907
858 s->motion_val[ s->block_index[block] ][0]= mx4; 908 s->motion_val[ s->block_index[block] ][0]= mx4;
859 s->motion_val[ s->block_index[block] ][1]= my4; 909 s->motion_val[ s->block_index[block] ][1]= my4;
860 dmin_sum+= dmin4; 910 }
861 } 911
862 return dmin_sum; 912 if(s->dsp.me_sub_cmp != s->dsp.mb_cmp){
913 dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*16*s->linesize, s->me.scratchpad, s->linesize);
914 }
915
916 if(s->avctx->mb_cmp&FF_CMP_CHROMA){
917 int dxy;
918 int mx, my;
919 int offset;
920
921 mx= ff_h263_round_chroma(mx4_sum);
922 my= ff_h263_round_chroma(my4_sum);
923 dxy = ((my & 1) << 1) | (mx & 1);
924
925 offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;
926
927 if(s->no_rounding){
928 s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8);
929 s->dsp.put_no_rnd_pixels_tab[1][dxy](s->me.scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8);
930 }else{
931 s->dsp.put_pixels_tab [1][dxy](s->me.scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8);
932 s->dsp.put_pixels_tab [1][dxy](s->me.scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8);
933 }
934
935 dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, s->me.scratchpad , s->uvlinesize);
936 dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, s->me.scratchpad+8, s->uvlinesize);
937 }
938
939 switch(s->avctx->mb_cmp&0xFF){
940 /*case FF_CMP_SSE:
941 return dmin_sum+ 32*s->qscale*s->qscale;*/
942 case FF_CMP_RD:
943 return dmin_sum;
944 default:
945 return dmin_sum+ 11*s->me.mb_penalty_factor;
946 }
863 } 947 }
864 948
865 void ff_estimate_p_frame_motion(MpegEncContext * s, 949 void ff_estimate_p_frame_motion(MpegEncContext * s,
866 int mb_x, int mb_y) 950 int mb_x, int mb_y)
867 { 951 {
879 963
880 assert(s->quarter_sample==0 || s->quarter_sample==1); 964 assert(s->quarter_sample==0 || s->quarter_sample==1);
881 965
882 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); 966 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp);
883 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); 967 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);
968 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
884 969
885 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code); 970 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code);
886 rel_xmin= xmin - mb_x*16; 971 rel_xmin= xmin - mb_x*16;
887 rel_xmax= xmax - mb_x*16; 972 rel_xmax= xmax - mb_x*16;
888 rel_ymin= ymin - mb_y*16; 973 rel_ymin= ymin - mb_y*16;
969 1054
970 //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); 1055 //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);
971 pic->mb_var [s->mb_width * mb_y + mb_x] = varc; 1056 pic->mb_var [s->mb_width * mb_y + mb_x] = varc;
972 pic->mc_mb_var[s->mb_width * mb_y + mb_x] = vard; 1057 pic->mc_mb_var[s->mb_width * mb_y + mb_x] = vard;
973 pic->mb_mean [s->mb_width * mb_y + mb_x] = (sum+128)>>8; 1058 pic->mb_mean [s->mb_width * mb_y + mb_x] = (sum+128)>>8;
1059 // pic->mb_cmp_score[s->mb_width * mb_y + mb_x] = dmin;
974 pic->mb_var_sum += varc; 1060 pic->mb_var_sum += varc;
975 pic->mc_mb_var_sum += vard; 1061 pic->mc_mb_var_sum += vard;
976 //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); 1062 //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);
977 1063
978 #if 0 1064 #if 0
995 mx <<=shift; 1081 mx <<=shift;
996 my <<=shift; 1082 my <<=shift;
997 } 1083 }
998 if((s->flags&CODEC_FLAG_4MV) 1084 if((s->flags&CODEC_FLAG_4MV)
999 && !s->me.skip && varc>50 && vard>10){ 1085 && !s->me.skip && varc>50 && vard>10){
1000 mv4_search(s, rel_xmin, rel_ymin, rel_xmax, rel_ymax, mx, my, shift); 1086 h263_mv4_search(s, rel_xmin, rel_ymin, rel_xmax, rel_ymax, mx, my, shift);
1001 mb_type|=MB_TYPE_INTER4V; 1087 mb_type|=MB_TYPE_INTER4V;
1002 1088
1003 set_p_mv_tables(s, mx, my, 0); 1089 set_p_mv_tables(s, mx, my, 0);
1004 }else 1090 }else
1005 set_p_mv_tables(s, mx, my, 1); 1091 set_p_mv_tables(s, mx, my, 1);
1006 }else{ 1092 }else{
1093 mb_type= MB_TYPE_INTER;
1094
1095 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, rel_xmin, rel_ymin, rel_xmax, rel_ymax,
1096 pred_x, pred_y, &s->last_picture, 0, 0, mv_penalty);
1097
1098 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)
1099 dmin= s->me.get_mb_score(s, mx, my, pred_x, pred_y, &s->last_picture, mv_penalty);
1100
1101 if((s->flags&CODEC_FLAG_4MV)
1102 && !s->me.skip && varc>50 && vard>10){
1103 int dmin4= h263_mv4_search(s, rel_xmin, rel_ymin, rel_xmax, rel_ymax, mx, my, shift);
1104 if(dmin4 < dmin){
1105 mb_type= MB_TYPE_INTER4V;
1106 dmin=dmin4;
1107 }
1108 }
1109 pic->mb_cmp_score[s->mb_width * mb_y + mb_x] = dmin;
1110 set_p_mv_tables(s, mx, my, mb_type!=MB_TYPE_INTER4V);
1111
1007 if (vard <= 64 || vard < varc) { 1112 if (vard <= 64 || vard < varc) {
1008 // if (sadP <= 32 || sadP < sadI + 500) {
1009 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); 1113 s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
1010 mb_type|= MB_TYPE_INTER;
1011 if (s->me_method != ME_ZERO) {
1012 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, rel_xmin, rel_ymin, rel_xmax, rel_ymax,
1013 pred_x, pred_y, &s->last_picture, 0, 0, mv_penalty);
1014 if((s->flags&CODEC_FLAG_4MV)
1015 && !s->me.skip && varc>50 && vard>10){
1016 int dmin4= mv4_search(s, rel_xmin, rel_ymin, rel_xmax, rel_ymax, mx, my, shift);
1017 if(dmin4 + 128 <dmin)
1018 mb_type= MB_TYPE_INTER4V;
1019 }
1020 set_p_mv_tables(s, mx, my, mb_type!=MB_TYPE_INTER4V);
1021
1022 } else {
1023 mx <<=shift;
1024 my <<=shift;
1025 }
1026 #if 0
1027 if (vard < 10) {
1028 skip++;
1029 fprintf(stderr,"\nEarly skip: %d vard: %2d varc: %5d dmin: %d",
1030 skip, vard, varc, dmin);
1031 }
1032 #endif
1033 }else{ 1114 }else{
1034 s->scene_change_score+= s->qscale; 1115 s->scene_change_score+= s->qscale;
1035 mb_type|= MB_TYPE_INTRA;
1036 mx = 0;
1037 my = 0;
1038 } 1116 }
1039 } 1117 }
1040 1118
1041 s->mb_type[mb_y*s->mb_width + mb_x]= mb_type; 1119 s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
1042 } 1120 }
1115 uint16_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV; 1193 uint16_t * const mv_penalty= s->me.mv_penalty[f_code] + MAX_MV;
1116 int mv_scale; 1194 int mv_scale;
1117 1195
1118 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp); 1196 s->me.penalty_factor = get_penalty_factor(s, s->avctx->me_cmp);
1119 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp); 1197 s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);
1198 s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
1120 1199
1121 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, f_code); 1200 get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, f_code);
1122 rel_xmin= xmin - mb_x*16; 1201 rel_xmin= xmin - mb_x*16;
1123 rel_xmax= xmax - mb_x*16; 1202 rel_xmax= xmax - mb_x*16;
1124 rel_ymin= ymin - mb_y*16; 1203 rel_ymin= ymin - mb_y*16;
1184 break; 1263 break;
1185 } 1264 }
1186 1265
1187 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, rel_xmin, rel_ymin, rel_xmax, rel_ymax, 1266 dmin= s->me.sub_motion_search(s, &mx, &my, dmin, rel_xmin, rel_ymin, rel_xmax, rel_ymax,
1188 pred_x, pred_y, picture, 0, 0, mv_penalty); 1267 pred_x, pred_y, picture, 0, 0, mv_penalty);
1268
1269 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)
1270 dmin= s->me.get_mb_score(s, mx, my, pred_x, pred_y, picture, mv_penalty);
1271
1189 //printf("%d %d %d %d//", s->mb_x, s->mb_y, mx, my); 1272 //printf("%d %d %d %d//", s->mb_x, s->mb_y, mx, my);
1190 // s->mb_type[mb_y*s->mb_width + mb_x]= mb_type; 1273 // s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
1191 mv_table[mot_xy][0]= mx; 1274 mv_table[mot_xy][0]= mx;
1192 mv_table[mot_xy][1]= my; 1275 mv_table[mot_xy][1]= my;
1193 1276
1247 1330
1248 ptr = s->next_picture.data[0] + (src_y * s->linesize) + src_x; 1331 ptr = s->next_picture.data[0] + (src_y * s->linesize) + src_x;
1249 s->dsp.avg_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16); 1332 s->dsp.avg_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16);
1250 } 1333 }
1251 1334
1252 fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->me.sub_penalty_factor 1335 fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->me.mb_penalty_factor
1253 +(mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->me.sub_penalty_factor; 1336 +(mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->me.mb_penalty_factor
1254 + s->dsp.me_sub_cmp[0](s, s->new_picture.data[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize); 1337 + s->dsp.mb_cmp[0](s, s->new_picture.data[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize);
1255 1338
1339 if(s->avctx->mb_cmp&FF_CMP_CHROMA){
1340 }
1341 //FIXME CHROMA !!!
1342
1256 return fbmin; 1343 return fbmin;
1257 } 1344 }
1258 1345
1259 /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/ 1346 /* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/
1260 static inline int bidir_refine(MpegEncContext * s, 1347 static inline int bidir_refine(MpegEncContext * s,
1354 P_TOPRIGHT[1] = clip(mv_table[mot_xy - mot_stride + 1 ][1], ymin<<shift, ymax<<shift); 1441 P_TOPRIGHT[1] = clip(mv_table[mot_xy - mot_stride + 1 ][1], ymin<<shift, ymax<<shift);
1355 1442
1356 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); 1443 P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
1357 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); 1444 P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
1358 } 1445 }
1359 1446
1447 //FIXME direct_search ptr in context!!! (needed for chroma anyway or this will get messy)
1360 if(s->flags&CODEC_FLAG_QPEL){ 1448 if(s->flags&CODEC_FLAG_QPEL){
1361 dmin = simple_direct_qpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax, 1449 dmin = simple_direct_qpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax,
1362 &s->last_picture, mv_table, 1<<14, mv_penalty); 1450 &s->last_picture, mv_table, 1<<14, mv_penalty);
1363 dmin = simple_direct_qpel_qpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, 1451 dmin = simple_direct_qpel_qpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax,
1364 0, 0, &s->last_picture, 0, 0, mv_penalty); 1452 0, 0, &s->last_picture, 0, 0, mv_penalty);
1453
1454 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)
1455 dmin= simple_direct_qpel_qpel_get_mb_score(s, mx, my, 0, 0, &s->last_picture, mv_penalty);
1365 }else{ 1456 }else{
1366 dmin = simple_direct_hpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax, 1457 dmin = simple_direct_hpel_epzs_motion_search(s, 0, &mx, &my, P, 0, 0, xmin, ymin, xmax, ymax,
1367 &s->last_picture, mv_table, 1<<15, mv_penalty); 1458 &s->last_picture, mv_table, 1<<15, mv_penalty);
1368 dmin = simple_direct_hpel_hpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, 1459 dmin = simple_direct_hpel_hpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax,
1369 0, 0, &s->last_picture, 0, 0, mv_penalty); 1460 0, 0, &s->last_picture, 0, 0, mv_penalty);
1461
1462 if(s->avctx->me_sub_cmp != s->avctx->mb_cmp && !s->me.skip)
1463 dmin= simple_direct_hpel_hpel_get_mb_score(s, mx, my, 0, 0, &s->last_picture, mv_penalty);
1370 } 1464 }
1371 1465
1372 s->b_direct_mv_table[mot_xy][0]= mx; 1466 s->b_direct_mv_table[mot_xy][0]= mx;
1373 s->b_direct_mv_table[mot_xy][1]= my; 1467 s->b_direct_mv_table[mot_xy][1]= my;
1374 return dmin; 1468 return dmin;
1375 } 1469 }
1376 1470
1377 void ff_estimate_b_frame_motion(MpegEncContext * s, 1471 void ff_estimate_b_frame_motion(MpegEncContext * s,
1378 int mb_x, int mb_y) 1472 int mb_x, int mb_y)
1379 { 1473 {
1380 const int penalty_factor= s->me.penalty_factor; 1474 const int penalty_factor= s->me.mb_penalty_factor;
1381 int fmin, bmin, dmin, fbmin; 1475 int fmin, bmin, dmin, fbmin;
1382 int type=0; 1476 int type=0;
1383 1477
1384 dmin= direct_search(s, mb_x, mb_y); 1478 dmin= direct_search(s, mb_x, mb_y);
1385 1479
1386 fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, &s->last_picture, s->f_code); 1480 fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, &s->last_picture, s->f_code) + 3*penalty_factor;
1387 bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, &s->next_picture, s->b_code) - penalty_factor; 1481 bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, &s->next_picture, s->b_code) + 2*penalty_factor;
1388 //printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); 1482 //printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
1389 1483
1390 fbmin= bidir_refine(s, mb_x, mb_y); 1484 fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor;
1391 1485 //printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin);
1392 { 1486 {
1393 int score= dmin; 1487 int score= dmin;
1394 type=MB_TYPE_DIRECT; 1488 type=MB_TYPE_DIRECT;
1395 1489
1396 if(fmin<score){ 1490 if(fmin<score){
1403 } 1497 }
1404 if(fbmin<score){ 1498 if(fbmin<score){
1405 score=fbmin; 1499 score=fbmin;
1406 type= MB_TYPE_BIDIR; 1500 type= MB_TYPE_BIDIR;
1407 } 1501 }
1502
1408 score= ((unsigned)(score*score + 128*256))>>16; 1503 score= ((unsigned)(score*score + 128*256))>>16;
1409 s->current_picture.mc_mb_var_sum += score; 1504 s->current_picture.mc_mb_var_sum += score;
1410 s->current_picture.mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD 1505 s->current_picture.mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSE
1411 } 1506 }
1412 1507
1413 if(s->flags&CODEC_FLAG_HQ){ 1508 if(s->flags&CODEC_FLAG_HQ){
1414 type= MB_TYPE_FORWARD | MB_TYPE_BACKWARD | MB_TYPE_BIDIR | MB_TYPE_DIRECT; //FIXME something smarter 1509 type= MB_TYPE_FORWARD | MB_TYPE_BACKWARD | MB_TYPE_BIDIR | MB_TYPE_DIRECT; //FIXME something smarter
1415 if(dmin>256*256*16) type&= ~MB_TYPE_DIRECT; //dont try direct mode if its invalid for this MB 1510 if(dmin>256*256*16) type&= ~MB_TYPE_DIRECT; //dont try direct mode if its invalid for this MB