Browse code

much better ME for b frames (a bit slow though) fixed MC rounding for b frames fixed hq mode with b-frames

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

Michael Niedermayer authored on 2002/04/19 12:25:20
Showing 5 changed files
... ...
@@ -881,6 +881,16 @@ static inline int mid_pred(int a, int b, int c)
881 881
     return a + b + c - vmin - vmax;
882 882
 }
883 883
 
884
+static inline int clip(int a, int amin, int amax)
885
+{
886
+    if (a < amin)
887
+        return amin;
888
+    else if (a > amax)
889
+        return amax;
890
+    else
891
+        return a;
892
+}
893
+
884 894
 /* memory */
885 895
 void *av_mallocz(int size);
886 896
 
... ...
@@ -18,7 +18,7 @@
18 18
  * along with this program; if not, write to the Free Software
19 19
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 20
  *
21
- * ac prediction encoding by Michael Niedermayer <michaelni@gmx.at>
21
+ * ac prediction encoding & b-frame support by Michael Niedermayer <michaelni@gmx.at>
22 22
  */
23 23
 #include "common.h"
24 24
 #include "dsputil.h"
... ...
@@ -282,7 +282,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
282 282
                 s->mv[0][0][1]= 
283 283
                 s->mv[1][0][0]= 
284 284
                 s->mv[1][0][1]= 0;
285
-//                s->mv_dir= MV_DIR_FORWARD; //doesnt matter
285
+                s->mv_dir= MV_DIR_FORWARD; //doesnt matter
286 286
                 return;
287 287
             }
288 288
 
... ...
@@ -334,7 +334,8 @@ void mpeg4_encode_mb(MpegEncContext * s,
334 334
                 s->last_mv[0][0][0]= motion_x;
335 335
                 s->last_mv[0][0][1]= motion_y;
336 336
                 break;
337
-            default: 
337
+            default:
338
+                printf("unknown mb type\n");
338 339
                 return;
339 340
             }
340 341
             bits= get_bit_count(&s->pb);
... ...
@@ -959,6 +960,31 @@ static void put_string(PutBitContext * pbc, char *s)
959 959
     put_bits(pbc, 8, 0);
960 960
 }
961 961
 
962
+/* must be called before writing the header */
963
+void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){
964
+    int time_div, time_mod;
965
+
966
+    if(s->pict_type==I_TYPE){ //we will encode a vol header
967
+        s->time_increment_resolution= s->frame_rate/ff_gcd(s->frame_rate, FRAME_RATE_BASE);
968
+        if(s->time_increment_resolution>=256*256) s->time_increment_resolution= 256*128;
969
+
970
+        s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
971
+    }
972
+
973
+    s->time= picture_number*(int64_t)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate;
974
+    time_div= s->time/s->time_increment_resolution;
975
+    time_mod= s->time%s->time_increment_resolution;
976
+
977
+    if(s->pict_type==B_TYPE){
978
+        s->bp_time= s->last_non_b_time - s->time;
979
+    }else{
980
+        s->last_time_base= s->time_base;
981
+        s->time_base= time_div;
982
+        s->pp_time= s->time - s->last_non_b_time;
983
+        s->last_non_b_time= s->time;
984
+    }
985
+}
986
+
962 987
 static void mpeg4_encode_vol_header(MpegEncContext * s)
963 988
 {
964 989
     int vo_ver_id=1; //must be 2 if we want GMC or q-pel
... ...
@@ -983,11 +1009,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s)
983 983
     put_bits(&s->pb, 2, RECT_SHAPE);	/* vol shape= rectangle */
984 984
     put_bits(&s->pb, 1, 1);		/* marker bit */
985 985
     
986
-    s->time_increment_resolution= s->frame_rate/ff_gcd(s->frame_rate, FRAME_RATE_BASE);
987
-    if(s->time_increment_resolution>=256*256) s->time_increment_resolution= 256*128;
988
-
989 986
     put_bits(&s->pb, 16, s->time_increment_resolution);
990
-    s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
991 987
     if (s->time_increment_bits < 1)
992 988
         s->time_increment_bits = 1;
993 989
     put_bits(&s->pb, 1, 1);		/* marker bit */
... ...
@@ -1034,9 +1056,6 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
1034 1034
     
1035 1035
     if(s->pict_type==I_TYPE) mpeg4_encode_vol_header(s);
1036 1036
     
1037
-    s->time= s->picture_number*(int64_t)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate;
1038
-    time_div= s->time/s->time_increment_resolution;
1039
-    time_mod= s->time%s->time_increment_resolution;
1040 1037
 //printf("num:%d rate:%d base:%d\n", s->picture_number, s->frame_rate, FRAME_RATE_BASE);
1041 1038
     
1042 1039
     if(get_bit_count(&s->pb)!=0) mpeg4_stuffing(&s->pb);
... ...
@@ -1044,15 +1063,8 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
1044 1044
     put_bits(&s->pb, 16, 0x1B6);	/* vop header */
1045 1045
     put_bits(&s->pb, 2, s->pict_type - 1);	/* pict type: I = 0 , P = 1 */
1046 1046
 
1047
-    if(s->pict_type==B_TYPE){
1048
-        s->bp_time= s->last_non_b_time - s->time;
1049
-    }else{
1050
-        s->last_time_base= s->time_base;
1051
-        s->time_base= time_div;
1052
-        s->pp_time= s->time - s->last_non_b_time;
1053
-        s->last_non_b_time= s->time;
1054
-    }
1055
-
1047
+    time_div= s->time/s->time_increment_resolution;
1048
+    time_mod= s->time%s->time_increment_resolution;
1056 1049
     time_incr= time_div - s->last_time_base;
1057 1050
     while(time_incr--)
1058 1051
         put_bits(&s->pb, 1, 1);
... ...
@@ -1770,6 +1782,7 @@ int h263_decode_mb(MpegEncContext *s,
1770 1770
             s->last_mv[0][0][1]= 
1771 1771
             s->last_mv[1][0][0]= 
1772 1772
             s->last_mv[1][0][1]= 0;
1773
+//            printf("\n");
1773 1774
         }
1774 1775
 
1775 1776
         /* if we skipped it in the future P Frame than skip it now too */
