Browse code

mpeg4 interlaced decoding support (not completly implemented/tested due to lack of samples)

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

Michael Niedermayer authored on 2002/08/28 01:28:19
Showing 2 changed files
... ...
@@ -1746,6 +1746,8 @@ void h263_decode_init_vlc(MpegEncContext *s)
1746 1746
                  &mb_type_b_tab[0][1], 2, 1,
1747 1747
                  &mb_type_b_tab[0][0], 2, 1);
1748 1748
     }
1749
+
1750
+    s->progressive_sequence=1; // set to most likely for the case of incomplete headers
1749 1751
 }
1750 1752
 
1751 1753
 int h263_decode_gob_header(MpegEncContext *s)
... ...
@@ -2426,7 +2428,37 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s,
2426 2426
 
2427 2427
     return 0;
2428 2428
 }
2429
+#if 0
2430
+static inline void decode_interlaced_info(MpegEncContext *s, int cbp, int mb_type){
2431
+    s->mv_type= 0;            
2432
+    if(!s->progressive_sequence){
2433
+        if(cbp || s->mb_intra)
2434
+            s->interlaced_dct= get_bits1(&s->gb);
2435
+        
2436
+        if(!s->mb_intra){
2437
+            if(   s->pict_type==P_TYPE //FIXME check that 4MV is forbidden
2438
+               || (s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && !s->mcsel)
2439
+               || (s->pict_type==B_TYPE && mb_type!=0) ){
2429 2440
 
2441
+                if(get_bits1(&s->gb)){
2442
+                    s->mv_type= MV_TYPE_FIELD;
2443
+
2444
+                    if(   s->pict_type==P_TYPE
2445
+                       || (s->pict_type==B_TYPE && mb_type!=2)){
2446
+                        s->field_select[0][0]= get_bits1(&s->gb);
2447
+                        s->field_select[0][1]= get_bits1(&s->gb);
2448
+                    }
2449
+                    if(s->pict_type==B_TYPE && mb_type!=3){
2450
+                        s->field_select[1][0]= get_bits1(&s->gb);
2451
+                        s->field_select[1][1]= get_bits1(&s->gb);
2452
+                    }
2453
+                }else
2454
+                    s->mv_type= 0;            
2455
+            }
2456
+        }   
2457
+    }
2458
+}
2459
+#endif
2430 2460
 
2431 2461
 int h263_decode_mb(MpegEncContext *s,
2432 2462
                    DCTELEM block[6][64])
... ...
@@ -2507,55 +2539,75 @@ int h263_decode_mb(MpegEncContext *s,
2507 2507
                 s->qscale = 31;
2508 2508
             h263_dc_scale(s);
2509 2509
         }
2510
+        if((!s->progressive_sequence) && (cbp || s->workaround_bugs==2))
2511
+            s->interlaced_dct= get_bits1(&s->gb);
2512
+        
2510 2513
         s->mv_dir = MV_DIR_FORWARD;
