Browse code

DV audio decoder by Roman Shaposhnick

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

Fabrice Bellard authored on 2003/01/27 18:21:30
Showing 4 changed files
... ...
@@ -72,7 +72,7 @@ void avcodec_register_all(void)
72 72
     register_avcodec(&rv10_decoder);
73 73
     register_avcodec(&svq1_decoder);
74 74
     register_avcodec(&dvvideo_decoder);
75
-    //    register_avcodec(&dvaudio_decoder);
75
+    register_avcodec(&dvaudio_decoder);
76 76
     register_avcodec(&mjpeg_decoder);
77 77
     register_avcodec(&mjpegb_decoder);
78 78
     register_avcodec(&mp2_decoder);
... ...
@@ -634,7 +634,6 @@ AVCodec dvvideo_decoder = {
634 634
 typedef struct DVAudioDecodeContext {
635 635
     AVCodecContext *avctx;
636 636
     GetBitContext gb;
637
-
638 637
 } DVAudioDecodeContext;
639 638
 
640 639
 static int dvaudio_decode_init(AVCodecContext *avctx)
... ...
@@ -643,13 +642,126 @@ static int dvaudio_decode_init(AVCodecContext *avctx)
643 643
     return 0;
644 644
 }
645 645
 
646
+static UINT16 dv_audio_12to16(UINT16 sample)
647
+{
648
+    UINT16 shift, result;
649
+    
650
+    sample = (sample < 0x800) ? sample : sample | 0xf000;
651
+    shift = (sample & 0xf00) >> 8;
652
+
653
+    if (shift < 0x2 || shift > 0xd) {
654
+	result = sample;
655
+    } else if (shift < 0x8) {
656
+        shift--;
657
+	result = (sample - (256 * shift)) << shift;
658
+    } else {
659
+	shift = 0xe - shift;
660
+	result = ((sample + ((256 * shift) + 1)) << shift) - 1;
661
+    }
662
+
663
+    return result;
664
+}
665
+
646 666
 /* NOTE: exactly one frame must be given (120000 bytes for NTSC,
647
-   144000 bytes for PAL) */
667
+   144000 bytes for PAL) 
668
+
669
+   There's a couple of assumptions being made here:
670
+         1. We don't do any kind of audio error correction. It means,
671
+	    that erroneous samples 0x8000 are being passed upwards.
672
+            Do we need to silence erroneous samples ? Average them ?
673
+	 2. We don't do software emphasis.
674
+	 3. We are not checking for 'speed' argument being valid.
675
+	 4. Audio is always returned as 16bit linear samples: 12bit
676
+	    nonlinear samples are converted into 16bit linear ones.
677
+*/
648 678
 static int dvaudio_decode_frame(AVCodecContext *avctx, 
649 679
                                  void *data, int *data_size,
650 680
                                  UINT8 *buf, int buf_size)