... ...
@@ -1789,6 +1802,7 @@ int h263_decode_mb(MpegEncContext *s,
1789 1789
 //FIXME is this correct?
1790 1790
 /*            s->last_mv[0][0][0]=
1791 1791
             s->last_mv[0][0][1]=0;*/
1792
+//            printf("S");
1792 1793
             return 0;
1793 1794
         }
1794 1795
 
... ...
@@ -1837,6 +1851,7 @@ int h263_decode_mb(MpegEncContext *s,
1837 1837
             s->mv[0][0][1] = 
1838 1838
             s->mv[1][0][0] = 
1839 1839
             s->mv[1][0][1] = 1000;*/
1840
+//            printf("D");
1840 1841
             break;
1841 1842
         case 1: 
1842 1843
             s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
... ...
@@ -1849,6 +1864,7 @@ int h263_decode_mb(MpegEncContext *s,
1849 1849
             my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);
1850 1850
             s->last_mv[1][0][0]= s->mv[1][0][0] = mx;
1851 1851
             s->last_mv[1][0][1]= s->mv[1][0][1] = my;
1852
+//            printf("I");
1852 1853
             break;
1853 1854
         case 2: 
1854 1855
             s->mv_dir = MV_DIR_BACKWARD;
... ...
@@ -1856,6 +1872,7 @@ int h263_decode_mb(MpegEncContext *s,
1856 1856
             my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);
1857 1857
             s->last_mv[1][0][0]= s->mv[1][0][0] = mx;
1858 1858
             s->last_mv[1][0][1]= s->mv[1][0][1] = my;
1859
+//            printf("B");
1859 1860
             break;
1860 1861
         case 3:
1861 1862
             s->mv_dir = MV_DIR_FORWARD;
... ...
@@ -1863,6 +1880,7 @@ int h263_decode_mb(MpegEncContext *s,
1863 1863
             my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code);
1864 1864
             s->last_mv[0][0][0]= s->mv[0][0][0] = mx;
1865 1865
             s->last_mv[0][0][1]= s->mv[0][0][1] = my;
1866
+//            printf("F");
1866 1867
             break;
1867 1868
         default: return -1;
1868 1869
         }
... ...
@@ -29,7 +29,7 @@
29 29
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
30 30
 #define INTER_BIAS	257
31 31
 