2511 2514
         if ((cbpc & 16) == 0) {
2512
-            PRINT_MB_TYPE("P");
2513
-            /* 16x16 motion prediction */
2514
-            s->mv_type = MV_TYPE_16X16;
2515
-            h263_pred_motion(s, 0, &pred_x, &pred_y);
2516
-            if (s->umvplus_dec)
2517
-               mx = h263p_decode_umotion(s, pred_x);
2518
-            else if(!s->mcsel)
2519
-               mx = h263_decode_motion(s, pred_x, s->f_code);
2520
-            else {
2521
-               const int a= s->sprite_warping_accuracy;
2515
+            if(s->mcsel){
2516
+                const int a= s->sprite_warping_accuracy;
2517
+                PRINT_MB_TYPE("G");
2518
+                /* 16x16 global motion prediction */
2519
+                s->mv_type = MV_TYPE_16X16;
2522 2520
 //        int l = (1 << (s->f_code - 1)) * 32;
2523 2521
                 if(s->divx_version==500 && s->divx_build==413){
2524 2522
                     mx = s->sprite_offset[0][0] / (1<<(a-s->quarter_sample));
2523
+                    my = s->sprite_offset[0][1] / (1<<(a-s->quarter_sample));
2525 2524
                 }else{
2526 2525
                     mx = RSHIFT(s->sprite_offset[0][0], a-s->quarter_sample);
2526
+                    my = RSHIFT(s->sprite_offset[0][1], a-s->quarter_sample);
2527 2527
                 }
2528
-//        if (mx < -l) mx= -l, printf("C");
2529
-//        else if (mx >= l) mx= l-1, printf("C");
2530
-            }
2531
-            if (mx >= 0xffff)
2532
-                return -1;
2533
-            
2534
-            if (s->umvplus_dec)
2535
-               my = h263p_decode_umotion(s, pred_y);
2536
-            else if(!s->mcsel)
2537
-               my = h263_decode_motion(s, pred_y, s->f_code);
2538
-            else{
2539
-               const int a= s->sprite_warping_accuracy;
2540 2528
 //       int l = (1 << (s->f_code - 1)) * 32;
2541
-                if(s->divx_version==500 && s->divx_build==413){
2542
-                    my = s->sprite_offset[0][1] / (1<<(a-s->quarter_sample));
2543
-                }else{
2544
-                    my = RSHIFT(s->sprite_offset[0][1], a-s->quarter_sample);
2529
+                s->mv[0][0][0] = mx;
2530
+                s->mv[0][0][1] = my;
2531
+            }else if((!s->progressive_sequence) && get_bits1(&s->gb)){
2532
+                PRINT_MB_TYPE("f");
2533
+                /* 16x8 field motion prediction */
2534
+                s->mv_type= MV_TYPE_FIELD;
2535
+
2536
+                s->field_select[0][0]= get_bits1(&s->gb);
2537
+                s->field_select[0][1]= get_bits1(&s->gb);
2538
+
2539
+                h263_pred_motion(s, 0, &pred_x, &pred_y);
2540
+                
2541
+                for(i=0; i<2; i++){
2542
+                    mx = h263_decode_motion(s, pred_x, s->f_code);
2543
+                    if (mx >= 0xffff)
2544
+                        return -1;
2545
+            
2546
+                    my = h263_decode_motion(s, pred_y/2, s->f_code);
2547
+                    if (my >= 0xffff)
2548
+                        return -1;
2549
+
2550
+                    s->mv[0][i][0] = mx;
2551
+                    s->mv[0][i][1] = my*2;
2545 2552
                 }
2546
-//       if (my < -l) my= -l, printf("C");
2547
-//       else if (my >= l) my= l-1, printf("C");
2553
+            }else{
2554
+                PRINT_MB_TYPE("P");
2555
+                /* 16x16 motion prediction */
2556
+                s->mv_type = MV_TYPE_16X16;
2557
+                h263_pred_motion(s, 0, &pred_x, &pred_y);
2558
+                if (s->umvplus_dec)
2559
+                   mx = h263p_decode_umotion(s, pred_x);
2560
+                else
2561
+                   mx = h263_decode_motion(s, pred_x, s->f_code);
2562
+            
2563
+                if (mx >= 0xffff)
2564
+                    return -1;
2565
+            
2566
+                if (s->umvplus_dec)
2567
+                   my = h263p_decode_umotion(s, pred_y);
2568
+                else
2569
+                   my = h263_decode_motion(s, pred_y, s->f_code);
2570
+            
2571
+                if (my >= 0xffff)
2572
+                    return -1;
2573
+                s->mv[0][0][0] = mx;
2574
+                s->mv[0][0][1] = my;
2575
+
2576
+                if (s->umvplus_dec && (mx - pred_x) == 1 && (my - pred_y) == 1)
2577
+                   skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */                   
2548 2578
             }
2549
-            if (my >= 0xffff)
2550
-                return -1;
2551
-            s->mv[0][0][0] = mx;
2552
-            s->mv[0][0][1] = my;
2553
-            /*fprintf(stderr, "\n MB %d", (s->mb_y * s->mb_width) + s->mb_x);
2554
-            fprintf(stderr, "\n\tmvx: %d\t\tpredx: %d", mx, pred_x);
2555
-            fprintf(stderr, "\n\tmvy: %d\t\tpredy: %d", my, pred_y);*/
2556
-            if (s->umvplus_dec && (mx - pred_x) == 1 && (my - pred_y) == 1)
2557
-               skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
2558
-                           
2559 2579
         } else {
2560 2580
             PRINT_MB_TYPE("4");
2561 2581
             s->mv_type = MV_TYPE_8X8;
... ...
@@ -2614,9 +2666,6 @@ int h263_decode_mb(MpegEncContext *s,
2614 2614
             s->mv[0][0][1] = 0;
2615 2615
             s->mv[1][0][0] = 0;
2616 2616
             s->mv[1][0][1] = 0;
2617
-//FIXME is this correct?
2618
-/*            s->last_mv[0][0][0]=
2619
-            s->last_mv[0][0][1]=0;*/
2620 2617
             PRINT_MB_TYPE("s");
2621 2618
             return 0;
2622 2619
         }
... ...
@@ -2637,6 +2686,7 @@ int h263_decode_mb(MpegEncContext *s,
2637 2637
                     h263_dc_scale(s);
2638 2638
                 }
2639 2639
             }
2640
+//            decode_interlaced_info(s, cbp, mb_type);
2640 2641
         }else{
2641 2642
             mb_type=4; //like 0 but no vectors coded
2642 2643
             cbp=0;
... ...
@@ -2682,6 +2732,7 @@ int h263_decode_mb(MpegEncContext *s,
2682 2682
             s->mv[1][0][0] = 
2683 2683
             s->mv[1][0][1] = 1000;*/
2684 2684
             break;
2685
+//FIXME additional MVs for interlaced stuff
2685 2686
         case 1: 
2686 2687
             s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
2687 2688
             mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code);
... ...
@@ -2741,6 +2792,8 @@ intra:
2741 2741
                 s->qscale = 31;
2742 2742
             h263_dc_scale(s);
2743 2743
         }
2744
+        if(!s->progressive_sequence)
2745
+            s->interlaced_dct= get_bits1(&s->gb);
2744 2746
 
2745 2747
         /* decode each block */
2746 2748
         if (s->h263_pred) {
... ...
@@ -3606,7 +3659,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
3606 3606
                 }
3607 3607
             }