651 681
 {
652
-    //    DVAudioDecodeContext *s = avctx->priv_data;
682
+    DVVideoDecodeContext *s = avctx->priv_data;
683
+    const UINT16 (*unshuffle)[9];
684
+    int smpls, freq, quant, sys, stride, difseg, ad, dp, nb_dif_segs, i;
685
+    UINT16 lc, rc;
686
+    UINT8 *buf_ptr;
687
+    
688
+    /* parse id */
689
+    init_get_bits(&s->gb, &buf[AAUX_OFFSET], 5*8);
690
+    i = get_bits(&s->gb, 8);
691
+    if (i != 0x50) { /* No audio ? */
692
+	*data_size = 0;
693
+	return buf_size;
694
+    }
695
+    
696
+    get_bits(&s->gb, 1); /* 0 - locked audio, 1 - unlocked audio */
697
+    skip_bits(&s->gb, 1);
698
+    smpls = get_bits(&s->gb, 6); /* samples in this frame - min. samples */
699
+
700
+    skip_bits(&s->gb, 8);
701
+
702
+    skip_bits(&s->gb, 2);
703
+    sys = get_bits(&s->gb, 1); /* 0 - 60 fields, 1 = 50 fields */
704
+    skip_bits(&s->gb, 5);
705
+
706
+    get_bits(&s->gb, 1); /* 0 - emphasis on, 1 - emphasis off */
707
+    get_bits(&s->gb, 1); /* 0 - reserved, 1 - emphasis time constant 50/15us */
708
+    freq = get_bits(&s->gb, 3); /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */
709
+    quant = get_bits(&s->gb, 3); /* 0 - 16bit linear, 1 - 12bit nonlinear */
710
+
711
+    if (quant > 1)
712
+	return -1; /* Unsupported quantization */
713
+
714
+    avctx->sample_rate = dv_audio_frequency[freq];
715
+    // What about:
716
+    // avctx->bit_rate = 
717
+    // avctx->frame_size =
718
+   
719
+    *data_size = (dv_audio_min_samples[sys][freq] + smpls) * 
720
+	         avctx->channels * 2;
721
+
722
+    if (sys) {
723
+	nb_dif_segs = 12;
724
+	stride = 108;
725
+	unshuffle = dv_place_audio50;
726
+    } else {
727
+	nb_dif_segs = 10;
728
+	stride = 90;
729
+	unshuffle = dv_place_audio60;
730
+    }
731
+    
732
+    /* for each DIF segment */
733
+    buf_ptr = buf;
734
+    for (difseg = 0; difseg < nb_dif_segs; difseg++) {
735
+         buf_ptr += 6 * 80; /* skip DIF segment header */
736
+         for (ad = 0; ad < 9; ad++) {
737
+              
738
+              for (dp = 8; dp < 80; dp+=2) {
739
+		   if (quant == 0) {  /* 16bit quantization */
740
+		       i = unshuffle[difseg][ad] + (dp - 8)/2 * stride;
741
+		       ((short *)data)[i] = (buf_ptr[dp] << 8) | buf_ptr[dp+1]; 
742
+		   } else {           /* 12bit quantization */
743
+		       if (difseg >= nb_dif_segs/2)
744
+			   goto out;  /* We're not doing 4ch at this time */
745
+		       
746
+		       lc = ((UINT16)buf_ptr[dp] << 4) | 
747
+			    ((UINT16)buf_ptr[dp+2] >> 4);
748
+		       rc = ((UINT16)buf_ptr[dp+1] << 4) |
749
+			    ((UINT16)buf_ptr[dp+2] & 0x0f);
750
+		       lc = dv_audio_12to16(lc);
751
+		       rc = dv_audio_12to16(rc);
752
+
753
+		       i = unshuffle[difseg][ad] + (dp - 8)/3 * stride;
754
+		       ((short *)data)[i] = lc;
755
+		       i = unshuffle[difseg+nb_dif_segs/2][ad] + (dp - 8)/3 * stride;
756
+		       ((short *)data)[i] = rc;
757
+		       ++dp;
758
+		   }
759
+	      }
760
+		
761
+	    buf_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
762
+        }
763
+    }
764
+
765
+out:
653 766
     return buf_size;
654 767
 }
655 768
 
... ...
@@ -18,6 +18,7 @@
18 18
  */
19 19
 
20 20
 #define NB_DV_VLC 409
21
+#define AAUX_OFFSET (80*6 + 80*16*3 + 3)
21 22
 
