Browse code

* preAlpha DV encoding support -- there's still a truckload of work to do, but it least people can try it out and share ideas. Please don't hesitate to give it a spin:

$ ffmpeg -i file.avi file.dv

is all you need.

* fix for a deallocation bug in DV muxer

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

Roman Shaposhnik authored on 2003/10/02 08:34:46
Showing 4 changed files
... ...
@@ -1,4 +1,5 @@
1 1
 version <next>:
2
+- DV encoder, DV muxer
2 3
 - Microsoft RLE video decoder
3 4
 - Microsoft Video-1 decoder
4 5
 - Apple Video (RPZA) decoder
... ...
@@ -618,7 +618,7 @@ library:
618 618
 @item MPEG4            @tab X @tab  X 
619 619
 @tab MPEG4 is a variant of Quicktime
620 620
 @item Raw MPEG4 video  @tab  X @tab  X 
621
-@item DV               @tab  @tab X
621
+@item DV               @tab  X @tab  X
622 622
 @item 4xm              @tab    @tab X
623 623
 @tab 4X Technologies format, used in some games
624 624
 @item Playstation STR  @tab    @tab X
... ...
@@ -668,7 +668,7 @@ following image formats are supported:
668 668
 @item WMV8                   @tab  X  @tab  X @tab Not completely working
669 669
 @item H263(+)                @tab  X  @tab  X @tab Also known as Real Video 1.0
670 670
 @item MJPEG                  @tab  X  @tab  X 
671
-@item DV                     @tab     @tab  X 
671
+@item DV                     @tab  X  @tab  X 
672 672
 @item Huff YUV               @tab  X  @tab  X
673 673
 @item Asus v1                @tab  X  @tab  X @tab fourcc: ASV1
674 674
 @item Asus v2                @tab  X  @tab  X @tab fourcc: ASV2
... ...
@@ -2,6 +2,12 @@
2 2
  * DV decoder
3 3
  * Copyright (c) 2002 Fabrice Bellard.
4 4
  *
5
+ * DV encoder 
6
+ * Copyright (c) 2003 Roman Shaposhnik.
7
+ *
8
+ * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
9
+ * of DV technical info.
10
+ *
5 11
  * This library is free software; you can redistribute it and/or
6 12
  * modify it under the terms of the GNU Lesser General Public
7 13
  * License as published by the Free Software Foundation; either
... ...
@@ -19,7 +25,7 @@
19 19
 
20 20
 /**
21 21
  * @file dv.c
22
- * DV decoder.
22
+ * DV codec.
23 23
  */
24 24
 #include "avcodec.h"
25 25
 #include "dsputil.h"
... ...
@@ -72,7 +78,7 @@ static void dv_build_unquantize_tables(DVVideoDecodeContext *s)
72 72
     }
73 73
 }
74 74
 
75
-static int dvvideo_decode_init(AVCodecContext *avctx)
75
+static int dvvideo_init(AVCodecContext *avctx)
76 76
 {
77 77
     DVVideoDecodeContext *s = avctx->priv_data;
78 78
     MpegEncContext s2;
... ...
@@ -140,6 +146,10 @@ static int dvvideo_decode_init(AVCodecContext *avctx)
140 140
     /* XXX: do it only for constant case */
141 141
     dv_build_unquantize_tables(s);
142 142
 
143
+    /* FIXME: I really don't think this should be here */
144
+    if (dv_codec_profile(avctx))
145
+	avctx->pix_fmt = dv_codec_profile(avctx)->pix_fmt; 
146
+    
143 147
     return 0;
144 148
 }
145 149
 
... ...
@@ -368,6 +378,9 @@ static inline void dv_decode_video_segment(DVVideoDecodeContext *s,
368 368
             mb->pos = 0;
369 369
             mb->partial_bit_count = 0;
370 370
 
371
+#ifdef VLC_DEBUG
372
+            printf("MB block: %d, %d ", mb_index, j);
373
+#endif
371 374
             dv_decode_ac(s, mb, block, last_index);
372 375
 
373 376
             /* write the remaining bits  in a new buffer only if the
... ...
@@ -391,7 +404,7 @@ static inline void dv_decode_video_segment(DVVideoDecodeContext *s,
391 391
 
392 392
         /* pass 2 : we can do it just after */
393 393
 #ifdef VLC_DEBUG
394
-        printf("***pass 2 size=%d\n", mb_bit_count);
394
+        printf("***pass 2 size=%d MB#=%d\n", mb_bit_count, mb_index);
395 395
 #endif
396 396
         block = block1;
397 397
         mb = mb1;
... ...
@@ -501,6 +514,317 @@ static inline void dv_decode_video_segment(DVVideoDecodeContext *s,
501 501
     }
502 502
 }