3608 3608
             
3609
-            if(get_bits1(&s->gb)) printf("interlaced not supported\n");   /* interlaced */
3609
+            s->progressive_sequence= get_bits1(&s->gb)^1;
3610 3610
             if(!get_bits1(&s->gb)) printf("OBMC not supported (very likely buggy encoder)\n");   /* OBMC Disable */
3611 3611
             if (vo_ver_id == 1) {
3612 3612
                 s->vol_sprite_usage = get_bits1(&s->gb); /* vol_sprite_usage */
... ...
@@ -3763,11 +3816,6 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
3763 3763
                 printf("This file was encoded with DivX%d Build%d\n", ver, build);
3764 3764
                 if(ver==500 && build==413){
3765 3765
                     printf("WARNING: this version of DivX is not MPEG4 compatible, trying to workaround these bugs...\n");
3766
-#if 0
3767
-                }else{
3768
-                    printf("hmm, i havnt seen that version of divx yet, lets assume they fixed these bugs ...\n"
3769
-                           "using mpeg4 decoder, if it fails contact the developers (of ffmpeg)\n");
3770
-#endif
3771 3766
                 }
3772 3767
             }
3773 3768
         }
... ...
@@ -3851,7 +3899,11 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
3851 3851
          int t;
3852 3852
          t=get_bits(&s->gb, 3); /* intra dc VLC threshold */
3853 3853
 //printf("threshold %d\n", t);
3854
-         //FIXME interlaced specific bits
3854
+         if(!s->progressive_sequence){
3855
+             s->top_field_first= get_bits1(&s->gb);
3856
+             s->alternate_scan= get_bits1(&s->gb);
3857
+//printf("top:%d alt:%d\n", s->top_field_first, s->alternate_scan);
3858
+         }
3855 3859
      }
3856 3860
 
3857 3861
      if(s->pict_type == S_TYPE && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){
... ...
@@ -600,6 +600,7 @@ int MPV_encode_end(AVCodecContext *avctx)
600 600
 }
601 601
 
602 602
 /* draw the edges of width 'w' of an image of size width, height */
603
+//FIXME check that this is ok for mpeg4 interlaced
603 604
 static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w)
604 605
 {
605 606
     UINT8 *ptr, *last_line;
... ...
@@ -1452,18 +1453,25 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
1452 1452
 
1453 1453
     /* update motion predictor, not for B-frames as they need the motion_val from the last P/S-Frame */
1454 1454
     if (s->out_format == FMT_H263 && s->pict_type!=B_TYPE) { //FIXME move into h263.c if possible, format specific stuff shouldnt be here
1455
-        int motion_x, motion_y;
1456 1455
         
1457 1456
         const int wrap = s->block_wrap[0];
1458 1457
         const int xy = s->block_index[0];
1459
-        if (s->mb_intra) {
1460
-            motion_x = 0;
1461
-            motion_y = 0;
1462
-            goto motion_init;
1463
-        } else if (s->mv_type == MV_TYPE_16X16) {
1464
-            motion_x = s->mv[0][0][0];
1465
-            motion_y = s->mv[0][0][1];
1466
-        motion_init:
1458
+        if(s->mv_type == MV_TYPE_8X8){
1459
+            s->non_b_mv4_table[xy]=1;
1460
+        } else {
1461
+            int motion_x, motion_y;
1462
+            if (s->mb_intra) {
1463
+                motion_x = 0;
1464
+                motion_y = 0;
1465
+            } else if (s->mv_type == MV_TYPE_16X16) {
1466
+                motion_x = s->mv[0][0][0];
1467
+                motion_y = s->mv[0][0][1];
1468
+            } else /*if (s->mv_type == MV_TYPE_FIELD)*/ {
1469
+                motion_x = s->mv[0][0][0] + s->mv[0][1][0];
1470
+                motion_y = s->mv[0][0][1] + s->mv[0][1][1];
1471
+                motion_x = (motion_x>>1) | (motion_x&1);
1472
+                motion_y = (motion_y>>1) | (motion_y&1);
1473
+            }
1467 1474
             /* no update if 8X8 because it has been done during parsing */
1468 1475
             s->motion_val[xy][0] = motion_x;
1469 1476
             s->motion_val[xy][1] = motion_y;
... ...
@@ -1474,8 +1482,6 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
1474 1474
             s->motion_val[xy + 1 + wrap][0] = motion_x;
1475 1475
             s->motion_val[xy + 1 + wrap][1] = motion_y;
1476 1476
             s->non_b_mv4_table[xy]=0;
1477
-        } else { /* 8X8 */
1478
-            s->non_b_mv4_table[xy]=1;
1479 1477
         }
1480 1478
     }
1481 1479