22 23
 static const UINT16 dv_vlc_bits[409] = {
23 24
  0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016,
... ...
@@ -905,3 +906,41 @@ static const UINT16 dv_place_411[1350] = {
905 905
  0x0834, 0x2320, 0x2f44, 0x3810, 0x1658,
906 906
 };
907 907
 
908
+static const UINT16 dv_place_audio60[10][9] = {
909
+  {  0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */
910
+  {  6, 36, 66, 26, 56, 86, 16, 46, 76 },
911
+  { 12, 42, 72,  2, 32, 62, 22, 52, 82 },
912
+  { 18, 48, 78,  8, 38, 68, 28, 58, 88 },
913
+  { 24, 54, 84, 14, 44, 74,  4, 34, 64 },
914
+  
915
+  {  1, 31, 61, 21, 51, 81, 11, 41, 71 }, /* 2nd channel */
916
+  {  7, 37, 67, 27, 57, 87, 17, 47, 77 },
917
+  { 13, 43, 73,  3, 33, 63, 23, 53, 83 },
918
+  { 19, 49, 79,  9, 39, 69, 29, 59, 89 },
919
+  { 25, 55, 85, 15, 45, 75,  5, 35, 65 },
920
+};
921
+
922
+static const UINT16 dv_place_audio50[12][9] = {
923
+  {   0,  36,  72,  26,  62,  98,  16,  52,  88}, /* 1st channel */
924
+  {   6,  42,  78,  32,  68, 104,  22,  58,  94},
925
+  {  12,  48,  84,   2,  38,  74,  28,  64, 100},
926
+  {  18,  54,  90,   8,  44,  80,  34,  70, 106},
927
+  {  24,  60,  96,  14,  50,  86,   4,  40,  76},  
928
+  {  30,  66, 102,  20,  56,  92,  10,  46,  82},
929
+	
930
+  {   1,  37,  73,  27,  63,  99,  17,  53,  89}, /* 2nd channel */
931
+  {   7,  43,  79,  33,  69, 105,  23,  59,  95},
932
+  {  13,  49,  85,   3,  39,  75,  29,  65, 101},
933
+  {  19,  55,  91,   9,  45,  81,  35,  71, 107},
934
+  {  25,  61,  97,  15,  51,  87,   5,  41,  77},  
935
+  {  31,  67, 103,  21,  57,  93,  11,  47,  83},
936
+};
937
+
938
+static const int dv_audio_frequency[3] = {
939
+    48000, 44100, 32000, 
940
+};
941
+
942
+static const int dv_audio_min_samples[2][3] = {
943
+    { 1580, 1452, 1053 }, /* 60 fields */
944
+    { 1896, 1742, 1264 }, /* 50 fileds */
945
+};
... ...
@@ -22,15 +22,17 @@
22 22
 #define PAL_FRAME_SIZE  144000
23 23
 
24 24
 typedef struct DVDemuxContext {
25
-    int is_audio;
25
+    int       is_audio;
26
+    uint8_t   buf[PAL_FRAME_SIZE];
27
+    int       size;
26 28
 } DVDemuxContext;
27 29
 
28 30
 /* raw input */
29 31
 static int dv_read_header(AVFormatContext *s,
30 32
                           AVFormatParameters *ap)
31 33
 {
32
-    AVStream *vst;
33
-    //    AVStream *ast;
34
+    AVStream *vst, *ast;
35
+    DVDemuxContext *c = s->priv_data;
34 36
 
35 37
     vst = av_new_stream(s, 0);
36 38
     if (!vst)
... ...
@@ -38,42 +40,46 @@ static int dv_read_header(AVFormatContext *s,
38 38
     vst->codec.codec_type = CODEC_TYPE_VIDEO;
39 39
     vst->codec.codec_id = CODEC_ID_DVVIDEO;
40 40
 
41
-#if 0
41
+
42 42
     ast = av_new_stream(s, 1);
43 43
     if (!ast)
44 44
         return AVERROR_NOMEM;
45 45
 
46 46
     ast->codec.codec_type = CODEC_TYPE_AUDIO;
47 47
     ast->codec.codec_id = CODEC_ID_DVAUDIO;
48
-#endif
48
+    ast->codec.channels = 2;
49
+    c->is_audio = 0;
50
+
49 51
     return 0;
50 52
 }
51 53
 
52 54
 /* XXX: build fake audio stream when DV audio decoder will be finished */
53 55
 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
54 56
 {
55
-    int ret, size, dsf;
56
-    uint8_t buf[4];
57
+    int ret, dsf;
58
+    DVDemuxContext *c = s->priv_data;
57 59
     
58
-    ret = get_buffer(&s->pb, buf, 4);
59
-    if (ret <= 0) 
60
-        return -EIO;
61
-    dsf = buf[3] & 0x80;
62
-    if (!dsf)
63
-        size = NTSC_FRAME_SIZE;
64
-    else
65
-        size = PAL_FRAME_SIZE;
60
+    if (!c->is_audio) {
61
+        ret = get_buffer(&s->pb, c->buf, 4);
62
+        if (ret <= 0) 
63
+            return -EIO;
64
+        dsf = c->buf[3] & 0x80;
65
+        if (!dsf)
66
+            c->size = NTSC_FRAME_SIZE;
67
+        else
68
+            c->size = PAL_FRAME_SIZE;
69
+	
70
+	ret = get_buffer(&s->pb, c->buf + 4, c->size - 4);
71
+	if (ret <= 0)
72
+	    return -EIO;
73
+    }
66 74
     
67
-    if (av_new_packet(pkt, size) < 0)
75
+    if (av_new_packet(pkt, c->size) < 0)
68 76
         return -EIO;
69 77
 
70
-    pkt->stream_index = 0;
71
-    memcpy(pkt->data, buf, 4);
72
-    ret = get_buffer(&s->pb, pkt->data + 4, size - 4);
73
-    if (ret <= 0) {
74
-        av_free_packet(pkt);
75
-        return -EIO;
76
-    }
78
+    pkt->stream_index = c->is_audio;
79
+    c->is_audio = !c->is_audio;
80
+    memcpy(pkt->data, c->buf, c->size);
77 81
     return ret;
78 82
 }
79 83