32
-static void halfpel_motion_search(MpegEncContext * s,
32
+static int halfpel_motion_search(MpegEncContext * s,
33 33
 				  int *mx_ptr, int *my_ptr, int dmin,
34 34
 				  int xmin, int ymin, int xmax, int ymax,
35 35
                                   int pred_x, int pred_y, uint8_t *ref_picture);
... ...
@@ -673,7 +673,7 @@ static int epzs_motion_search4(MpegEncContext * s, int block,
673 673
     
674 674
 /* The idea would be to make half pel ME after Inter/Intra decision to 
675 675
    save time. */
676
-static inline void halfpel_motion_search(MpegEncContext * s,
676
+static inline int halfpel_motion_search(MpegEncContext * s,
677 677
 				  int *mx_ptr, int *my_ptr, int dmin,
678 678
 				  int xmin, int ymin, int xmax, int ymax,
679 679
                                   int pred_x, int pred_y, uint8_t *ref_picture)
... ...
@@ -702,7 +702,7 @@ static inline void halfpel_motion_search(MpegEncContext * s,
702 702
         if(dmin < Z_THRESHOLD && mx==0 && my==0){
703 703
             *mx_ptr = 0;
704 704
             *my_ptr = 0;
705
-            return;
705
+            return dmin;
706 706
         }
707 707
         
708 708
         pen_x= pred_x + mx;
... ...
@@ -727,6 +727,7 @@ static inline void halfpel_motion_search(MpegEncContext * s,
727 727
 
728 728
     *mx_ptr = mx;
729 729
     *my_ptr = my;
730
+    return dminh;
730 731
 }
731 732
 
732 733
 static inline void halfpel_motion_search4(MpegEncContext * s,
... ...
@@ -1044,17 +1045,15 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
1044 1044
     set_p_mv_tables(s, mx, my);
1045 1045
 }
1046 1046
 
1047
-void ff_estimate_motion_b(MpegEncContext * s,
1047
+int ff_estimate_motion_b(MpegEncContext * s,
1048 1048
                        int mb_x, int mb_y, int16_t (*mv_table)[2], uint8_t *ref_picture, int f_code)
1049 1049
 {
1050
-    UINT8 *pix, *ppix;
1051
-    int sum, varc, vard, mx, my, range, dmin, xx, yy;
1050
+    int mx, my, range, dmin;
1052 1051
     int xmin, ymin, xmax, ymax;
1053 1052
     int rel_xmin, rel_ymin, rel_xmax, rel_ymax;
1054 1053
     int pred_x=0, pred_y=0;
1055 1054
     int P[6][2];
1056 1055
     const int shift= 1+s->quarter_sample;
1057
-    int mb_type=0;
1058 1056
     const int mot_stride = s->mb_width + 2;
1059 1057
     const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1;
1060 1058
     
... ...
@@ -1124,18 +1123,210 @@ void ff_estimate_motion_b(MpegEncContext * s,
1124 1124
     /* At this point (mx,my) are full-pell and the absolute displacement */
1125 1125
 //    ppix = ref_picture + (my * s->linesize) + mx;
1126 1126
     
1127
-    halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y, ref_picture);
1127
+    dmin= halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y, ref_picture);
1128 1128
 
1129 1129
 //    s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
1130 1130
     mv_table[mot_xy][0]= mx;
1131 1131
     mv_table[mot_xy][1]= my;
1132
+    return dmin;
1132 1133
 }
1133 1134
 
1134 1135
 
1135
-int ff_decide_type(MpegEncContext * s,
1136
-                int mb_x, int mb_y)
1136
+static inline int check_bidir_mv(MpegEncContext * s,
1137
+                   int mb_x, int mb_y,
1138
+                   int motion_fx, int motion_fy,
1139
+                   int motion_bx, int motion_by,
1140
+                   int pred_fx, int pred_fy,
1141
+                   int pred_bx, int pred_by)
1137 1142
 {
1143
+    //FIXME optimize?
1144
+    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
1145
+    uint8_t *dest_y = s->me_scratchpad;
1146
+    uint8_t *ptr;
1147
+    int dxy;
1148
+    int src_x, src_y;
1149
+    int fbmin;
1150
+
1151
+    fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->qscale;
1152
+
1153
+    dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);
1154
+    src_x = mb_x * 16 + (motion_fx >> 1);
1155
+    src_y = mb_y * 16 + (motion_fy >> 1);
1156
+            
1157
+    ptr = s->last_picture[0] + (src_y * s->linesize) + src_x;
1158
+    put_pixels_tab[dxy](dest_y    , ptr    , s->linesize, 16);
1159
+    put_pixels_tab[dxy](dest_y + 8, ptr + 8, s->linesize, 16);
1160
+    
1161
+    fbmin += (mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->qscale;
1162
+
1163
+    dxy = ((motion_by & 1) << 1) | (motion_bx & 1);
1164
+    src_x = mb_x * 16 + (motion_bx >> 1);
1165
+    src_y = mb_y * 16 + (motion_by >> 1);
1166
+            
1167
+    ptr = s->next_picture[0] + (src_y * s->linesize) + src_x;
1168
+    avg_pixels_tab[dxy](dest_y    , ptr    , s->linesize, 16);
1169
+    avg_pixels_tab[dxy](dest_y + 8, ptr + 8, s->linesize, 16);
1170
+    
1171
+    fbmin += pix_abs16x16(s->new_picture[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize);
1172
+    return fbmin;
1173
+}
1138 1174
 
1175
+/* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/
1176
+static inline int bidir_refine(MpegEncContext * s,
1177
+                                  int mb_x, int mb_y)
1178
+{
1179
+    const int mot_stride = s->mb_width + 2;
1180
+    const int xy = (mb_y + 1)*mot_stride + mb_x + 1;
1181
+    int fbmin;
1182
+    int pred_fx= s->b_bidir_forw_mv_table[xy-1][0];
1183
+    int pred_fy= s->b_bidir_forw_mv_table[xy-1][1];
1184
+    int pred_bx= s->b_bidir_back_mv_table[xy-1][0];
1185
+    int pred_by= s->b_bidir_back_mv_table[xy-1][1];
1186
+    int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0];
1187
+    int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1];
1188
+    int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0];
1189
+    int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1];
1190
+
1191
+    //FIXME do refinement and add flag
1192
+    
1193
+    fbmin= check_bidir_mv(s, mb_x, mb_y, 
1194
+                          motion_fx, motion_fy,
1195
+                          motion_bx, motion_by,
1196
+                          pred_fx, pred_fy,
1197
+                          pred_bx, pred_by);
1198
+
1199
+   return fbmin;
1200
+}
1201
+
1202
+static inline int direct_search(MpegEncContext * s,
1203
+                                int mb_x, int mb_y)
1204
+{
1205
+    int P[6][2];
1206
+    const int mot_stride = s->mb_width + 2;
1207
+    const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1;
1208
+    int dmin, dmin2;
1209
+    int motion_fx, motion_fy, motion_bx, motion_by, motion_bx0, motion_by0;
1210
+    int motion_dx, motion_dy;
1211
+    const int motion_px= s->p_mv_table[mot_xy][0];
1212
+    const int motion_py= s->p_mv_table[mot_xy][1];
1213
+    const int time_pp= s->pp_time;
1214
+    const int time_bp= s->bp_time;
1215
+    const int time_pb= time_pp - time_bp;
1216
+    int bx, by;
1217
+    int mx, my, mx2, my2;
1218
+    uint8_t *ref_picture= s->me_scratchpad - (mb_x + 1 + (mb_y + 1)*s->linesize)*16;
1219
+    int16_t (*mv_table)[2]= s->b_direct_mv_table;
1220
+    uint16_t *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
1221
+
1222
+    /* thanks to iso-mpeg the rounding is different for the zero vector, so we need to handle that ... */
1223
+    motion_fx= (motion_px*time_pb)/time_pp;
1224
+    motion_fy= (motion_py*time_pb)/time_pp;
1225
+    motion_bx0= (-motion_px*time_bp)/time_pp;
1226
+    motion_by0= (-motion_py*time_bp)/time_pp;
1227
+    motion_dx= motion_dy=0;
1228
+    dmin2= check_bidir_mv(s, mb_x, mb_y, 
1229
+                          motion_fx, motion_fy,
1230
+                          motion_bx0, motion_by0,
1231
+                          motion_fx, motion_fy,
1232
+                          motion_bx0, motion_by0) - s->qscale;
1233
+
1234
+    motion_bx= motion_fx - motion_px;
1235
+    motion_by= motion_fy - motion_py;
1236
+    for(by=-1; by<2; by++){
1237
+        for(bx=-1; bx<2; bx++){
1238
+            uint8_t *dest_y = s->me_scratchpad + (by+1)*s->linesize*16 + (bx+1)*16;
1239
+            uint8_t *ptr;
1240
+            int dxy;
1241
+            int src_x, src_y;
1242
+            const int width= s->width;
1243
+            const int height= s->height;
1244
+
1245
+            dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);
1246
+            src_x = (mb_x + bx) * 16 + (motion_fx >> 1);
1247
+            src_y = (mb_y + by) * 16 + (motion_fy >> 1);
1248
+            src_x = clip(src_x, -16, width);
1249
+            if (src_x == width) dxy &= ~1;
1250
+            src_y = clip(src_y, -16, height);
1251
+            if (src_y == height) dxy &= ~2;
1252
+
1253
+            ptr = s->last_picture[0] + (src_y * s->linesize) + src_x;
1254
+            put_pixels_tab[dxy](dest_y    , ptr    , s->linesize, 16);
1255
+            put_pixels_tab[dxy](dest_y + 8, ptr + 8, s->linesize, 16);
1256
+
1257
+            dxy = ((motion_by & 1) << 1) | (motion_bx & 1);
1258
+            src_x = (mb_x + bx) * 16 + (motion_bx >> 1);
1259
+            src_y = (mb_y + by) * 16 + (motion_by >> 1);
1260
+            src_x = clip(src_x, -16, width);
1261
+            if (src_x == width) dxy &= ~1;
1262
+            src_y = clip(src_y, -16, height);
1263
+            if (src_y == height) dxy &= ~2;
1264
+
1265
+            avg_pixels_tab[dxy](dest_y    , ptr    , s->linesize, 16);
1266
+            avg_pixels_tab[dxy](dest_y + 8, ptr + 8, s->linesize, 16);
1267
+        }
1268
+    }
1269
+
1270
+    P[0][0] = mv_table[mot_xy    ][0];
1271
+    P[0][1] = mv_table[mot_xy    ][1];
1272
+    P[1][0] = mv_table[mot_xy - 1][0];
1273
+    P[1][1] = mv_table[mot_xy - 1][1];
1274
+
1275
+    /* special case for first line */
1276
+    if ((mb_y == 0 || s->first_slice_line || s->first_gob_line)) {
1277
+        P[4][0] = P[1][0];
1278
+        P[4][1] = P[1][1];
1279
+    } else {
1280
+        P[2][0] = mv_table[mot_xy - mot_stride             ][0];
1281
+        P[2][1] = mv_table[mot_xy - mot_stride             ][1];
1282
+        P[3][0] = mv_table[mot_xy - mot_stride + 1         ][0];
1283
+        P[3][1] = mv_table[mot_xy - mot_stride + 1         ][1];
1284
+    
1285
+        P[4][0]= mid_pred(P[1][0], P[2][0], P[3][0]);
1286
+        P[4][1]= mid_pred(P[1][1], P[2][1], P[3][1]);
1287
+    }
1288
+    dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, -16, -16, 15, 15, ref_picture);
1289
+    if(mx==0 && my==0) dmin=99999999; // not representable, due to rounding stuff
1290
+    if(dmin2<dmin){ 
1291
+        dmin= dmin2;
1292
+        mx=0;
1293
+        my=0;
1294
+    }
1295
+#if 1
1296
+    mx2= mx= mx*2; 
1297
+    my2= my= my*2;
1298
+    for(by=-1; by<2; by++){
1299
+        if(my2+by < -32) continue;
1300
+        for(bx=-1; bx<2; bx++){
1301
+            if(bx==0 && by==0) continue;
1302
+            if(mx2+bx < -32) continue;
1303
+            dmin2= check_bidir_mv(s, mb_x, mb_y, 
1304
+                          mx2+bx+motion_fx, my2+by+motion_fy,
1305
+                          mx2+bx+motion_bx, my2+by+motion_by,
1306
+                          mx2+bx+motion_fx, my2+by+motion_fy,
1307
+                          motion_bx, motion_by) - s->qscale;
1308
+            
1309
+            if(dmin2<dmin){
1310
+                dmin=dmin2;
1311
+                mx= mx2 + bx;
1312
+                my= my2 + by;
1313
+            }
1314
+        }
1315
+    }
1316
+#else
1317
+    mx*=2; my*=2;
1318
+#endif
1319
+    if(mx==0 && my==0){
1320
+        motion_bx= motion_bx0;
1321
+        motion_by= motion_by0;
1322
+    }
1323
+
1324
+    s->b_direct_mv_table[mot_xy][0]= mx;
1325
+    s->b_direct_mv_table[mot_xy][1]= my;
1326
+    s->b_direct_forw_mv_table[mot_xy][0]= motion_fx + mx;
1327
+    s->b_direct_forw_mv_table[mot_xy][1]= motion_fy + my;
1328
+    s->b_direct_back_mv_table[mot_xy][0]= motion_bx + mx;
1329
+    s->b_direct_back_mv_table[mot_xy][1]= motion_by + my;
1330
+    return dmin;
1139 1331
 }
1140 1332
 
1141 1333
 void ff_estimate_b_frame_motion(MpegEncContext * s,
... ...
@@ -1143,16 +1334,41 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
1143 1143
 {
1144 1144
     const int mot_stride = s->mb_width + 2;
1145 1145
     const int xy = (mb_y + 1)*mot_stride + mb_x + 1;
1146
+    const int quant= s->qscale;
1147
+    int fmin, bmin, dmin, fbmin;
1148
+    int type=0;
1149
+    int motion_fx, motion_fy, motion_bx, motion_by;
1150
+    
1151
+    dmin= direct_search(s, mb_x, mb_y);
1146 1152
 
1147
-    ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[0], s->f_code);
1148
-    ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture[0], s->b_code);
1153
+    fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[0], s->f_code);
1154
+    bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture[0], s->b_code) - quant;
1149 1155
 //printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
