Browse code

new motion estimation (epzs) not complete yet but allready pretty good :) unlimited mv search range minor bugfix in the mpeg4 header parser reset picture in gop counter if scene change is detected

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

Michael Niedermayer authored on 2002/03/22 11:21:17
Showing 8 changed files
... ...
@@ -57,6 +57,8 @@ extern int motion_estimation_method;
57 57
 #define ME_FULL   1
58 58
 #define ME_LOG    2
59 59
 #define ME_PHODS  3
60
+#define ME_EPZS   4
61
+#define ME_X1     5
60 62
 
61 63
 /* encoding support */
62 64
 
... ...
@@ -128,6 +128,7 @@ void init_get_bits(GetBitContext *s,
128 128
         s->bit_cnt += 8;
129 129
     }
130 130
 #endif
131
+    s->size= buffer_size;
131 132
 }
132 133
 
133 134
 #ifndef ALT_BITSTREAM_READER
... ...
@@ -197,6 +197,7 @@ typedef struct GetBitContext {
197 197
     int bit_cnt;
198 198
     UINT8 *buf, *buf_ptr, *buf_end;
199 199
 #endif
200
+    int size;
200 201
 } GetBitContext;
201 202
 
202 203
 typedef struct VLC {
... ...
@@ -787,6 +788,24 @@ static inline int av_log2(unsigned int v)
787 787
     return n;
788 788
 }
789 789
 
790
+/* median of 3 */
791
+static inline int mid_pred(int a, int b, int c)
792
+{
793
+    int vmin, vmax;
794
+    vmax = vmin = a;
795
+    if (b < vmin)
796
+        vmin = b;
797
+    else
798
+	vmax = b;
799
+
800
+    if (c < vmin)
801
+        vmin = c;
802
+    else if (c > vmax)
803
+        vmax = c;
804
+
805
+    return a + b + c - vmin - vmax;
806
+}
807
+
790 808
 /* memory */
791 809
 void *av_mallocz(int size);
792 810
 
... ...
@@ -17,6 +17,8 @@
17 17
  * You should have received a copy of the GNU General Public License
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
+ *
21
+ * ac prediction encoding by Michael Niedermayer <michaelni@gmx.at>
20 22
  */
21 23
 #include "common.h"
22 24
 #include "dsputil.h"
... ...
@@ -45,9 +47,11 @@ static int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
45 45
 static inline int mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr);
46 46
 static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n,
47 47
                               int dir);
48
-
49 48
 extern UINT32 inverse[256];
50 49
 
50
+static UINT16 mv_penalty[MAX_FCODE][MAX_MV*2+1];
51
+static UINT8 fcode_tab[MAX_MV*2+1];
52
+
51 53
 int h263_get_picture_format(int width, int height)
52 54
 {
53 55
     int format;
... ...
@@ -524,24 +528,6 @@ void h263_pred_acdc(MpegEncContext * s, INT16 *block, int n)
524 524
         ac_val1[8 + i] = block[block_permute_op(i)];
525 525
 }
526 526
 
527
-
528
-static inline int mid_pred(int a, int b, int c)
529
-{
530
-    int vmin, vmax;
531
-    vmax = vmin = a;
532
-    if (b < vmin)
533
-        vmin = b;
534
-    else
535
-	vmax = b;
536
-
537
-    if (c < vmin)
538
-        vmin = c;
539
-    else if (c > vmax)
540
-        vmax = c;
541
-
542
-    return a + b + c - vmin - vmax;
543
-}
544
-
545 527
 INT16 *h263_pred_motion(MpegEncContext * s, int block, 
546 528
                         int *px, int *py)
547 529
 {
... ...
@@ -648,7 +634,46 @@ static void h263p_encode_umotion(MpegEncContext * s, int val)
648 648
     }
649 649
 }
650 650
 