503 503
 
504
+/* Converts run and level (where level != 0) pair into vlc, returning bit size */
505
+static inline int dv_rl2vlc(int run, int l, uint32_t* vlc)
506
+{
507
+    int sign = l >> 8;
508
+    int level = (l ^ sign) - sign;
509
+    int size;
510
+    
511
+    sign = (sign & 1);
512
+
513
+    if (run < 15 && level < 23 && dv_vlc_codes[run][level] != -1) {
514
+        *vlc = (dv_vlc_bits[dv_vlc_codes[run][level]] << 1) | sign; 
515
+	size = dv_vlc_len[dv_vlc_codes[run][level]] + 1;
516
+    }
517
+    else { 
518
+	if (level < 23) {
519
+	    *vlc = (dv_vlc_bits[dv_vlc_codes[0][level]] << 1) | sign; 
520
+	    size = dv_vlc_len[dv_vlc_codes[0][level]] + 1;
521
+	} else {
522
+	    *vlc = 0xfe00 | (level << 1) | sign;
523
+	    size = 16;
524
+	}
525
+
526
+	switch(run) {
527
+	case 0:
528
+	    break;
529
+	case 1:
530
+	case 2:
531
+	    *vlc |= ((0x7ce | (run - 1)) << size);
532
+	    size += 11;
533
+	    break;
534
+	case 3:
535
+	case 4:
536
+	case 5:
537
+	case 6:
538
+	    *vlc |= ((0xfac | (run - 3)) << size);
539
+	    size += 12;
540
+	    break;
541
+	default:
542
+	    *vlc |= ((0x1f80 | (run - 1)) << size);
543
+	    size += 13;
544
+	    break;
545
+	}
546
+    }
547
+    
548
+    return size;
549
+}
550
+
551
+typedef struct EncBlockInfo {
552
+    int qno;
553
+    int cno;
554
+    int dct_mode;
555
+    int block_size;
556
+    DCTELEM *mb;
557
+    PutBitContext pb;
558
+} EncBlockInfo;
559
+
560
+static inline int dv_bits_left(EncBlockInfo* bi)
561
+{
562
+    return (bi->block_size - get_bit_count(&bi->pb));
563
+}
564
+
565
+static inline void dv_encode_ac(EncBlockInfo* bi, PutBitContext* heap)
566
+{
567
+    int i, level, size, run = 0;
568
+    uint32_t vlc;
569
+    PutBitContext* cpb = &bi->pb;
570
+    
571
+    for (i=1; i<64; i++) {
572
+       level = bi->mb[ff_zigzag_direct[i]] / 
573
+               (1<<(dv_quant_shifts[bi->qno + dv_quant_offset[bi->cno]]
574
+			       [dv_88_areas[ff_zigzag_direct[i]]] + 4 + (bi->cno == 3)));
575
+       if (level != 0) {
576
+	   size = dv_rl2vlc(run, level, &vlc);
577
+put_vlc:
578
+
579
+#ifdef VLC_DEBUG
580
+           printf(" %3d:%3d", run, level);
581
+#endif
582
+	   if (cpb == &bi->pb && size > dv_bits_left(bi)) {
583
+	       size -= dv_bits_left(bi);
584
+	       put_bits(cpb, dv_bits_left(bi), vlc >> size);
585
+	       vlc = vlc & ((1<<size)-1);
586
+	       cpb = heap;
587
+	   }
588
+	   put_bits(cpb, size, vlc);
589
+	   run = 0;
590
+       } else
591
+	   run++;
592
+    }
593
+   
594
+    if (i == 64) {
595
+        size = 4; vlc = 6; /* End Of Block stamp */
596
+	goto put_vlc;
597
+    }
598
+}
599
+
600
+static inline void dv_redistr_bits(EncBlockInfo* bi, int count, uint8_t* extra_data, int extra_bits, PutBitContext* heap)
601
+{
602
+    int i;
603
+    GetBitContext gb;
604
+    
605
+    init_get_bits(&gb, extra_data, extra_bits);
606
+    
607
+    for (i=0; i<count; i++) {
608
+       int bits_left = dv_bits_left(bi);
609
+#ifdef VLC_DEBUG
610
+       if (bits_left)
611
+           printf("------------> inserting %d bytes in %d:%d\n", bits_left, i/6, i%6);
612
+#endif
613
+       if (bits_left > extra_bits) {
614
+           bit_copy(&bi->pb, &gb, extra_bits); 
615
+	   extra_bits = 0;
616
+	   break;
617
+       } else
618
+           bit_copy(&bi->pb, &gb, bits_left);
619
+	   
620
+       extra_bits -= bits_left;
621
+       bi++;
622
+    }
623
+    
624
+    if (extra_bits > 0 && heap)
625
+	bit_copy(heap, &gb, extra_bits);
626
+}
627
+
628
+static inline void dv_set_class_number(EncBlockInfo* bi, int j)
629
+{
630
+    int i, max_ac = 0;
631
+
632
+    for (i=1; i<64; i++) {
633
+       int ac = abs(bi->mb[ff_zigzag_direct[i]]) / 4;
634
+       if (max_ac < ac)
635
+           max_ac = ac;
636
+    }
637
+    if (max_ac < 12)
638
+        bi->cno = j;
639
+    else if (max_ac < 24)
640
+        bi->cno = j + 1;
641
+    else if (max_ac < 36)
642
+        bi->cno = j + 2;
643
+    else
644
+        bi->cno = j + 3;
645
+    
646
+    if (bi->cno > 3)
647
+        bi->cno = 3;
648
+}
649
+
650
+/*
651
+ * This is a very rough initial implementaion. The performance is
652
+ * horrible and some features are missing, mainly 2-4-8 DCT encoding.
653
+ * The weighting is missing as well, but it's missing from the decoding
654
+ * step also -- so at least we're on the same page with decoder ;-)
655
+ */
656
+static inline void dv_encode_video_segment(DVVideoDecodeContext *s, 
657
+                                           uint8_t *dif, 
658
+                                           const uint16_t *mb_pos_ptr)
659
+{
660
+    int mb_index, i, j, v;
661
+    int mb_x, mb_y, c_offset, linesize; 
662
+    uint8_t*  y_ptr;
663
+    uint8_t*  data;
664
+    int       do_edge_wrap;
665
+    DCTELEM  *block;
666
+    EncBlockInfo  enc_blks[5*6];
667
+    EncBlockInfo* enc_blk;
668
+    int       free_vs_bits;
669
+    int extra_bits;
670
+    PutBitContext extra_vs;
671
+    uint8_t   extra_vs_data[5*6*128];
672
+    uint8_t   extra_mb_data[6*128];
673
+
674
+    int       QNO = 15;
675
+   
676
+    /* Stage 1 -- doing DCT on 5 MBs */
677
+    block = &s->block[0][0];
678
+    for(mb_index = 0; mb_index < 5; mb_index++) {
679
+        v = *mb_pos_ptr++;
680
+        mb_x = v & 0xff;
681
+        mb_y = v >> 8;
682
+        y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8);
683
+	c_offset = (s->sys->pix_fmt == PIX_FMT_YUV411P) ?
684
+	           ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8)) :
685
+		   (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8));
686
+	do_edge_wrap = 0;
687
+        for(j = 0;j < 6; j++) {
688
+            if (j < 4) {  /* Four Y blocks */
689
+		/* NOTE: at end of line, the macroblock is handled as 420 */
690
+		if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {
691
+                    data = y_ptr + (j * 8);
692
+                } else {
693
+                    data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]);
694
+                }
695
+		linesize = s->picture.linesize[0];
696
+            } else {      /* Cr and Cb blocks */
697
+	        /* don't ask Fabrice why they inverted Cb and Cr ! */
698
+	        data = s->picture.data[6 - j] + c_offset;
699
+		linesize = s->picture.linesize[6 - j];
700
+		if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8))
701
+		    do_edge_wrap = 1;
702
+	    }	
703
+            
704
+	    /* Everything is set up -- now just copy data -> DCT block */
705
+	    if (do_edge_wrap) {  /* Edge wrap copy: 4x16 -> 8x8 */
706
+		uint8_t* d;
707
+		DCTELEM *b = block;
708
+	        for (i=0;i<8;i++) {
709
+		   d = data + 8 * linesize;
710
+		   b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3];
711
+                   b[4] =    d[0]; b[5] =    d[1]; b[6] =    d[2]; b[7] =    d[3];
712
+		   data += linesize;
713
+		   b += 8;
714
+		}
715
+	    } else {             /* Simple copy: 8x8 -> 8x8 */
716
+	        s->get_pixels(block, data, linesize);
717
+	    }
718
+            
719
+	    s->fdct(block);
720
+	    
721
+	    block += 64;
722
+        }
723
+    }
724
+
725
+    /* Stage 2 -- setup for encoding phase */
726
+    enc_blk = &enc_blks[0];
727
+    block = &s->block[0][0];
728
+    for (i=0; i<5; i++) {
729
+       for (j=0; j<6; j++) {
730
+	  enc_blk->mb = block;
731
+	  enc_blk->dct_mode = 0;
732
+	  enc_blk->block_size = block_sizes[j];
733
+	  
734
+	  dv_set_class_number(enc_blk, j/4*(j%2));
735
+	  
736
+	  block += 64;
737
+	  enc_blk++;
738
+       }
739
+    }
740
+   
741
+    /* Stage 3 -- encoding by trial-and-error */
742
+encode_vs:
743
+    enc_blk = &enc_blks[0];
744
+    for (i=0; i<5; i++) {
745
+       uint8_t* p = dif + i*80 + 4;
746
+       for (j=0; j<6; j++) {
747
+          enc_blk->qno = QNO;
748
+	  init_put_bits(&enc_blk->pb, p, block_sizes[j]/8, NULL, NULL);
749
+	  enc_blk++;
750
+	  p += block_sizes[j]/8;
751
+       }
752
+    }
753
+
754
+    init_put_bits(&extra_vs, extra_vs_data, sizeof(extra_vs_data), NULL, NULL);
755
+    free_vs_bits = 0;
756
+    enc_blk = &enc_blks[0];
757
+    for (i=0; i<5; i++) {
758
+       PutBitContext extra_mb;
759
+       EncBlockInfo* enc_blk2 = enc_blk;
760
+       int free_mb_bits = 0;
761
+
762
+       init_put_bits(&extra_mb, extra_mb_data, sizeof(extra_mb_data), NULL, NULL);
763
+       dif[i*80 + 3] = enc_blk->qno;
764
+       
765
+       for (j=0; j<6; j++) {
766
+	  uint16_t dc = ((enc_blk->mb[0] >> 3) - 1024) >> 2;
767
+
768
+	  put_bits(&enc_blk->pb, 9, dc);
769
+	  put_bits(&enc_blk->pb, 1, enc_blk->dct_mode);
770
+	  put_bits(&enc_blk->pb, 2, enc_blk->cno);
771
+
772
+#ifdef VLC_DEBUG
773
+          printf("[%d, %d]: ", i, j);
774
+#endif
775
+	  dv_encode_ac(enc_blk, &extra_mb);
776
+#ifdef VLC_DEBUG
777
+          printf("\n");
778
+#endif
779
+	  
780
+	  free_mb_bits += dv_bits_left(enc_blk);
781
+	  enc_blk++;
782
+       }
783
+       
784
+       /* We can't flush extra_mb just yet -- since it'll round up bit number */
785
+       extra_bits = get_bit_count(&extra_mb);
786
+       if (free_mb_bits > extra_bits)
787
+           free_vs_bits += free_mb_bits - extra_bits;
788
+    
789
+       if (extra_bits) {  /* FIXME: speed up things when free_mb_bits == 0 */
790
+           flush_put_bits(&extra_mb);
791
+           dv_redistr_bits(enc_blk2, 6, extra_mb_data, extra_bits, &extra_vs);
792
+       }
793
+    }
794
+    
795
+    /* We can't flush extra_mb just yet -- since it'll round up bit number */
796
+    extra_bits = get_bit_count(&extra_vs);
797
+    if (extra_bits > free_vs_bits && QNO) { /* FIXME: very crude trial-and-error */
798
+        QNO--;
799
+	goto encode_vs;
800
+    }
801
+    
802
+    if (extra_bits) {
803
+        flush_put_bits(&extra_vs);
804
+        dv_redistr_bits(&enc_blks[0], 5*6, extra_vs_data, extra_bits, NULL);
805
+    }
806
+
807
+    for (i=0; i<6*5; i++) {
808
+       flush_put_bits(&enc_blks[i].pb);
809
+#ifdef VLC_DEBUG
810
+       printf("[%d:%d] qno=%d cno=%d\n", i/6, i%6, enc_blks[i].qno, enc_blks[i].cno);
811
+#endif
812
+    }
813
+}
814
+
504 815
 /* NOTE: exactly one frame must be given (120000 bytes for NTSC,
505 816
    144000 bytes for PAL) */