1150
-    s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0];
1151
-    s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1];
1152
-    s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0];
1153
-    s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1];
1154
-    
1155
-    s->mb_type[mb_y*s->mb_width + mb_x]= MB_TYPE_FORWARD; //FIXME
1156
+
1157
+    fbmin= bidir_refine(s, mb_x, mb_y);
1158
+
1159
+    if(s->flags&CODEC_FLAG_HQ){
1160
+        type= MB_TYPE_FORWARD | MB_TYPE_BACKWARD | MB_TYPE_BIDIR | MB_TYPE_DIRECT;
1161
+    }else{
1162
+        int score= dmin;
1163
+        type=MB_TYPE_DIRECT;
1164
+        
1165
+        if(fmin<score){
1166
+            score=fmin;
1167
+            type= MB_TYPE_FORWARD; 
1168
+        }
1169
+        if(bmin<score){
1170
+            score=bmin;
1171
+            type= MB_TYPE_BACKWARD; 
1172
+        }
1173
+        if(fbmin<score){
1174
+            score=fbmin;
1175
+            type= MB_TYPE_BIDIR;
1176
+        }
1177
+        s->mc_mb_var += score;
1178
+    }
1179
+
1180
+    s->mb_type[mb_y*s->mb_width + mb_x]= type;
1156 1181
 }
1157 1182
 
1158 1183
 /* find best f_code for ME which do unlimited searches */
... ...
@@ -1184,8 +1400,12 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
1184 1184
         }
1185 1185
 
1186 1186
         for(i=MAX_FCODE; i>1; i--){
1187
+            int threshold;
1187 1188
             loose+= mv_num[i];
1188
-            if(loose > s->mb_num/20) break; //FIXME this is pretty ineffective
1189
+
1190
+            if(s->pict_type==B_TYPE) threshold= 0;
1191
+            else                     threshold= s->mb_num/20; //FIXME 
1192
+            if(loose > threshold) break;
1189 1193
         }