651
-void h263_encode_init_vlc(MpegEncContext *s)
651
+static void init_mv_penalty_and_fcode(MpegEncContext *s)
652
+{
653
+    int f_code;
654
+    int mv;
655
+    for(f_code=1; f_code<=MAX_FCODE; f_code++){
656
+        for(mv=-MAX_MV; mv<=MAX_MV; mv++){
657
+            int len;
658
+
659
+            if(mv==0) len= mvtab[0][1];
660
+            else{
661
+                int val, bit_size, range, code;
662
+
663
+                bit_size = s->f_code - 1;
664
+                range = 1 << bit_size;
665
+
666
+                val=mv;
667
+                if (val < 0) 
668
+                    val = -val;
669
+                val--;
670
+                code = (val >> bit_size) + 1;
671
+                if(code<33){
672
+                    len= mvtab[code][1] + 1 + bit_size;
673
+                }else{
674
+                    len= mvtab[32][1] + 2 + bit_size;
675
+                }
676
+            }
677
+
678
+            mv_penalty[f_code][mv+MAX_MV]= len;
679
+        }
680
+    }
681
+    
682
+
683
+    for(f_code=MAX_FCODE; f_code>0; f_code--){
684
+        for(mv=-(16<<f_code); mv<(16<<f_code); mv++){
685
+            fcode_tab[mv+MAX_MV]= f_code;
686
+        }
687
+    }
688
+}
689
+
690
+void h263_encode_init(MpegEncContext *s)
652 691
 {
653 692
     static int done = 0;
654 693
 
... ...
@@ -656,7 +681,13 @@ void h263_encode_init_vlc(MpegEncContext *s)
656 656
         done = 1;
657 657
         init_rl(&rl_inter);
658 658
         init_rl(&rl_intra);
659
+
660
+        init_mv_penalty_and_fcode(s);
659 661
     }
662
+    s->mv_penalty= mv_penalty;
663
+    
664
+    // use fcodes >1 only for mpeg4 FIXME
665
+    if(!s->h263_msmpeg4 && s->h263_pred) s->fcode_tab= fcode_tab;
660 666
 }
661 667
 
662 668
 static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
... ...
@@ -2094,9 +2125,8 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
2094 2094
             break;
2095 2095
         }
2096 2096
         state = ((state << 8) | v) & 0xffffff;
2097
-        /* XXX: really detect end of frame */
2098
-        if (state == 0){
2099
-            printf("illegal zero code found\n");
2097
+        if( get_bits_count(&s->gb) > s->gb.size*8){
2098
+            printf("no VOP startcode found\n");
2100 2099
             return -1;
2101 2100
         }
2102 2101
     }
... ...
@@ -2152,6 +2182,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
2152 2152
                 if(width && height){ /* they should be non zero but who knows ... */
2153 2153
                     s->width = width;
2154 2154
                     s->height = height;
2155
+//                    printf("%d %d\n", width, height);
2155 2156
                 }
2156 2157
             }
2157 2158
             
... ...
@@ -16,6 +16,8 @@
16 16
  * You should have received a copy of the GNU General Public License
17 17
  * along with this program; if not, write to the Free Software
18 18
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
+ *
20
+ * new Motion Estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at>
19 21
  */
20 22
 #include <stdlib.h>
21 23
 #include <stdio.h>
... ...
@@ -25,7 +27,8 @@
25 25
 
26 26
 static void halfpel_motion_search(MpegEncContext * s,
27 27
 				  int *mx_ptr, int *my_ptr, int dmin,
28
-				  int xmin, int ymin, int xmax, int ymax);
28
+				  int xmin, int ymin, int xmax, int ymax,
29
+                                  int pred_x, int pred_y);
29 30
 
30 31
 /* config it to test motion vector encoding (send random vectors) */
31 32
 //#define CONFIG_TEST_MV_ENCODE
... ...
@@ -328,67 +331,209 @@ static int phods_motion_search(MpegEncContext * s,
328 328
     return dminy;
329 329
 }
330 330
 
