Browse code

motion estimation pre pass

Originally committed as revision 1389 to svn://svn.ffmpeg.org/ffmpeg/trunk

Michael Niedermayer authored on 2003/01/02 10:29:35
Showing 4 changed files
... ...
@@ -5,8 +5,8 @@
5 5
 
6 6
 #define LIBAVCODEC_VERSION_INT 0x000406
7 7
 #define LIBAVCODEC_VERSION     "0.4.6"
8
-#define LIBAVCODEC_BUILD       4649
9
-#define LIBAVCODEC_BUILD_STR   "4649"
8
+#define LIBAVCODEC_BUILD       4650
9
+#define LIBAVCODEC_BUILD_STR   "4650"
10 10
 
11 11
 enum CodecID {
12 12
     CODEC_ID_NONE, 
... ...
@@ -894,6 +894,13 @@ typedef struct AVCodecContext {
894 894
      * decoding: unused
895 895
      */
896 896
     int last_predictor_count;
897
+    
898
+    /**
899
+     * pre pass for motion estimation
900
+     * encoding: set by user.
901
+     * decoding: unused
902
+     */
903
+    int pre_me;
897 904
 
898 905
 } AVCodecContext;
899 906
 
... ...
@@ -754,12 +754,10 @@ static inline void get_limits(MpegEncContext *s, int *range, int *xmin, int *ymi
754 754
         *ymin = -16;
755 755
         if (s->h263_plus)
756 756
             *range *= 2;
757
-        if(s->avctx==NULL || s->avctx->codec->id!=CODEC_ID_MPEG4){
757
+        if(s->avctx->codec->id!=CODEC_ID_MPEG4){
758 758
             *xmax = s->mb_width*16;
759 759
             *ymax = s->mb_height*16;
760 760
         }else {
761
-            /* XXX: dunno if this is correct but ffmpeg4 decoder wont like it otherwise 
762
-	            (cuz the drawn edge isnt large enough))*/
763 761
             *xmax = s->width;
764 762
             *ymax = s->height;
765 763
         }
... ...
@@ -1024,6 +1022,68 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
1024 1024
     s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
1025 1025
 }
1026 1026
 
1027
+int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
1028
+                                    int mb_x, int mb_y)
1029
+{
1030
+    int mx, my, range, dmin;
1031
+    int xmin, ymin, xmax, ymax;
1032
+    int rel_xmin, rel_ymin, rel_xmax, rel_ymax;
1033
+    int pred_x=0, pred_y=0;
1034
+    int P[10][2];
1035
+    const int shift= 1+s->quarter_sample;
1036
+    uint16_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV;
1037
+    const int mv_stride= s->mb_width + 2;
1038
+    const int xy= mb_x + 1 + (mb_y + 1)*mv_stride;
1039
+    
1040
+    assert(s->quarter_sample==0 || s->quarter_sample==1);
1041
+
1042
+    s->me.penalty_factor    = get_penalty_factor(s, s->avctx->me_cmp);
1043
+
1044
+    get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code);
1045
+    rel_xmin= xmin - mb_x*16;
1046
+    rel_xmax= xmax - mb_x*16;
1047
+    rel_ymin= ymin - mb_y*16;
1048
+    rel_ymax= ymax - mb_y*16;
1049
+    s->me.skip=0;
1050
+
1051
+    P_LEFT[0]       = s->p_mv_table[xy + 1][0];
1052
+    P_LEFT[1]       = s->p_mv_table[xy + 1][1];
1053
+
1054
+    if(P_LEFT[0]       < (rel_xmin<<shift)) P_LEFT[0]       = (rel_xmin<<shift);
1055
+
1056
+    /* special case for first line */
1057
+    if (mb_y == s->mb_height-1) {
1058
+        pred_x= P_LEFT[0];
1059
+        pred_y= P_LEFT[1];
1060
+    } else {
1061
+        P_TOP[0]      = s->p_mv_table[xy + mv_stride    ][0];
1062
+        P_TOP[1]      = s->p_mv_table[xy + mv_stride    ][1];
1063
+        P_TOPRIGHT[0] = s->p_mv_table[xy + mv_stride - 1][0];
1064
+        P_TOPRIGHT[1] = s->p_mv_table[xy + mv_stride - 1][1];
1065
+        if(P_TOP[1]      < (rel_ymin<<shift)) P_TOP[1]     = (rel_ymin<<shift);
1066
+        if(P_TOPRIGHT[0] > (rel_xmax<<shift)) P_TOPRIGHT[0]= (rel_xmax<<shift);
1067
+        if(P_TOPRIGHT[1] < (rel_ymin<<shift)) P_TOPRIGHT[1]= (rel_ymin<<shift);
1068
+    
1069
+        P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
1070
+        P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
1071
+
1072
+        if(s->out_format == FMT_H263){
1073
+            pred_x = P_MEDIAN[0];
1074
+            pred_y = P_MEDIAN[1];
1075
+        }else { /* mpeg1 at least */
1076
+            pred_x= P_LEFT[0];
1077
+            pred_y= P_LEFT[1];
1078
+        }
1079
+    }
1080
+    dmin = s->me.motion_search[0](s, 0, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax, 
1081
+                                  &s->last_picture, s->p_mv_table, (1<<16)>>shift, mv_penalty);
1082
+        
1083
+    s->p_mv_table[xy][0] = mx<<shift;
1084
+    s->p_mv_table[xy][1] = my<<shift;
1085
+    
1086
+    return dmin;
1087
+}
1088
+
1027 1089
 int ff_estimate_motion_b(MpegEncContext * s,
1028 1090
                        int mb_x, int mb_y, int16_t (*mv_table)[2], Picture *picture, int f_code)
1029 1091
 {
... ...
@@ -2789,6 +2789,19 @@ static void encode_picture(MpegEncContext *s, int picture_number)
2789 2789
 
2790 2790
     /* Estimate motion for every MB */
2791 2791
     if(s->pict_type != I_TYPE){
2792
+
2793
+        if(s->pict_type != B_TYPE){
2794
+            if((s->avctx->pre_me && s->last_non_b_pict_type==I_TYPE) || s->avctx->pre_me==2){
2795
+                for(mb_y=s->mb_height-1; mb_y >=0 ; mb_y--) {
2796
+                    for(mb_x=s->mb_width-1; mb_x >=0 ; mb_x--) {
2797
+                        s->mb_x = mb_x;
2798
+                        s->mb_y = mb_y;
2799
+                        ff_pre_estimate_p_frame_motion(s, mb_x, mb_y);
2800
+                    }
2801
+                }
2802
+            }
2803
+        }
2804
+
2792 2805
         for(mb_y=0; mb_y < s->mb_height; mb_y++) {
2793 2806
             s->block_index[0]= s->block_wrap[0]*(mb_y*2 + 1) - 1;
2794 2807
             s->block_index[1]= s->block_wrap[0]*(mb_y*2 + 1);
... ...
@@ -620,6 +620,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type);
620 620
 void ff_fix_long_p_mvs(MpegEncContext * s);
621 621
 void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type);
622 622
 void ff_init_me(MpegEncContext *s);
623
+int ff_pre_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y);
623 624
 
624 625
 
625 626
 /* mpeg12.c */