1190 1194
 //    printf("fcode: %d type: %d\n", i, s->pict_type);
1191 1195
         return i;
... ...
@@ -1275,11 +1495,12 @@ void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, i
1275 1275
                    || fcode_tab[mv_table[xy][0] + MAX_MV] == 0
1276 1276
                    || fcode_tab[mv_table[xy][1] + MAX_MV] > f_code
1277 1277
                    || fcode_tab[mv_table[xy][1] + MAX_MV] == 0 ){
1278
-                    s->mb_type[i] &= ~type;
1279
-                    if(s->mb_type[i]==0) s->mb_type[i]= MB_TYPE_FORWARD; //FIXME 
1280
-                    mv_table[xy][0] = 0;
1281
-                    mv_table[xy][1] = 0;
1282
-                    //this is certainly bad FIXME
1278
+                    if(s->mb_type[i]&(~type)) s->mb_type[i] &= ~type;
1279
+                    else{
1280
+                        mv_table[xy][0] = 0;
1281
+                        mv_table[xy][1] = 0;
1282
+                        //this is certainly bad FIXME            
1283
+                    }
1283 1284
                 }
1284 1285
             }
1285 1286
             xy++;
... ...
@@ -225,6 +225,12 @@ int MPV_common_init(MpegEncContext *s)
225 225
             goto fail;
226 226
         }
227 227
 