331
+
332
+#define Z_THRESHOLD 256
333
+
334
+#define CHECK_MV(x,y)\
335
+    d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16);\
336
+    d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\
337
+    if(d<dmin){\
338
+        best[0]=x;\
339
+        best[1]=y;\
340
+        dmin=d;\
341
+    }
342
+
343
+#define CHECK_MV_DIR(x,y,new_dir)\
344
+{\
345
+    d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16);\
346
+    d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\
347
+    if(d<dmin){\
348
+        best[0]=x;\
349
+        best[1]=y;\
350
+        dmin=d;\
351
+        next_dir= new_dir;\
352
+    }\
353
+}
354
+
355
+static inline int small_diamond_search(MpegEncContext * s, int *best, int dmin,
356
+                                       UINT8 *new_pic, UINT8 *old_pic, int pic_stride,
357
+                                       int pred_x, int pred_y, UINT16 *mv_penalty, int quant,
358
+                                       int xmin, int ymin, int xmax, int ymax, int shift)
359
+{
360
+    int next_dir=-1;
361
+
362
+    for(;;){
363
+        int d;
364
+        const int dir= next_dir;
365
+        const int x= best[0];
366
+        const int y= best[1];
367
+        next_dir=-1;
368
+
369
+//printf("%d", dir);
370
+        if(dir!=2 && x-1>=xmin) CHECK_MV_DIR(x-1, y  , 0)
371
+        if(dir!=3 && y-1>=ymin) CHECK_MV_DIR(x  , y-1, 1)
372
+        if(dir!=0 && x+1<=xmax) CHECK_MV_DIR(x+1, y  , 2)
373
+        if(dir!=1 && y+1<=ymax) CHECK_MV_DIR(x  , y+1, 3)
374
+
375
+        if(next_dir==-1){
376
+            return dmin;
377
+        }
378
+    }
379
+}
380
+
381
+static int epzs_motion_search(MpegEncContext * s,
382
+                             int *mx_ptr, int *my_ptr,
383
+                             int *px_ptr, int *py_ptr,
384
+                             int xmin, int ymin, int xmax, int ymax)
385
+{
386
+    INT16 P_left[2], P_top[2], P_topright[2], P_last[2];
387
+    static const int off[4]= {2, 1, 1, -1};
388
+    int best[2]={0, 0};
389
+    int d, dmin; 
390
+    UINT8 *new_pic, *old_pic;
391
+    const int pic_stride= s->linesize;
392
+    const int pic_xy= (s->mb_y*pic_stride + s->mb_x)*16;
393
+    const int mot_stride = s->block_wrap[0];
394
+    const int mot_xy = s->block_index[0];
395
+    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
396
+    int quant= s->qscale; // qscale of the prev frame
397
+    int pred_x, pred_y;
398
+    const int shift= 1+s->quarter_sample;
399
+
400
+    new_pic = s->new_picture[0] + pic_xy;
401
+    old_pic = s->last_picture[0] + pic_xy;
402
+
403
+    xmin-=s->mb_x*16;
404
+    xmax-=s->mb_x*16;
405
+    ymin-=s->mb_y*16;
406
+    ymax-=s->mb_y*16;
407
+    
408
+    dmin = pix_abs16x16(new_pic, old_pic, pic_stride, 16);
409
+    if(dmin<Z_THRESHOLD){
410
+        *mx_ptr= 0;
411
+        *my_ptr= 0;
412
+//printf("Z");
413
+        return dmin;
414
+    }
415
+
416
+    P_last[0] = s->motion_val[mot_xy    ][0];
417
+    P_last[1] = s->motion_val[mot_xy    ][1];
418
+    P_left[0] = s->motion_val[mot_xy - 1][0];
419
+    P_left[1] = s->motion_val[mot_xy - 1][1];
420
+    if(P_left[0] > (xmax<<shift)) P_left[0]= (xmax<<shift);
421
+
422
+    /* special case for first line */
423
+    if ((s->mb_y == 0 || s->first_slice_line || s->first_gob_line)) {
424
+        *px_ptr= pred_x = P_left[0];
425
+        *py_ptr= pred_y = P_left[1];
426
+        CHECK_MV(pred_x>>shift, pred_y>>shift)
427
+        if(dmin<Z_THRESHOLD){
428
+            *mx_ptr= pred_x>>shift;
429
+            *my_ptr= pred_y>>shift;
430
+//printf("M");
431
+            return dmin;
432
+        }
433
+    } else {
434
+        P_top     [0] = s->motion_val[mot_xy - mot_stride             ][0];
435
+        P_top     [1] = s->motion_val[mot_xy - mot_stride             ][1];
436
+        P_topright[0] = s->motion_val[mot_xy - mot_stride + off[0]    ][0];
437
+        P_topright[1] = s->motion_val[mot_xy - mot_stride + off[0]    ][1];
438
+        if(P_top     [1] > (ymax<<shift)) P_top     [1]= (ymax<<shift);
439
+        if(P_topright[0] < (xmin<<shift)) P_topright[0]= (xmin<<shift);
440
+        if(P_topright[1] > (ymax<<shift)) P_topright[1]= (ymax<<shift);
441
+
442
+        *px_ptr= pred_x = mid_pred(P_left[0], P_top[0], P_topright[0]);
443
+        *py_ptr= pred_y = mid_pred(P_left[1], P_top[1], P_topright[1]);
444
+        
445
+        CHECK_MV(pred_x>>shift, pred_y>>shift)
446
+        if(dmin<Z_THRESHOLD){
447
+            *mx_ptr= pred_x>>shift;
448
+            *my_ptr= pred_y>>shift;
449
+//printf("M");
450
+            return dmin;
451
+        }
452
+
453
+        CHECK_MV(P_left    [0]>>shift, P_left    [1]>>shift)
454
+        CHECK_MV(P_top     [0]>>shift, P_top     [1]>>shift)
455
+        CHECK_MV(P_topright[0]>>shift, P_topright[1]>>shift)
456
+        CHECK_MV(P_last    [0]>>shift, P_last    [1]>>shift)
457
+    }
458
+
459
+    dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride, 
460
+                               pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift);
461
+    *mx_ptr= best[0];
462
+    *my_ptr= best[1];
463
+
464
+//    printf("%d %d %d \n", best[0], best[1], dmin);
465
+
466
+    return dmin;
467
+}
468
+
469
+#define CHECK_HALF_MV(suffix, x, y) \
470
+    d= pix_abs16x16_ ## suffix(pix, ptr+((x)>>1), s->linesize, 16);\
471
+    d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*quant;\
472
+    if(d<dminh){\
473
+        dminh= d;\
474
+        mx= mx1 + x;\
475
+        my= my1 + y;\
476
+    }
477
+
331 478
 /* The idea would be to make half pel ME after Inter/Intra decision to 
332 479
    save time. */