506 817
 static int dvvideo_decode_frame(AVCodecContext *avctx, 
... ...
@@ -535,6 +859,9 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
535 535
             if ((vs % 3) == 0)
536 536
 	        buf += 80; /* skip audio block */
537 537
             
538
+#ifdef VLC_DEBUG
539
+            printf("********************* %d, %d **********************\n", ds, vs);
540
+#endif
538 541
 	    dv_decode_video_segment(s, buf, mb_pos_ptr);
539 542
             buf += 5 * 80;
540 543
             mb_pos_ptr += 5;
... ...
@@ -550,10 +877,45 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
550 550
     return s->sys->frame_size;
551 551
 }
552 552
 
553
-static int dvvideo_decode_end(AVCodecContext *avctx)
553
+static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, 
554
+                                void *data)
554 555
 {
555
-    avcodec_default_free_buffers(avctx);    
556
+    DVVideoDecodeContext *s = c->priv_data;
557
+    const uint16_t *mb_pos_ptr;
558
+    int ds, vs;
559
+
560
+    s->sys = dv_codec_profile(c);
561
+    if (!s->sys)
562
+	return -1;
563
+    
564
+    c->pix_fmt = s->sys->pix_fmt;
565
+    s->picture = *((AVFrame *)data);
566
+
567
+    /* for each DIF segment */
568
+    mb_pos_ptr = s->sys->video_place;
569
+    for (ds = 0; ds < s->sys->difseg_size; ds++) {
570
+        buf += 6 * 80; /* skip DIF segment header */
571
+        
572
+        for(vs = 0; vs < 27; vs++) {
573
+            if ((vs % 3) == 0)
574
+	        buf += 80; /* skip audio block */
575
+
576
+#ifdef VLC_DEBUG
577
+            printf("********************* %d, %d **********************\n", ds, vs);
578
+#endif
579
+	    dv_encode_video_segment(s, buf, mb_pos_ptr);
580
+            buf += 5 * 80;
581
+            mb_pos_ptr += 5;
582
+        }
583
+    }
556 584
 
585
+    emms_c();
586
+    return s->sys->frame_size;
587
+}
588
+
589
+static int dvvideo_end(AVCodecContext *avctx)
590
+{
591
+    avcodec_default_free_buffers(avctx);    
557 592
     return 0;
558 593
 }
559 594
 
... ...
@@ -562,9 +924,9 @@ AVCodec dvvideo_decoder = {
562 562
     CODEC_TYPE_VIDEO,
563 563
     CODEC_ID_DVVIDEO,
564 564
     sizeof(DVVideoDecodeContext),
565
-    dvvideo_decode_init,
566
-    NULL,
567
-    dvvideo_decode_end,
565
+    dvvideo_init,
566
+    dvvideo_encode_frame,
567
+    dvvideo_end,
568 568
     dvvideo_decode_frame,
569 569
     CODEC_CAP_DR1,
570 570
     NULL
... ...
@@ -678,7 +678,6 @@ bail_out:
678 678
 void dv_delete_mux(DVMuxContext *c)
679 679
 {    
680 680
     fifo_free(&c->audio_data);
681
-    av_free(c);
682 681
 }
683 682
 
684 683
 DVDemuxContext* dv_init_demux(AVFormatContext *s, int vid, int aid)