228
+        s->me_scratchpad = av_mallocz( s->linesize*16*3*sizeof(uint8_t));
229
+        if (s->me_scratchpad == NULL) {
230
+            perror("malloc");
231
+            goto fail;
232
+        }
233
+
228 234
         if(s->max_b_frames){
229 235
             for(j=0; j<REORDER_BUFFER_SIZE; j++){
230 236
                 int i;
... ...
@@ -297,7 +303,7 @@ int MPV_common_init(MpegEncContext *s)
297 297
     if (!s->mbskip_table)
298 298
         goto fail;
299 299
     
300
-    s->block= s->intra_block;
300
+    s->block= s->blocks[0];
301 301
 
302 302
     s->context_initialized = 1;
303 303
     return 0;
... ...
@@ -333,6 +339,7 @@ void MPV_common_end(MpegEncContext *s)
333 333
     CHECK_FREE(s->ac_val[0]);
334 334
     CHECK_FREE(s->coded_block);
335 335
     CHECK_FREE(s->mbintra_table);
336
+    CHECK_FREE(s->me_scratchpad);
336 337
 
337 338
     CHECK_FREE(s->mbskip_table);
338 339
     for(i=0;i<3;i++) {
... ...
@@ -761,16 +768,6 @@ int MPV_encode_picture(AVCodecContext *avctx,
761 761
     return pbBufPtr(&s->pb) - s->pb.buf;
762 762
 }
763 763
 
764
-static inline int clip(int a, int amin, int amax)
765
-{
766
-    if (a < amin)
767
-        return amin;
768
-    else if (a > amax)
769
-        return amax;
770
-    else
771
-        return a;
772
-}
773
-
774 764
 static inline void gmc1_motion(MpegEncContext *s,
775 765
                                UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
776 766
                                int dest_offset,
... ...
@@ -1225,7 +1222,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
1225 1225
         if (!s->mb_intra) {
1226 1226
             /* motion handling */
1227 1227
             if((s->flags&CODEC_FLAG_HQ) || (!s->encoding)){
1228
-                if (!s->no_rounding){
1228
+                if ((!s->no_rounding) || s->pict_type==B_TYPE){                
1229 1229
                     op_pix = put_pixels_tab;
1230 1230
                     op_qpix= qpel_mc_rnd_tab;
1231 1231
                 }else{
... ...
@@ -1235,7 +1232,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
1235 1235
 
1236 1236
                 if (s->mv_dir & MV_DIR_FORWARD) {
1237 1237
                     MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix);
1238
-                    if (!s->no_rounding) 
1238
+                    if ((!s->no_rounding) || s->pict_type==B_TYPE)
1239 1239
                         op_pix = avg_pixels_tab;
1240 1240
                     else
1241 1241
                         op_pix = avg_no_rnd_pixels_tab;
... ...
@@ -1312,7 +1309,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
1312 1312
         dest_cb = s->current_picture[1] + (mb_y * 8  * (s->linesize >> 1)) + mb_x * 8;
1313 1313
         dest_cr = s->current_picture[2] + (mb_y * 8  * (s->linesize >> 1)) + mb_x * 8;
1314 1314
 
1315
-        if (!s->no_rounding){
1315
+        if ((!s->no_rounding) || s->pict_type==B_TYPE){
1316 1316
             op_pix = put_pixels_tab;
1317 1317
             op_qpix= qpel_mc_rnd_tab;
1318 1318
         }else{
... ...
@@ -1322,7 +1319,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
1322 1322
 
1323 1323
         if (s->mv_dir & MV_DIR_FORWARD) {
1324 1324
             MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix);
1325
-            if (!s->no_rounding) 
1325
+           if ((!s->no_rounding) || s->pict_type==B_TYPE)
1326 1326
                 op_pix = avg_pixels_tab;
1327 1327
             else
1328 1328
                 op_pix = avg_no_rnd_pixels_tab;
... ...
@@ -1429,6 +1426,8 @@ static void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int
1429 1429
     d->skip_count= s->skip_count;
1430 1430
     d->misc_bits= s->misc_bits;
1431 1431
     d->last_bits= s->last_bits;
1432
+
1433
+    d->mb_skiped= s->mb_skiped;
1432 1434
 }
1433 1435
 
1434 1436
 static void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int type){
... ...
@@ -1453,6 +1452,7 @@ static void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int
1453 1453
     d->last_bits= s->last_bits;
1454 1454
 
1455 1455
     d->mb_intra= s->mb_intra;
1456
+    d->mb_skiped= s->mb_skiped;
1456 1457
     d->mv_type= s->mv_type;
1457 1458
     d->mv_dir= s->mv_dir;
1458 1459
     d->pb= s->pb;
... ...
@@ -1468,7 +1468,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1468 1468
     int i;
1469 1469
     int bits;
1470 1470
     MpegEncContext best_s, backup_s;
1471
-    UINT8 bit_buf[4][3000]; //FIXME check that this is ALLWAYS large enogh for a MB
1471
+    UINT8 bit_buf[7][3000]; //FIXME check that this is ALLWAYS large enogh for a MB
1472 1472
 
1473 1473
     s->picture_number = picture_number;
1474 1474
 
... ...
@@ -1483,7 +1483,11 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1483 1483
     /* Reset the average MB variance */
1484 1484
     s->avg_mb_var = 0;
1485 1485
     s->mc_mb_var = 0;
1486
-    
1486
+
1487
+    /* we need to initialize some time vars before we can encode b-frames */
1488
+    if (s->h263_pred && !s->h263_msmpeg4)
1489
+        ff_set_mpeg4_time(s, s->picture_number); 
1490
+
1487 1491
     /* Estimate motion for every MB */
1488 1492
     if(s->pict_type != I_TYPE){
1489 1493
 //        int16_t (*tmp)[2]= s->p_mv_table;
... ...
@@ -1535,9 +1539,11 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1535 1535
     if(s->pict_type==B_TYPE){
1536 1536
         s->f_code= ff_get_best_fcode(s, s->b_forw_mv_table, MB_TYPE_FORWARD);
1537 1537
         s->b_code= ff_get_best_fcode(s, s->b_back_mv_table, MB_TYPE_BACKWARD);
1538
-        //FIXME if BIDIR != for&back
1539
-        ff_fix_long_b_mvs(s, s->b_forw_mv_table, s->f_code, MB_TYPE_FORWARD |MB_TYPE_BIDIR);
1540
-        ff_fix_long_b_mvs(s, s->b_back_mv_table, s->b_code, MB_TYPE_BACKWARD|MB_TYPE_BIDIR);
1538
+
1539
+        ff_fix_long_b_mvs(s, s->b_forw_mv_table, s->f_code, MB_TYPE_FORWARD);
1540
+        ff_fix_long_b_mvs(s, s->b_back_mv_table, s->b_code, MB_TYPE_BACKWARD);
1541
+        ff_fix_long_b_mvs(s, s->b_bidir_forw_mv_table, s->f_code, MB_TYPE_BIDIR);
1542
+        ff_fix_long_b_mvs(s, s->b_bidir_back_mv_table, s->b_code, MB_TYPE_BIDIR);
1541 1543
     }
1542 1544
     
1543 1545
 //printf("f_code %d ///\n", s->f_code);
... ...
@@ -1632,7 +1638,8 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1632 1632
         s->block_index[4]= s->block_wrap[4]*(mb_y + 1)                    + s->block_wrap[0]*(s->mb_height*2 + 2);
1633 1633
         s->block_index[5]= s->block_wrap[4]*(mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2);
1634 1634
         for(mb_x=0; mb_x < s->mb_width; mb_x++) {
1635
-            /*const */int mb_type= s->mb_type[mb_y * s->mb_width + mb_x];
1635
+            const int mb_type= s->mb_type[mb_y * s->mb_width + mb_x];
1636
+            const int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
1636 1637
             PutBitContext pb;
1637 1638
             int d;
1638 1639
             int dmin=10000000;
... ...
@@ -1647,19 +1654,19 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1647 1647
             s->block_index[4]++;
1648 1648
             s->block_index[5]++;
1649 1649
             if(mb_type & (mb_type-1)){ // more than 1 MB type possible
1650
+                int next_block=0;
1650 1651
                 pb= s->pb;
1651
-                s->mv_dir = MV_DIR_FORWARD;
1652 1652
 
1653 1653
                 copy_context_before_encode(&backup_s, s, -1);
1654 1654
 
1655 1655
                 if(mb_type&MB_TYPE_INTER){
1656
-                    int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
1656
+                    s->mv_dir = MV_DIR_FORWARD;
1657 1657
                     s->mv_type = MV_TYPE_16X16;
1658 1658
                     s->mb_intra= 0;
1659 1659
                     s->mv[0][0][0] = s->p_mv_table[xy][0];
1660 1660
                     s->mv[0][0][1] = s->p_mv_table[xy][1];
1661 1661
                     init_put_bits(&s->pb, bit_buf[1], 3000, NULL, NULL);
1662
-                    s->block= s->inter_block;
1662
+                    s->block= s->blocks[next_block];
1663 1663
 
1664 1664
                     encode_mb(s, s->mv[0][0][0], s->mv[0][0][1]);
1665 1665
                     d= get_bit_count(&s->pb);
... ...
@@ -1668,10 +1675,12 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1668 1668
                         dmin=d;
1669 1669
                         copy_context_after_encode(&best_s, s, MB_TYPE_INTER);
1670 1670
                         best=1;
1671
+                        next_block^=1;
1671 1672
                     }
1672 1673
                 }
1673 1674
                 if(mb_type&MB_TYPE_INTER4V){                 
1674 1675
                     copy_context_before_encode(s, &backup_s, MB_TYPE_INTER4V);
1676
+                    s->mv_dir = MV_DIR_FORWARD;
1675 1677
                     s->mv_type = MV_TYPE_8X8;
1676 1678
                     s->mb_intra= 0;
1677 1679
                     for(i=0; i<4; i++){
... ...
@@ -1679,25 +1688,111 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1679 1679
                         s->mv[0][i][1] = s->motion_val[s->block_index[i]][1];
1680 1680
                     }
1681 1681
                     init_put_bits(&s->pb, bit_buf[2], 3000, NULL, NULL);
1682
-                    s->block= s->inter4v_block;
1682
+                    s->block= s->blocks[next_block];
1683 1683
 
1684 1684
                     encode_mb(s, 0, 0);
1685 1685
                     d= get_bit_count(&s->pb);
1686
-                    if(d<dmin && 0){
1686
+                    if(d<dmin){
1687 1687
                         flush_put_bits(&s->pb);
1688 1688
                         dmin=d;
1689 1689
                         copy_context_after_encode(&best_s, s, MB_TYPE_INTER4V);
1690 1690
                         best=2;
1691
+                        next_block^=1;
1692
+                    }
1693
+                }
1694
+                if(mb_type&MB_TYPE_FORWARD){
1695
+                    copy_context_before_encode(s, &backup_s, MB_TYPE_FORWARD);
1696
+                    s->mv_dir = MV_DIR_FORWARD;
1697
+                    s->mv_type = MV_TYPE_16X16;
1698
+                    s->mb_intra= 0;
1699
+                    s->mv[0][0][0] = s->b_forw_mv_table[xy][0];
1700
+                    s->mv[0][0][1] = s->b_forw_mv_table[xy][1];
1701
+                    init_put_bits(&s->pb, bit_buf[3], 3000, NULL, NULL);
1702
+                    s->block= s->blocks[next_block];
1703
+
1704
+                    encode_mb(s, s->mv[0][0][0], s->mv[0][0][1]);
1705
+                    d= get_bit_count(&s->pb);
1706
+                    if(d<dmin){
1707
+                        flush_put_bits(&s->pb);
1708
+                        dmin=d;
1709
+                        copy_context_after_encode(&best_s, s, MB_TYPE_FORWARD);
1710
+                        best=3;
1711
+                        next_block^=1;
1712
+                    }
1713
+                }
1714
+                if(mb_type&MB_TYPE_BACKWARD){
1715
+                    copy_context_before_encode(s, &backup_s, MB_TYPE_BACKWARD);
1716
+                    s->mv_dir = MV_DIR_BACKWARD;
1717
+                    s->mv_type = MV_TYPE_16X16;
1718
+                    s->mb_intra= 0;
1719
+                    s->mv[1][0][0] = s->b_back_mv_table[xy][0];
1720
+                    s->mv[1][0][1] = s->b_back_mv_table[xy][1];
1721
+                    init_put_bits(&s->pb, bit_buf[4], 3000, NULL, NULL);
1722
+                    s->block= s->blocks[next_block];
1723
+
1724
+                    encode_mb(s, s->mv[1][0][0], s->mv[1][0][1]);
1725
+                    d= get_bit_count(&s->pb);
1726
+                    if(d<dmin){
1727
+                        flush_put_bits(&s->pb);
1728
+                        dmin=d;
1729
+                        copy_context_after_encode(&best_s, s, MB_TYPE_BACKWARD);
1730
+                        best=4;
1731
+                        next_block^=1;
1732
+                    }
1733
+                }
1734
+                if(mb_type&MB_TYPE_BIDIR){
1735
+                    copy_context_before_encode(s, &backup_s, MB_TYPE_BIDIR);
1736
+                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1737
+                    s->mv_type = MV_TYPE_16X16;
1738
+                    s->mb_intra= 0;
1739
+                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
1740
+                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
1741
+                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
1742
+                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
1743
+                    init_put_bits(&s->pb, bit_buf[5], 3000, NULL, NULL);
1744
+                    s->block= s->blocks[next_block];
1745
+
1746
+                    encode_mb(s, 0, 0);
1747
+                    d= get_bit_count(&s->pb);
1748
+                    if(d<dmin){
1749
+                        flush_put_bits(&s->pb);
1750
+                        dmin=d;
1751
+                        copy_context_after_encode(&best_s, s, MB_TYPE_BIDIR);
1752
+                        best=5;
1753
+                        next_block^=1;
1754
+                    }
1755
+                }
1756
+                if(mb_type&MB_TYPE_DIRECT){
1757
+                    copy_context_before_encode(s, &backup_s, MB_TYPE_DIRECT);
1758
+                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
1759
+                    s->mv_type = MV_TYPE_16X16; //FIXME
1760
+                    s->mb_intra= 0;
1761
+                    s->mv[0][0][0] = s->b_direct_forw_mv_table[xy][0];
1762
+                    s->mv[0][0][1] = s->b_direct_forw_mv_table[xy][1];
1763
+                    s->mv[1][0][0] = s->b_direct_back_mv_table[xy][0];
1764
+                    s->mv[1][0][1] = s->b_direct_back_mv_table[xy][1];
1765
+                    init_put_bits(&s->pb, bit_buf[6], 3000, NULL, NULL);
1766
+                    s->block= s->blocks[next_block];
1767
+
1768
+                    encode_mb(s, s->b_direct_mv_table[xy][0], s->b_direct_mv_table[xy][1]);
1769
+                    d= get_bit_count(&s->pb);
1770
+                    if(d<dmin){
1771
+                        flush_put_bits(&s->pb);
1772
+                        dmin=d;
1773
+                        copy_context_after_encode(&best_s, s, MB_TYPE_DIRECT);
1774
+                        best=6;
1775
+                        next_block^=1;
1691 1776
                     }
1692 1777
                 }
1693 1778
                 if(mb_type&MB_TYPE_INTRA){
1694 1779
                     copy_context_before_encode(s, &backup_s, MB_TYPE_INTRA);
1780
+                    s->mv_dir = MV_DIR_FORWARD;
1695 1781
                     s->mv_type = MV_TYPE_16X16;
1696 1782
                     s->mb_intra= 1;
1697 1783
                     s->mv[0][0][0] = 0;
1698 1784
                     s->mv[0][0][1] = 0;
1699 1785
                     init_put_bits(&s->pb, bit_buf[0], 3000, NULL, NULL);
1700
-                    s->block= s->intra_block;
1786
+                    s->block= s->blocks[next_block];
1701 1787
                    
1702 1788
                     encode_mb(s, 0, 0);
1703 1789
                     d= get_bit_count(&s->pb);
... ...
@@ -1706,6 +1801,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1706 1706
                         dmin=d;
1707 1707
                         copy_context_after_encode(&best_s, s, MB_TYPE_INTRA);
1708 1708
                         best=0;
1709
+                        next_block^=1;
1709 1710
                     }
1710 1711
                     /* force cleaning of ac/dc pred stuff if needed ... */
1711 1712
                     if(s->h263_pred || s->h263_aic)
... ...
@@ -1718,30 +1814,30 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1718 1718
                 int motion_x, motion_y;
1719 1719
                 s->mv_type=MV_TYPE_16X16;
1720 1720
                 // only one MB-Type possible
1721
-                //FIXME convert to swicth()
1722
-                if(mb_type&MB_TYPE_INTRA){
1721
+                switch(mb_type){
1722
+                case MB_TYPE_INTRA:
1723 1723
                     s->mv_dir = MV_DIR_FORWARD;
1724 1724
                     s->mb_intra= 1;
1725 1725
                     motion_x= s->mv[0][0][0] = 0;
1726 1726
                     motion_y= s->mv[0][0][1] = 0;
1727
-                }else if(mb_type&MB_TYPE_INTER){
1728
-                    int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
1727
+                    break;
1728
+                case MB_TYPE_INTER:
1729 1729
                     s->mv_dir = MV_DIR_FORWARD;
1730 1730
                     s->mb_intra= 0;
1731 1731
                     motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0];
1732 1732
                     motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1];
1733
-                }else if(mb_type&MB_TYPE_DIRECT){
1734
-                    int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
1733
+                    break;
1734
+                case MB_TYPE_DIRECT:
1735 1735
                     s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
1736 1736
                     s->mb_intra= 0;
1737
-                    motion_x=0;
1738
-                    motion_y=0;
1739
-                    s->mv[0][0][0] = 0;
1740
-                    s->mv[0][0][1] = 0;
1741
-                    s->mv[1][0][0] = 0;
1742
-                    s->mv[1][0][1] = 0;
1743
-                }else if(mb_type&MB_TYPE_BIDIR){
1744
-                    int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
1737
+                    motion_x=s->b_direct_mv_table[xy][0];
1738
+                    motion_y=s->b_direct_mv_table[xy][1];
1739
+                    s->mv[0][0][0] = s->b_direct_forw_mv_table[xy][0];
1740
+                    s->mv[0][0][1] = s->b_direct_forw_mv_table[xy][1];
1741
+                    s->mv[1][0][0] = s->b_direct_back_mv_table[xy][0];
1742
+                    s->mv[1][0][1] = s->b_direct_back_mv_table[xy][1];
1743
+                    break;
1744
+                case MB_TYPE_BIDIR:
1745 1745
                     s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1746 1746
                     s->mb_intra= 0;
1747 1747
                     motion_x=0;
... ...
@@ -1750,25 +1846,31 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1750 1750
                     s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
1751 1751
                     s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
1752 1752
                     s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
1753
-                }else if(mb_type&MB_TYPE_BACKWARD){
1754
-                    int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
1753
+                    break;
1754
+                case MB_TYPE_BACKWARD:
1755 1755
                     s->mv_dir = MV_DIR_BACKWARD;
1756 1756
                     s->mb_intra= 0;
1757 1757
                     motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0];
1758 1758
                     motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1];
1759
-                }else if(mb_type&MB_TYPE_FORWARD){
1760
-                    int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
1759
+                    break;
1760
+                case MB_TYPE_FORWARD:
1761 1761
                     s->mv_dir = MV_DIR_FORWARD;
1762 1762
                     s->mb_intra= 0;
1763 1763
                     motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0];
1764 1764
                     motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1];
1765 1765
 //                    printf(" %d %d ", motion_x, motion_y);
1766
-                }else{
1766
+                    break;
1767
+                default:
1767 1768
                     motion_x=motion_y=0; //gcc warning fix
1768 1769
                     printf("illegal MB type\n");
1769 1770
                 }
1770 1771
                 encode_mb(s, motion_x, motion_y);
1771 1772
             }
1773
+            /* clean the MV table in IPS frames for direct mode in B frames */
1774
+            if(s->mb_intra /* && I,P,S_TYPE */){
1775
+                s->p_mv_table[xy][0]=0;
1776
+                s->p_mv_table[xy][1]=0;
1777
+            }
1772 1778
 
1773 1779
             MPV_decode_mb(s, s->block);
1774 1780
         }
... ...
@@ -141,7 +141,8 @@ typedef struct MpegEncContext {
141 141
     INT16 (*b_direct_forw_mv_table)[2];/* MV table (1MV per MB) direct mode b-frame encoding */
142 142
     INT16 (*b_direct_back_mv_table)[2];/* MV table (1MV per MB) direct mode b-frame encoding */
143 143
     INT16 (*b_direct_mv_table)[2];     /* MV table (1MV per MB) direct mode b-frame encoding */
144
-    int me_method;          /* ME algorithm */
144
+    int me_method;                     /* ME algorithm */
145
+    uint8_t *me_scratchpad;            /* data area for the me algo, so that the ME doesnt need to malloc/free */
145 146
     int mv_dir;
146 147
 #define MV_DIR_BACKWARD  1
147 148
 #define MV_DIR_FORWARD   2
... ...
@@ -164,7 +165,8 @@ typedef struct MpegEncContext {
164 164
     UINT8 *fcode_tab; /* smallest fcode needed for each MV */
165 165
 
166 166
     int has_b_frames;
167
-    int no_rounding; /* apply no rounding to motion compensation (MPEG4, msmpeg4, ...) */
167
+    int no_rounding; /* apply no rounding to motion compensation (MPEG4, msmpeg4, ...) 
168
+                        for b-frames rounding mode is allways 0 */
168 169
 
169 170
     /* macroblock layer */
170 171
     int mb_x, mb_y;
... ...
@@ -335,9 +337,7 @@ typedef struct MpegEncContext {
335 335
     UINT32 mb_line_avgsize;
336 336
     
337 337
     DCTELEM (*block)[64]; /* points to one of the following blocks */
338
-    DCTELEM intra_block[6][64] __align8;
339
-    DCTELEM inter_block[6][64] __align8;
340
-    DCTELEM inter4v_block[6][64] __align8;
338
+    DCTELEM blocks[2][6][64] __align8; // for HQ mode we need to keep the best block
341 339
     void (*dct_unquantize_mpeg1)(struct MpegEncContext *s, 
342 340
                            DCTELEM *block, int n, int qscale);
343 341
     void (*dct_unquantize_mpeg2)(struct MpegEncContext *s, 
... ...
@@ -421,6 +421,7 @@ INT16 *h263_pred_motion(MpegEncContext * s, int block,
421 421
                         int *px, int *py);
422 422
 void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, 
423 423
                    int dir);
424
+void ff_set_mpeg4_time(MpegEncContext * s, int picture_number);
424 425
 void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
425 426
 void h263_encode_init(MpegEncContext *s);
426 427