333
-static void halfpel_motion_search(MpegEncContext * s,
480
+static inline void halfpel_motion_search(MpegEncContext * s,
334 481
 				  int *mx_ptr, int *my_ptr, int dmin,
335
-				  int xmin, int ymin, int xmax, int ymax)
482
+				  int xmin, int ymin, int xmax, int ymax,
483
+                                  int pred_x, int pred_y)
336 484
 {
485
+    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame
486
+    const int quant= s->qscale;
487
+    int pen_x, pen_y;
337 488
     int mx, my, mx1, my1, d, xx, yy, dminh;
338
-    UINT8 *pix;
489
+    UINT8 *pix, *ptr;
339 490
 
340
-    mx = *mx_ptr << 1;
341
-    my = *my_ptr << 1;
491
+    
492
+    mx = *mx_ptr;
493
+    my = *my_ptr;
494
+    ptr = s->last_picture[0] + (my * s->linesize) + mx;
342 495
 
343 496
     xx = 16 * s->mb_x;
344 497
     yy = 16 * s->mb_y;
345
-
498
+    pix =  s->new_picture[0] + (yy * s->linesize) + xx;
499
+    
346 500
     dminh = dmin;
347 501
 
348
-    /* Half pixel search */
349
-    mx1 = mx;
350
-    my1 = my;
351
-
352
-    pix = s->new_picture[0] + (yy * s->linesize) + xx;
502
+    if (mx > xmin && mx < xmax && 
503
+        my > ymin && my < ymax) {
353 504
 
354
-    if ((mx > (xmin << 1)) && mx < (xmax << 1) && 
355
-        (my > (ymin << 1)) && my < (ymax << 1)) {
356
-	    int dx, dy, px, py;
357
-	    UINT8 *ptr;
358
-        for (dy = -1; dy <= 1; dy++) {
359
-            for (dx = -1; dx <= 1; dx++) {
360
-                if (dx != 0 || dy != 0) {
361
-                    px = mx1 + dx;
362
-                    py = my1 + dy;
363
-                    ptr = s->last_picture[0] + ((py >> 1) * s->linesize) + (px >> 1);
364
-                    switch (((py & 1) << 1) | (px & 1)) {
365
-                    default:
366
-                    case 0:
367
-                        d = pix_abs16x16(pix, ptr, s->linesize, 16);
368
-                        break;
369
-                    case 1:
370
-                        d = pix_abs16x16_x2(pix, ptr, s->linesize, 16);
371
-                        break;
372
-                    case 2:
373
-                        d = pix_abs16x16_y2(pix, ptr, s->linesize, 16);
374
-                        break;
375
-                    case 3:
376
-                        d = pix_abs16x16_xy2(pix, ptr, s->linesize, 16);
377
-                        break;
378
-                    }
379
-                    if (d < dminh) {
380
-                        dminh = d;
381
-                        mx = px;
382
-                        my = py;
383
-                    }
384
-                }
385
-            }
505
+        mx= mx1= 2*(mx - xx);
506
+        my= my1= 2*(my - yy);
507
+        if(dmin < Z_THRESHOLD && mx==0 && my==0){
508
+            *mx_ptr = 0;
509
+            *my_ptr = 0;
510
+            return;
386 511
         }
512
+        
513
+        pen_x= pred_x + mx;
514
+        pen_y= pred_y + my;
515
+
516
+        ptr-= s->linesize;
517
+        CHECK_HALF_MV(xy2, -1, -1)
518
+        CHECK_HALF_MV(y2 ,  0, -1)
519
+        CHECK_HALF_MV(xy2, +1, -1)
520
+        
521
+        ptr+= s->linesize;
522
+        CHECK_HALF_MV(x2 , -1,  0)
523
+        CHECK_HALF_MV(x2 , +1,  0)
524
+        CHECK_HALF_MV(xy2, -1, +1)
525
+        CHECK_HALF_MV(y2 ,  0, +1)
526
+        CHECK_HALF_MV(xy2, +1, +1)
527
+    }else{
528
+        mx= 2*(mx - xx);
529
+        my= 2*(my - yy);
387 530
     }
388 531
 
389
-    *mx_ptr = mx - (xx << 1);
390
-    *my_ptr = my - (yy << 1);
391
-    //fprintf(stderr,"half  - MX: %d\tMY: %d\n",*mx_ptr ,*my_ptr);
532
+    *mx_ptr = mx;
533
+    *my_ptr = my;
392 534
 }
393 535
 
394 536
 #ifndef CONFIG_TEST_MV_ENCODE
... ...
@@ -400,6 +545,7 @@ int estimate_motion(MpegEncContext * s,
400 400
     UINT8 *pix, *ppix;
401 401
     int sum, varc, vard, mx, my, range, dmin, xx, yy;
402 402
     int xmin, ymin, xmax, ymax;
403
+    int pred_x=0, pred_y=0;
403 404
     
404 405
     range = 8 * (1 << (s->f_code - 1));
405 406
     /* XXX: temporary kludge to avoid overflow for msmpeg4 */
... ...
@@ -426,7 +572,6 @@ int estimate_motion(MpegEncContext * s,
426 426
         xmax = s->mb_width*16 - 16;
427 427
         ymax = s->mb_height*16 - 16;
428 428
     }
429
-
430 429
     switch(s->full_search) {
431 430
     case ME_ZERO:
432 431
     default:
... ...
@@ -442,8 +587,13 @@ int estimate_motion(MpegEncContext * s,
442 442
     case ME_PHODS:
443 443
 	dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax);
444 444
         break;
445
+    case ME_X1: // just reserving some space for experiments ...
446
+    case ME_EPZS:
447
+	dmin = epzs_motion_search(s, &mx, &my, &pred_x, &pred_y, xmin, ymin, xmax, ymax);
448
+        mx+= s->mb_x*16;
449
+        my+= s->mb_y*16;
450
+        break;
445 451
     }
446
-    emms_c();
447 452
 
448 453
     /* intra / predictive decision */
449 454
     xx = mb_x * 16;
... ...
@@ -470,7 +620,7 @@ int estimate_motion(MpegEncContext * s,
470 470
 #endif
471 471
     if (vard <= 64 || vard < varc) {
472 472
         if (s->full_search != ME_ZERO) {
473
-            halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax);
473
+            halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y);
474 474
         } else {
475 475
             mx -= 16 * s->mb_x;
476 476
             my -= 16 * s->mb_y;
... ...
@@ -66,7 +66,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
66 66
         int n;
67 67
         UINT64 time_code;
68 68
         
69
-        if ((s->picture_number % s->gop_size) == 0) {
69
+        if (s->picture_in_gop_number == 0) {
70 70
             /* mpeg1 header repeated every gop */
71 71
             put_header(s, SEQ_START_CODE);
72 72
             
... ...
@@ -67,6 +67,9 @@ static UINT8 h263_chroma_roundtab[16] = {
67 67
     0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
68 68
 };
69 69
 
70
+static UINT16 default_mv_penalty[MAX_FCODE][MAX_MV*2+1];
71
+static UINT8 default_fcode_tab[MAX_MV*2+1];
72
+
70 73
 /* default motion estimation */
71 74
 int motion_estimation_method = ME_LOG;
72 75
 
... ...
@@ -356,8 +359,24 @@ int MPV_encode_init(AVCodecContext *avctx)
356 356
         return -1;
357 357
     }
358 358
 
359
+    { /* set up some save defaults, some codecs might override them later */
360
+        static int done=0;
361
+        if(!done){
362
+            int i;
363
+            done=1;
364
+            memset(default_mv_penalty, 0, sizeof(UINT16)*MAX_FCODE*(2*MAX_MV+1));
365
+            memset(default_fcode_tab , 0, sizeof(UINT8)*(2*MAX_MV+1));
366
+
367
+            for(i=-16; i<16; i++){
368
+                default_fcode_tab[i + MAX_MV]= 1;
369
+            }
370
+        }
371
+    }
372
+    s->mv_penalty= default_mv_penalty;
373
+    s->fcode_tab= default_fcode_tab;
374
+
359 375
     if (s->out_format == FMT_H263)
360
-        h263_encode_init_vlc(s);
376
+        h263_encode_init(s);
361 377
 
362 378
     s->encoding = 1;
363 379
 
... ...
@@ -375,6 +394,7 @@ int MPV_encode_init(AVCodecContext *avctx)
375 375
     rate_control_init(s);
376 376
 
377 377
     s->picture_number = 0;
378
+    s->picture_in_gop_number = 0;
378 379
     s->fake_picture_number = 0;
379 380
     /* motion detector init */
380 381
     s->f_code = 1;
... ...
@@ -480,9 +500,10 @@ int MPV_encode_picture(AVCodecContext *avctx,
480 480
 
481 481
     if (!s->intra_only) {
482 482
         /* first picture of GOP is intra */
483
-        if ((s->picture_number % s->gop_size) == 0)
483
+        if (s->picture_in_gop_number >= s->gop_size){
484
+            s->picture_in_gop_number=0;
484 485
             s->pict_type = I_TYPE;
485
-        else
486
+        }else
486 487
             s->pict_type = P_TYPE;
487 488
     } else {
488 489
         s->pict_type = I_TYPE;
... ...
@@ -521,6 +542,7 @@ int MPV_encode_picture(AVCodecContext *avctx,
521 521
     
522 522
     MPV_frame_end(s);
523 523
     s->picture_number++;
524
+    s->picture_in_gop_number++;
524 525
 
525 526
     if (s->out_format == FMT_MJPEG)
526 527
         mjpeg_picture_trailer(s);
... ...
@@ -1077,17 +1099,66 @@ static void encode_picture(MpegEncContext *s, int picture_number)
1077 1077
             s->mv_table[1][xy] = motion_y;
1078 1078
         }
1079 1079
     }
1080
+    emms_c();
1080 1081
 
1081 1082
     if(s->avg_mb_var < s->mc_mb_var && s->pict_type != B_TYPE){ //FIXME subtract MV bits
1082 1083
         int i;
1083 1084
         s->pict_type= I_TYPE;
1084
-        for(i=0; i<s->mb_height*s->mb_width; i++){
1085
-            s->mb_type[i] = I_TYPE;
1085
+        s->picture_in_gop_number=0;
1086
+        for(i=0; i<s->mb_num; i++){
1087
+            s->mb_type[i] = 1;
1086 1088
             s->mv_table[0][i] = 0;
1087 1089
             s->mv_table[1][i] = 0;
1088 1090
         }
1089 1091
     }
1090
-        
1092
+
1093
+    /* find best f_code */
1094
+    if(s->pict_type==P_TYPE){
1095
+        int mv_num[8];
1096
+        int i;
1097
+        int loose=0;
1098
+        UINT8 * fcode_tab= s->fcode_tab;
1099
+
1100
+        for(i=0; i<8; i++) mv_num[i]=0;
1101
+
1102
+        for(i=0; i<s->mb_num; i++){
1103
+            if(s->mb_type[i] == 0){
1104
+                mv_num[ fcode_tab[s->mv_table[0][i] + MAX_MV] ]++;
1105
+                mv_num[ fcode_tab[s->mv_table[1][i] + MAX_MV] ]++;
1106
+//printf("%d %d %d\n", s->mv_table[0][i], fcode_tab[s->mv_table[0][i] + MAX_MV], i);
1107
+            }
1108
+//else printf("I");
1109
+        }
1110
+
1111
+        for(i=MAX_FCODE; i>1; i--){
1112
+            loose+= mv_num[i];
1113
+            if(loose > 4) break;
1114
+        }
1115
+        s->f_code= i;
1116
+    }else{
1117
+        s->f_code= 1;
1118
+    }
1119
+//printf("f_code %d ///\n", s->f_code);
1120
+    /* convert MBs with too long MVs to I-Blocks */
1121
+    if(s->pict_type==P_TYPE){
1122
+        int i;
1123
+        const int f_code= s->f_code;
1124
+        UINT8 * fcode_tab= s->fcode_tab;
1125
+
1126
+        for(i=0; i<s->mb_num; i++){
1127
+            if(s->mb_type[i] == 0){
1128
+                if(   fcode_tab[s->mv_table[0][i] + MAX_MV] > f_code
1129
+                   || fcode_tab[s->mv_table[0][i] + MAX_MV] == 0
1130
+                   || fcode_tab[s->mv_table[1][i] + MAX_MV] > f_code
1131
+                   || fcode_tab[s->mv_table[1][i] + MAX_MV] == 0 ){
1132
+                    s->mb_type[i] = 1;
1133
+                    s->mv_table[0][i] = 0;
1134
+                    s->mv_table[1][i] = 0;
1135
+                }
1136
+            }
1137
+        }
1138
+    }
1139
+
1091 1140
 //    printf("%d %d\n", s->avg_mb_var, s->mc_mb_var);
1092 1141
 
1093 1142
     if (!s->fixed_qscale) 
... ...
@@ -34,6 +34,9 @@ enum OutputFormat {
34 34
 #define QMAT_SHIFT_MMX 19
35 35
 #define QMAT_SHIFT 25
36 36
 
37
+#define MAX_FCODE 7
38
+#define MAX_MV 2048
39
+
37 40
 typedef struct Predictor{
38 41
     double coeff;
39 42
     double count;
... ...
@@ -71,7 +74,8 @@ typedef struct MpegEncContext {
71 71
     int context_initialized;
72 72
     int picture_number;
73 73
     int fake_picture_number; /* picture number at the bitstream frame rate */
74
-    int gop_picture_number;  /* index of the first picture of a GOP */
74
+    int gop_picture_number;  /* index of the first picture of a GOP based on fake_pic_num & mpeg1 specific */
75
+    int picture_in_gop_number; /* 0-> first pic in gop, ... */
75 76
     int mb_width, mb_height;
76 77
     int mb_num;                /* number of MBs of a picture */
77 78
     int linesize;              /* line size, in bytes, may be different from width */
... ...
@@ -114,7 +118,7 @@ typedef struct MpegEncContext {
114 114
 #define MV_DIRECT        4 // bidirectional mode where the difference equals the MV of the last P/S/I-Frame (mpeg4)
115 115
     int mv_type;
116 116
 #define MV_TYPE_16X16       0   /* 1 vector for the whole mb */
117
-#define MV_TYPE_8X8         1   /* 4 vectors (h263) */
117
+#define MV_TYPE_8X8         1   /* 4 vectors (h263, mpeg4 4MV) */
118 118
 #define MV_TYPE_16X8        2   /* 2 vectors, one per 16x8 block */ 
119 119
 #define MV_TYPE_FIELD       3   /* 2 vectors, one per field */ 
120 120
 #define MV_TYPE_DMV         4   /* 2 vectors, special mpeg2 Dual Prime Vectors */
... ...
@@ -126,6 +130,8 @@ typedef struct MpegEncContext {
126 126
     int mv[2][4][2];
127 127
     int field_select[2][2];
128 128
     int last_mv[2][2][2];
129
+    UINT16 (*mv_penalty)[MAX_MV*2+1]; /* amount of bits needed to encode a MV, used for ME */
130
+    UINT8 *fcode_tab; /* smallest fcode needed for each MV */
129 131
 
130 132
     int has_b_frames;
131 133
     int no_rounding; /* apply no rounding to motion estimation (MPEG4) */
... ...
@@ -350,7 +356,7 @@ INT16 *h263_pred_motion(MpegEncContext * s, int block,
350 350
 void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, 
351 351
                    int dir);
352 352
 void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
353
-void h263_encode_init_vlc(MpegEncContext *s);
353
+void h263_encode_init(MpegEncContext *s);
354 354
 
355 355
 void h263_decode_init_vlc(MpegEncContext *s);
356 356
 int h263_decode_picture_header(MpegEncContext *s);