Browse code

* DV handling was streamlined for both muxing/demuxing and decoding. All muxing/demuxing functionality is now available in libavformat/dv.[ch].

* dv1394.c and avidec.c were hooked up with general DV demuxer.

* DVAUDIO is dead! Long live pcm_s16le!

* DV audio is now always recognized -- which means we can
now hear all those ducks quaking in pond.dv.

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

Roman Shaposhnik authored on 2003/09/30 02:54:07
Showing 9 changed files
... ...
@@ -103,7 +103,6 @@ void avcodec_register_all(void)
103 103
     register_avcodec(&mpeg_xvmc_decoder);
104 104
 #endif
105 105
     register_avcodec(&dvvideo_decoder);
106
-    register_avcodec(&dvaudio_decoder);
107 106
     register_avcodec(&mjpeg_decoder);
108 107
     register_avcodec(&mjpegb_decoder);
109 108
     register_avcodec(&mp2_decoder);
... ...
@@ -1388,7 +1388,6 @@ extern AVCodec rv10_decoder;
1388 1388
 extern AVCodec svq1_decoder;
1389 1389
 extern AVCodec svq3_decoder;
1390 1390
 extern AVCodec dvvideo_decoder;
1391
-extern AVCodec dvaudio_decoder;
1392 1391
 extern AVCodec wmav1_decoder;
1393 1392
 extern AVCodec wmav2_decoder;
1394 1393
 extern AVCodec mjpeg_decoder;
... ...
@@ -25,34 +25,29 @@
25 25
 #include "dsputil.h"
26 26
 #include "mpegvideo.h"
27 27
 #include "simple_idct.h"
28
-
29
-#define NTSC_FRAME_SIZE 120000
30
-#define PAL_FRAME_SIZE  144000
31
-
32
-#define TEX_VLC_BITS 9
28
+#include "dvdata.h"
33 29
 
34 30
 typedef struct DVVideoDecodeContext {
35
-    AVCodecContext *avctx;
31
+    const DVprofile* sys;
36 32
     GetBitContext gb;
37
-    VLC *vlc;
38
-    int sampling_411; /* 0 = 420, 1 = 411 */
39
-    int width, height;
40
-    uint8_t *current_picture[3]; /* picture structure */
41 33
     AVFrame picture;
42
-    int linesize[3];
43 34
     DCTELEM block[5*6][64] __align8;
35
+    
36
+    /* FIXME: the following is extracted from DSP */
44 37
     uint8_t dv_zigzag[2][64];
45 38
     uint8_t idct_permutation[64];
39
+    void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size);
40
+    void (*fdct)(DCTELEM *block);
41
+    
46 42
     /* XXX: move it to static storage ? */
47 43
     uint8_t dv_shift[2][22][64];
48 44
     void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
49 45
 } DVVideoDecodeContext;
50 46
 
51
-#include "dvdata.h"
52
-
53
-static VLC dv_vlc;
47
+#define TEX_VLC_BITS 9
54 48
 /* XXX: also include quantization */
55 49
 static RL_VLC_ELEM *dv_rl_vlc[1];
50
+static VLC_TYPE dv_vlc_codes[15][23];
56 51
 
57 52
 static void dv_build_unquantize_tables(DVVideoDecodeContext *s)
58 53
 {
... ...
@@ -85,6 +80,7 @@ static int dvvideo_decode_init(AVCodecContext *avctx)
85 85
 
86 86
     if (!done) {
87 87
         int i;
88
+        VLC dv_vlc;
88 89
 
89 90
         done = 1;
90 91
 
... ...
@@ -114,6 +110,12 @@ static int dvvideo_decode_init(AVCodecContext *avctx)
114 114
             dv_rl_vlc[0][i].level = level;
115 115
             dv_rl_vlc[0][i].run = run;
116 116
         }
117
+
118
+	memset(dv_vlc_codes, 0xff, sizeof(dv_vlc_codes));
119
+	for (i = 0; i < NB_DV_VLC - 1; i++) {
120
+	   if (dv_vlc_run[i] < 15 && dv_vlc_level[i] < 23 && dv_vlc_len[i] < 15)
121
+	       dv_vlc_codes[dv_vlc_run[i]][dv_vlc_level[i]] = i;
122
+	}
117 123
     }
118 124
 
119 125
     /* ugly way to get the idct & scantable */
... ...
@@ -124,6 +126,9 @@ static int dvvideo_decode_init(AVCodecContext *avctx)
124 124
     if (DCT_common_init(&s2) < 0)
125 125
        return -1;
126 126
 
127
+    s->get_pixels = s2.dsp.get_pixels;
128
+    s->fdct = s2.dsp.fdct;
129
+    
127 130
     s->idct_put[0] = s2.dsp.idct_put;
128 131
     memcpy(s->idct_permutation, s2.dsp.idct_permutation, 64);
129 132
     memcpy(s->dv_zigzag[0], s2.intra_scantable.permutated, 64);
... ...
@@ -134,11 +139,11 @@ static int dvvideo_decode_init(AVCodecContext *avctx)
134 134
 
135 135
     /* XXX: do it only for constant case */
136 136
     dv_build_unquantize_tables(s);
137
-    
137
+
138 138
     return 0;
139 139
 }
140 140
 
141
-//#define VLC_DEBUG
141
+// #define VLC_DEBUG
142 142
 
143 143
 typedef struct BlockInfo {
144 144
     const uint8_t *shift_table;
... ...
@@ -450,29 +455,29 @@ static inline void dv_decode_video_segment(DVVideoDecodeContext *s,
450 450
         v = *mb_pos_ptr++;
451 451
         mb_x = v & 0xff;
452 452
         mb_y = v >> 8;
453
-        y_ptr = s->current_picture[0] + (mb_y * s->linesize[0] * 8) + (mb_x * 8);
454
-        if (s->sampling_411)
455
-            c_offset = (mb_y * s->linesize[1] * 8) + ((mb_x >> 2) * 8);
453
+        y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8);
454
+        if (s->sys->pix_fmt == PIX_FMT_YUV411P)
455
+            c_offset = (mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8);
456 456
         else
457
-            c_offset = ((mb_y >> 1) * s->linesize[1] * 8) + ((mb_x >> 1) * 8);
457
+            c_offset = ((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8);
458 458
         for(j = 0;j < 6; j++) {
459 459
             idct_put = s->idct_put[mb->dct_mode];
460 460
             if (j < 4) {
461
-                if (s->sampling_411 && mb_x < (704 / 8)) {
461
+                if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {
462 462
                     /* NOTE: at end of line, the macroblock is handled as 420 */
463
-                    idct_put(y_ptr + (j * 8), s->linesize[0], block);
463
+                    idct_put(y_ptr + (j * 8), s->picture.linesize[0], block);
464 464
                 } else {
465
-                    idct_put(y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->linesize[0]),
466
-                             s->linesize[0], block);
465
+                    idct_put(y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]),
466
+                             s->picture.linesize[0], block);
467 467
                 }
468 468
             } else {
469
-                if (s->sampling_411 && mb_x >= (704 / 8)) {
469
+                if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
470 470
                     uint8_t pixels[64], *c_ptr, *c_ptr1, *ptr;
471 471
                     int y, linesize;
472 472
                     /* NOTE: at end of line, the macroblock is handled as 420 */
473 473
                     idct_put(pixels, 8, block);
474
-                    linesize = s->linesize[6 - j];
475
-                    c_ptr = s->current_picture[6 - j] + c_offset;
474
+                    linesize = s->picture.linesize[6 - j];
475
+                    c_ptr = s->picture.data[6 - j] + c_offset;
476 476
                     ptr = pixels;
477 477
                     for(y = 0;y < 8; y++) {
478 478
                         /* convert to 411P */
... ...
@@ -486,8 +491,8 @@ static inline void dv_decode_video_segment(DVVideoDecodeContext *s,
486 486
                     }
487 487
                 } else {
488 488
                     /* don't ask me why they inverted Cb and Cr ! */
489
-                    idct_put(s->current_picture[6 - j] + c_offset, 
490
-                             s->linesize[6 - j], block);
489
+                    idct_put(s->picture.data[6 - j] + c_offset, 
490
+                             s->picture.linesize[6 - j], block);
491 491
                 }
492 492
             }
493 493
             block += 64;
... ...
@@ -496,7 +501,6 @@ static inline void dv_decode_video_segment(DVVideoDecodeContext *s,
496 496
     }
497 497
 }
498 498
 
499
-
500 499
 /* NOTE: exactly one frame must be given (120000 bytes for NTSC,
501 500
    144000 bytes for PAL) */
502 501
 static int dvvideo_decode_frame(AVCodecContext *avctx, 
... ...
@@ -504,115 +508,35 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
504 504
                                  uint8_t *buf, int buf_size)
505 505
 {
506 506
     DVVideoDecodeContext *s = avctx->priv_data;
507
-    int sct, dsf, apt, ds, nb_dif_segs, vs, width, height, i, packet_size;
508
-    uint8_t *buf_ptr;
507
+    int ds, vs;
509 508
     const uint16_t *mb_pos_ptr;
510 509
     
511
-    /* parse id */
512
-    init_get_bits(&s->gb, buf, buf_size*8);
513
-    sct = get_bits(&s->gb, 3);
514
-    if (sct != 0)
515
-        return -1;
516
-    skip_bits(&s->gb, 5);
517
-    get_bits(&s->gb, 4); /* dsn (sequence number */
518
-    get_bits(&s->gb, 1); /* fsc (channel number) */
519
-    skip_bits(&s->gb, 3);
520
-    get_bits(&s->gb, 8); /* dbn (diff block number 0-134) */
521
-
522
-    dsf = get_bits(&s->gb, 1); /* 0 = NTSC 1 = PAL */
523
-    if (get_bits(&s->gb, 1) != 0)
524
-        return -1;
525
-    skip_bits(&s->gb, 11);
526
-    apt = get_bits(&s->gb, 3); /* apt */
527
-
528
-    get_bits(&s->gb, 1); /* tf1 */
529
-    skip_bits(&s->gb, 4);
530
-    get_bits(&s->gb, 3); /* ap1 */
531
-
532
-    get_bits(&s->gb, 1); /* tf2 */
533
-    skip_bits(&s->gb, 4);
534
-    get_bits(&s->gb, 3); /* ap2 */
535
-
536
-    get_bits(&s->gb, 1); /* tf3 */
537
-    skip_bits(&s->gb, 4);
538
-    get_bits(&s->gb, 3); /* ap3 */
539
-    
540
-    /* init size */
541
-    width = 720;
542
-    if (dsf) {
543
-        avctx->frame_rate = 25;
544
-	avctx->frame_rate_base = 1;
545
-        packet_size = PAL_FRAME_SIZE;
546
-        height = 576;
547
-        nb_dif_segs = 12;
548
-    } else {
549
-        avctx->frame_rate = 30000;
550
-	avctx->frame_rate_base = 1001;
551
-        packet_size = NTSC_FRAME_SIZE;
552
-        height = 480;
553
-        nb_dif_segs = 10;
554
-    }
555
-    /* NOTE: we only accept several full frames */
556
-    if (buf_size < packet_size)
557
-        return -1;
558
-    
559
-    /* NTSC[dsf == 0] is always 720x480, 4:1:1
560
-     *  PAL[dsf == 1] is always 720x576, 4:2:0 for IEC 68134[apt == 0]
561
-     *  but for the SMPTE 314M[apt == 1] it is 720x576, 4:1:1
562
-     */
563
-    s->sampling_411 = !dsf || apt;
564
-    if (s->sampling_411) {
565
-        mb_pos_ptr = dsf ? dv_place_411P : dv_place_411;
566
-        avctx->pix_fmt = PIX_FMT_YUV411P;
567
-    } else {
568
-        mb_pos_ptr = dv_place_420;
569
-        avctx->pix_fmt = PIX_FMT_YUV420P;
570
-    }
571
-
572
-    avctx->width = width;
573
-    avctx->height = height;
574
-    
575
-    /* Once again, this is pretty complicated by the fact that the same
576
-     * field is used differently by IEC 68134[apt == 0] and 
577
-     * SMPTE 314M[apt == 1].
578
-     */
579
-    if (buf[VAUX_TC61_OFFSET] == 0x61 &&
580
-        ((apt == 0 && (buf[VAUX_TC61_OFFSET + 2] & 0x07) == 0x07) ||
581
-	 (apt == 1 && (buf[VAUX_TC61_OFFSET + 2] & 0x07) == 0x02)))
582
-        avctx->aspect_ratio = 16.0 / 9.0;
583
-    else
584
-        avctx->aspect_ratio = 4.0 / 3.0;
510
+    s->sys = dv_frame_profile(buf);
511
+    if (!s->sys || buf_size < s->sys->frame_size)
512
+        return -1; /* NOTE: we only accept several full frames */
585 513
 
514
+	
586 515
     if(s->picture.data[0])
587 516
         avctx->release_buffer(avctx, &s->picture);
588 517
     
589
-    s->picture.reference= 0;
518
+    s->picture.reference = 0;
519
+    avctx->pix_fmt = s->sys->pix_fmt;
590 520
     if(avctx->get_buffer(avctx, &s->picture) < 0) {
591 521
         fprintf(stderr, "get_buffer() failed\n");
592 522
         return -1;
593 523
     }
594 524
 
595
-    for(i=0;i<3;i++) {
596
-        s->current_picture[i] = s->picture.data[i];
597
-        s->linesize[i] = s->picture.linesize[i];
598
-        if (!s->current_picture[i])
599
-            return -1;
600
-    }
601
-    s->width = width;
602
-    s->height = height;
603
-
604 525
     /* for each DIF segment */
605
-    buf_ptr = buf;
606
-    for (ds = 0; ds < nb_dif_segs; ds++) {
607
-        buf_ptr += 6 * 80; /* skip DIF segment header */
526
+    mb_pos_ptr = s->sys->video_place;
527
+    for (ds = 0; ds < s->sys->difseg_size; ds++) {
528
+        buf += 6 * 80; /* skip DIF segment header */
608 529
         
609 530
         for(vs = 0; vs < 27; vs++) {
610
-            if ((vs % 3) == 0) {
611
-                /* skip audio block */
612
-                buf_ptr += 80;
613
-            }
614
-            dv_decode_video_segment(s, buf_ptr, mb_pos_ptr);
615
-            buf_ptr += 5 * 80;
531
+            if ((vs % 3) == 0)
532
+	        buf += 80; /* skip audio block */
533
+            
534
+	    dv_decode_video_segment(s, buf, mb_pos_ptr);
535
+            buf += 5 * 80;
616 536
             mb_pos_ptr += 5;
617 537
         }
618 538
     }
... ...
@@ -623,7 +547,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
623 623
     *data_size = sizeof(AVFrame);
624 624
     *(AVFrame*)data= s->picture;
625 625
     
626
-    return packet_size;
626
+    return s->sys->frame_size;
627 627
 }
628 628
 
629 629
 static int dvvideo_decode_end(AVCodecContext *avctx)
... ...
@@ -645,158 +569,3 @@ AVCodec dvvideo_decoder = {
645 645
     CODEC_CAP_DR1,
646 646
     NULL
647 647
 };
648
-
649
-typedef struct DVAudioDecodeContext {
650
-    AVCodecContext *avctx;
651
-    GetBitContext gb;
652
-} DVAudioDecodeContext;
653
-
654
-static int dvaudio_decode_init(AVCodecContext *avctx)
655
-{
656
-    //    DVAudioDecodeContext *s = avctx->priv_data;
657
-    return 0;
658
-}
659
-
660
-static uint16_t dv_audio_12to16(uint16_t sample)
661
-{
662
-    uint16_t shift, result;
663
-    
664
-    sample = (sample < 0x800) ? sample : sample | 0xf000;
665
-    shift = (sample & 0xf00) >> 8;
666
-
667
-    if (shift < 0x2 || shift > 0xd) {
668
-	result = sample;
669
-    } else if (shift < 0x8) {
670
-        shift--;
671
-	result = (sample - (256 * shift)) << shift;
672
-    } else {
673
-	shift = 0xe - shift;
674
-	result = ((sample + ((256 * shift) + 1)) << shift) - 1;
675
-    }
676
-
677
-    return result;
678
-}
679
-
680
-/* NOTE: exactly one frame must be given (120000 bytes for NTSC,
681
-   144000 bytes for PAL) 
682
-
683
-   There's a couple of assumptions being made here:
684
-         1. By default we silence erroneous (0x8000/16bit 0x800/12bit) 
685
-	    audio samples. We can pass them upwards when ffmpeg will be ready
686
-	    to deal with them.
687
-	 2. We don't do software emphasis.
688
-	 3. Audio is always returned as 16bit linear samples: 12bit
689
-	    nonlinear samples are converted into 16bit linear ones.
690
-*/
691
-static int dvaudio_decode_frame(AVCodecContext *avctx, 
692
-                                 void *data, int *data_size,
693
-                                 uint8_t *buf, int buf_size)
694
-{
695
-    DVVideoDecodeContext *s = avctx->priv_data;
696
-    const uint16_t (*unshuffle)[9];
697
-    int smpls, freq, quant, sys, stride, difseg, ad, dp, nb_dif_segs, i;
698
-    uint16_t lc, rc;
699
-    uint8_t *buf_ptr;
700
-    
701
-    /* parse id */
702
-    init_get_bits(&s->gb, &buf[AAUX_AS_OFFSET], 5*8);
703
-    i = get_bits(&s->gb, 8);
704
-    if (i != 0x50) { /* No audio ? */
705
-	*data_size = 0;
706
-	return buf_size;
707
-    }
708
-    
709
-    get_bits(&s->gb, 1); /* 0 - locked audio, 1 - unlocked audio */
710
-    skip_bits(&s->gb, 1);
711
-    smpls = get_bits(&s->gb, 6); /* samples in this frame - min. samples */
712
-
713
-    skip_bits(&s->gb, 8);
714
-
715
-    skip_bits(&s->gb, 2);
716
-    sys = get_bits(&s->gb, 1); /* 0 - 60 fields, 1 = 50 fields */
717
-    skip_bits(&s->gb, 5);
718
-
719
-    get_bits(&s->gb, 1); /* 0 - emphasis on, 1 - emphasis off */
720
-    get_bits(&s->gb, 1); /* 0 - reserved, 1 - emphasis time constant 50/15us */
721
-    freq = get_bits(&s->gb, 3); /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */
722
-    quant = get_bits(&s->gb, 3); /* 0 - 16bit linear, 1 - 12bit nonlinear */
723
-
724
-    if (quant > 1)
725
-	return -1; /* Unsupported quantization */
726
-
727
-    avctx->sample_rate = dv_audio_frequency[freq];
728
-    avctx->channels = 2;
729
-    avctx->bit_rate = avctx->channels * avctx->sample_rate * 16;
730
-    // What about:
731
-    // avctx->frame_size =
732
-   
733
-    *data_size = (dv_audio_min_samples[sys][freq] + smpls) * 
734
-	         avctx->channels * 2;
735
-
736
-    if (sys) {
737
-	nb_dif_segs = 12;
738
-	stride = 108;
739
-	unshuffle = dv_place_audio50;
740
-    } else {
741
-	nb_dif_segs = 10;
742
-	stride = 90;
743
-	unshuffle = dv_place_audio60;
744
-    }
745
-    
746
-    /* for each DIF segment */
747
-    buf_ptr = buf;
748
-    for (difseg = 0; difseg < nb_dif_segs; difseg++) {
749
-         buf_ptr += 6 * 80; /* skip DIF segment header */
750
-         for (ad = 0; ad < 9; ad++) {
751
-              
752
-              for (dp = 8; dp < 80; dp+=2) {
753
-		   if (quant == 0) {  /* 16bit quantization */
754
-		       i = unshuffle[difseg][ad] + (dp - 8)/2 * stride;
755
-		       ((short *)data)[i] = (buf_ptr[dp] << 8) | buf_ptr[dp+1]; 
756
-		       if (((unsigned short *)data)[i] == 0x8000)
757
-		           ((short *)data)[i] = 0;
758
-		   } else {           /* 12bit quantization */
759
-		       if (difseg >= nb_dif_segs/2)
760
-			   goto out;  /* We're not doing 4ch at this time */
761
-		       
762
-		       lc = ((uint16_t)buf_ptr[dp] << 4) | 
763
-			    ((uint16_t)buf_ptr[dp+2] >> 4);
764
-		       rc = ((uint16_t)buf_ptr[dp+1] << 4) |
765
-			    ((uint16_t)buf_ptr[dp+2] & 0x0f);
766
-		       lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
767
-		       rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
768
-
769
-		       i = unshuffle[difseg][ad] + (dp - 8)/3 * stride;
770
-		       ((short *)data)[i] = lc;
771
-		       i = unshuffle[difseg+nb_dif_segs/2][ad] + (dp - 8)/3 * stride;
772
-		       ((short *)data)[i] = rc;
773
-		       ++dp;
774
-		   }
775
-	      }
776
-		
777
-	    buf_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
778
-        }
779
-    }
780
-
781
-out:
782
-    return buf_size;
783
-}
784
-
785
-static int dvaudio_decode_end(AVCodecContext *avctx)
786
-{
787
-    //    DVAudioDecodeContext *s = avctx->priv_data;
788
-    return 0;
789
-}
790
-
791
-AVCodec dvaudio_decoder = {
792
-    "dvaudio",
793
-    CODEC_TYPE_AUDIO,
794
-    CODEC_ID_DVAUDIO,
795
-    sizeof(DVAudioDecodeContext),
796
-    dvaudio_decode_init,
797
-    NULL,
798
-    dvaudio_decode_end,
799
-    dvaudio_decode_frame,
800
-    0,
801
-    NULL
802
-};
... ...
@@ -21,11 +21,34 @@
21 21
  * @file dvdata.h
22 22
  * Constants for DV codec.
23 23
  */
24
- 
24
+
25
+/* 
26
+ * DVprofile is used to express the differences between various 
27
+ * DV flavors. For now it's primarily used for differentiating
28
+ * 525/60 and 625/50, but the plans are to use it for various
29
+ * DV specs as well (e.g. SMPTE314M vs. IEC 61834).
30
+ */
31
+typedef struct DVprofile {
32
+    int              dsf;                 /* value of the dsf in the DV header */
33
+    int              frame_size;          /* total size of one frame in bytes */
34
+    int              difseg_size;         /* number of DIF segments */
35
+    int              frame_rate;      
36
+    int              frame_rate_base;
37
+    int              ltc_divisor;         /* FPS from the LTS standpoint */
38
+    int              height;              /* picture height in pixels */
39
+    int              width;               /* picture width in pixels */
40
+    const uint16_t  *video_place;         /* positions of all DV macro blocks */
41
+    enum PixelFormat pix_fmt;             /* picture pixel format */
42
+    
43
+    int              audio_stride;        /* size of audio_shuffle table */
44
+    int              audio_min_samples[3];/* min ammount of audio samples */
45
+                                          /* for 48Khz, 44.1Khz and 32Khz */
46
+    int              audio_samples_dist[5];/* how many samples are supposed to be */
47
+                                         /* in each frame in a 5 frames window */
48
+    const uint16_t (*audio_shuffle)[9];  /* PCM shuffling table */
49
+} DVprofile;
50
+
25 51
 #define NB_DV_VLC 409
26
-#define AAUX_AS_OFFSET  (80*6 + 80*16*3 + 3)
27
-#define AAUX_ASC_OFFSET (80*6 + 80*16*4 + 3)
28
-#define VAUX_TC61_OFFSET (80*5 + 48 + 5)
29 52
 
30 53
 static const uint16_t dv_vlc_bits[409] = {
31 54
  0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016,
... ...
@@ -283,7 +306,7 @@ static const uint8_t dv_248_areas[64] = {
283 283
     1,2,2,3,3,3,3,3,
284 284
 };
285 285
 
286
-static uint8_t dv_quant_shifts[22][4] = {
286
+static const uint8_t dv_quant_shifts[22][4] = {
287 287
   { 3,3,4,4 }, 
288 288
   { 3,3,4,4 }, 
289 289
   { 2,3,3,4 }, 
... ...
@@ -1240,7 +1263,7 @@ static const uint16_t dv_place_411[1350] = {
1240 1240
  0x0834, 0x2320, 0x2f44, 0x3810, 0x1658,
1241 1241
 };
1242 1242
 
1243
-static const uint16_t dv_place_audio60[10][9] = {
1243
+static const uint16_t dv_audio_shuffle525[10][9] = {
1244 1244
   {  0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */
1245 1245
   {  6, 36, 66, 26, 56, 86, 16, 46, 76 },
1246 1246
   { 12, 42, 72,  2, 32, 62, 22, 52, 82 },
... ...
@@ -1254,7 +1277,7 @@ static const uint16_t dv_place_audio60[10][9] = {
1254 1254
   { 25, 55, 85, 15, 45, 75,  5, 35, 65 },
1255 1255
 };
1256 1256
 
1257
-static const uint16_t dv_place_audio50[12][9] = {
1257
+static const uint16_t dv_audio_shuffle625[12][9] = {
1258 1258
   {   0,  36,  72,  26,  62,  98,  16,  52,  88}, /* 1st channel */
1259 1259
   {   6,  42,  78,  32,  68, 104,  22,  58,  94},
1260 1260
   {  12,  48,  84,   2,  38,  74,  28,  64, 100},
... ...
@@ -1271,10 +1294,77 @@ static const uint16_t dv_place_audio50[12][9] = {
1271 1271
 };
1272 1272
 
1273 1273
 static const int dv_audio_frequency[3] = {
1274
-    48000, 44100, 32000, 
1274
+    48000, 44100, 32000,
1275 1275
 };
1276
-
1277
-static const int dv_audio_min_samples[2][3] = {
1278
-    { 1580, 1452, 1053 }, /* 60 fields */
1279
-    { 1896, 1742, 1264 }, /* 50 fileds */
1276
+    
1277
+static const DVprofile dv_profiles[] = {
1278
+    { .dsf = 0,
1279
+      .frame_size = 120000,        /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */
1280
+      .difseg_size = 10,
1281
+      .frame_rate = 30000,
1282
+      .ltc_divisor = 30,
1283
+      .frame_rate_base = 1001,
1284
+      .height = 480,
1285
+      .width = 720,
1286
+      .video_place = dv_place_411,
1287
+      .pix_fmt = PIX_FMT_YUV411P,
1288
+      .audio_stride = 90,
1289
+      .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32Khz */
1290
+      .audio_samples_dist = { 1602, 1601, 1602, 1601, 1602 },
1291
+      .audio_shuffle = dv_audio_shuffle525,
1292
+    }, 
1293
+    { .dsf = 1,
1294
+      .frame_size = 144000,        /* IEC 61834 - 625/50 (PAL) */
1295
+      .difseg_size = 12,
1296
+      .frame_rate = 25,
1297
+      .frame_rate_base = 1,
1298
+      .ltc_divisor = 25,
1299
+      .height = 576,
1300
+      .width = 720,
1301
+      .video_place = dv_place_420,
1302
+      .pix_fmt = PIX_FMT_YUV420P,
1303
+      .audio_stride = 108,
1304
+      .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32Khz */
1305
+      .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
1306
+      .audio_shuffle = dv_audio_shuffle625,
1307
+    },
1308
+    { .dsf = 1,
1309
+      .frame_size = 144000,        /* SMPTE-314M - 625/50 (PAL) */
1310
+      .difseg_size = 12,
1311
+      .frame_rate = 25,
1312
+      .frame_rate_base = 1,
1313
+      .ltc_divisor = 25,
1314
+      .height = 576,
1315
+      .width = 720,
1316
+      .video_place = dv_place_411P,
1317
+      .pix_fmt = PIX_FMT_YUV411P,
1318
+      .audio_stride = 108,
1319
+      .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32Khz */
1320
+      .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 },
1321
+      .audio_shuffle = dv_audio_shuffle625,
1322
+     }
1280 1323
 };
1324
+
1325
+static inline const DVprofile* dv_frame_profile(uint8_t* frame)
1326
+{
1327
+    if ((frame[3] & 0x80) == 0) {      /* DSF flag */
1328
+        return &dv_profiles[0];
1329
+    }
1330
+    else if ((frame[5] & 0x07) == 0) { /* APT flag */
1331
+        return &dv_profiles[1];
1332
+    }
1333
+    else 
1334
+        return &dv_profiles[2];
1335
+}
1336
+
1337
+static inline const DVprofile* dv_codec_profile(AVCodecContext* codec)
1338
+{
1339
+    if (codec->width != 720) {
1340
+        return NULL;
1341
+    } 
1342
+    else if (codec->height == 480) {
1343
+        return &dv_profiles[0];
1344
+    } 
1345
+    else 
1346
+        return &dv_profiles[1];
1347
+}
... ...
@@ -13,7 +13,7 @@ PPOBJS=
13 13
 
14 14
 # mux and demuxes
15 15
 OBJS+=mpeg.o mpegts.o mpegtsenc.o ffm.o crc.o img.o raw.o rm.o \
16
-      avienc.o avidec.o wav.o swf.o au.o gif.o mov.o mpjpeg.o dvcore.o dv.o \
16
+      avienc.o avidec.o wav.o swf.o au.o gif.o mov.o mpjpeg.o dv.o \
17 17
       yuv4mpeg.o 4xm.o flvenc.o flvdec.o movenc.o psxstr.o idroq.o ipmovie.o \
18 18
       nut.o wc3movie.o mp3.o
19 19
 
... ...
@@ -18,21 +18,10 @@
18 18
  */
19 19
 #include "avformat.h"
20 20
 #include "avi.h"
21
+#include "dv.h"
21 22
 
22 23
 //#define DEBUG
23 24
 
24
-static const struct AVI1Handler {
25
-   enum CodecID vcid;
26
-   enum CodecID acid;
27
-   uint32_t tag;
28
-} AVI1Handlers[] = {
29
-  { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 's', 'd') },
30
-  { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'h', 'd') },
31
-  { CODEC_ID_DVVIDEO, CODEC_ID_DVAUDIO, MKTAG('d', 'v', 's', 'l') },
32
-  /* This is supposed to be the last one */
33
-  { CODEC_ID_NONE, CODEC_ID_NONE, 0 },
34
-};
35
-
36 25
 typedef struct AVIIndex {
37 26
     unsigned char tag[4];
38 27
     unsigned int flags, pos, len;
... ...
@@ -40,14 +29,11 @@ typedef struct AVIIndex {
40 40
 } AVIIndex;
41 41
 
42 42
 typedef struct {
43
-    int64_t riff_end;
44
-    int64_t movi_end;
45
-    int     type;
46
-    uint8_t *buf;
47
-    int      buf_size;
48
-    int      stream_index;
43
+    int64_t  riff_end;
44
+    int64_t  movi_end;
49 45
     offset_t movi_list;
50 46
     AVIIndex *first, *last;
47
+    void* dv_demux;
51 48
 } AVIContext;
52 49
 
53 50
 #ifdef DEBUG
... ...
@@ -97,11 +83,6 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
97 97
     stream_index = -1;
98 98
     codec_type = -1;
99 99
     frame_period = 0;
100
-    avi->type = 2;
101
-    avi->buf = av_malloc(1);
102
-    if (!avi->buf)
103
-        return -1;
104
-    avi->buf_size = 1;
105 100
     for(;;) {
106 101
         if (url_feof(pb))
107 102
             goto fail;
... ...
@@ -134,7 +115,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
134 134
 	    url_fskip(pb, 4 * 4);
135 135
             n = get_le32(pb);
136 136
             for(i=0;i<n;i++) {
137
-                st = av_new_stream(s, 0);
137
+                st = av_new_stream(s, i);
138 138
                 if (!st)
139 139
                     goto fail;
140 140
 	    }
... ...
@@ -144,24 +125,36 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
144 144
             /* stream header */
145 145
             stream_index++;
146 146
             tag1 = get_le32(pb);
147
+            handler = get_le32(pb); /* codec tag */
147 148
             switch(tag1) {
148 149
             case MKTAG('i', 'a', 'v', 's'):
149 150
 	    case MKTAG('i', 'v', 'a', 's'):
151
+                /* 
152
+	         * After some consideration -- I don't think we 
153
+	         * have to support anything but DV in a type1 AVIs.
154
+	         */
150 155
 	        if (s->nb_streams != 1)
151 156
 		    goto fail;
152
-		avi->type = 1;
153
-		avi->stream_index = 0;
157
+	        
158
+		if (handler != MKTAG('d', 'v', 's', 'd') &&
159
+	            handler != MKTAG('d', 'v', 'h', 'd') &&
160
+		    handler != MKTAG('d', 'v', 's', 'l'))
161
+	           goto fail;
162
+
163
+	        avi->dv_demux = dv_init_demux(s, stream_index, stream_index + 1);
164
+		if (!avi->dv_demux)
165
+		    goto fail;
166
+	        stream_index++;
154 167
 	    case MKTAG('v', 'i', 'd', 's'):
155 168
                 codec_type = CODEC_TYPE_VIDEO;
156 169
 
157 170
                 if (stream_index >= s->nb_streams) {
158
-                    url_fskip(pb, size - 4);
171
+                    url_fskip(pb, size - 8);
159 172
                     break;
160 173
                 } 
161 174
 
162 175
                 st = s->streams[stream_index];
163 176
 
164
-                handler = get_le32(pb); /* codec tag */
165 177
                 get_le32(pb); /* flags */
166 178
                 get_le16(pb); /* priority */
167 179
                 get_le16(pb); /* language */
... ...
@@ -186,29 +179,6 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
186 186
                     st->codec.frame_rate_base * AV_TIME_BASE / 
187 187
                     st->codec.frame_rate;
188 188
                 
189
-                if (avi->type == 1) {
190
-                    AVStream *st;
191
-
192
-                    st = av_new_stream(s, 0);
193
-                    if (!st)
194
-		        goto fail;
195
-                    
196
-		    stream_index++;
197
-		    
198
-		    for (i=0; AVI1Handlers[i].tag != 0; ++i)
199
-		       if (AVI1Handlers[i].tag == handler)
200
-		           break;
201
-
202
-		    if (AVI1Handlers[i].tag != 0) {
203
-		        s->streams[0]->codec.codec_type = CODEC_TYPE_VIDEO;
204
-                        s->streams[0]->codec.codec_id   = AVI1Handlers[i].vcid;
205
-		        s->streams[1]->codec.codec_type = CODEC_TYPE_AUDIO;
206
-                        s->streams[1]->codec.codec_id   = AVI1Handlers[i].acid;
207
-		    } else {
208
-		        goto fail;
209
-                    }
210
-		}
211
-		
212 189
 		url_fskip(pb, size - 9 * 4);
213 190
                 break;
214 191
             case MKTAG('a', 'u', 'd', 's'):
... ...
@@ -218,12 +188,11 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
218 218
                     codec_type = CODEC_TYPE_AUDIO;
219 219
 
220 220
                     if (stream_index >= s->nb_streams) {
221
-                        url_fskip(pb, size - 4);
221
+                        url_fskip(pb, size - 8);
222 222
                         break;
223 223
                     } 
224 224
                     st = s->streams[stream_index];
225 225
 
226
-                    get_le32(pb); /* tag */
227 226
                     get_le32(pb); /* flags */
228 227
                     get_le16(pb); /* priority */
229 228
                     get_le16(pb); /* language */
... ...
@@ -244,7 +213,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
244 244
             break;
245 245
         case MKTAG('s', 't', 'r', 'f'):
246 246
             /* stream header */
247
-            if (stream_index >= s->nb_streams || avi->type == 1) {
247
+            if (stream_index >= s->nb_streams || avi->dv_demux) {
248 248
                 url_fskip(pb, size);
249 249
             } else {
250 250
                 st = s->streams[stream_index];
... ...
@@ -305,7 +274,6 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
305 305
     /* check stream number */
306 306
     if (stream_index != s->nb_streams - 1) {
307 307
     fail:
308
-        av_free(avi->buf);
309 308
         for(i=0;i<s->nb_streams;i++) {
310 309
             av_freep(&s->streams[i]->codec.extradata);
311 310
             av_freep(&s->streams[i]);
... ...
@@ -316,31 +284,21 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
316 316
     return 0;
317 317
 }
318 318
 
319
-static void __destruct_pkt(struct AVPacket *pkt)
320
-{
321
-    pkt->data = NULL; pkt->size = 0;
322
-    return;
323
-}
324
-
325 319
 static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
326 320
 {
327 321
     AVIContext *avi = s->priv_data;
328 322
     ByteIOContext *pb = &s->pb;
329 323
     int n, d[8], size, i;
324
+    void* dstr;
330 325
 
331 326
     memset(d, -1, sizeof(int)*8);
332
-    
333
-    if (avi->type == 1 && avi->stream_index) {
334
-        /* duplicate DV packet */
335
-        av_init_packet(pkt);
336
-        pkt->data = avi->buf;
337
-        pkt->size = avi->buf_size;
338
-        pkt->destruct = __destruct_pkt;
339
-        pkt->stream_index = avi->stream_index;
340
-        avi->stream_index = !avi->stream_index;
341
-        return 0;
327
+   
328
+    if (avi->dv_demux) {
329
+        size = dv_get_packet(avi->dv_demux, pkt);
330
+	if (size >= 0)
331
+	    return size;
342 332
     }
343
-
333
+        
344 334
     for(i=url_ftell(pb); !url_feof(pb); i++) {
345 335
         int j;
346 336
 
... ...
@@ -387,26 +345,24 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
387 387
             && n < s->nb_streams
388 388
             && i + size <= avi->movi_end) {
389 389
         
390
-            if (avi->type == 1) {
391
-                uint8_t *tbuf = av_realloc(avi->buf, size + FF_INPUT_BUFFER_PADDING_SIZE);
392
-                if (!tbuf)
393
-                    return -1;
394
-                avi->buf = tbuf;
395
-                avi->buf_size = size;
396
-                av_init_packet(pkt);
397
-                pkt->data = avi->buf;
398
-                pkt->size = avi->buf_size;
399
-                pkt->destruct = __destruct_pkt;
400
-                avi->stream_index = n;
401
-            } else {
402
-                av_new_packet(pkt, size);
403
-            }
390
+            av_new_packet(pkt, size);
404 391
             get_buffer(pb, pkt->data, size);
405
-            if (size & 1)
392
+            if (size & 1) {
406 393
                 get_byte(pb);
407
-            pkt->stream_index = n;
408
-            pkt->flags |= PKT_FLAG_KEY; // FIXME: We really should read index for that
409
-            return 0;
394
+		size++;
395
+	    }
396
+	
397
+	    if (avi->dv_demux) {
398
+	        dstr = pkt->destruct;
399
+	        size = dv_produce_packet(avi->dv_demux, pkt,
400
+		                         pkt->data, pkt->size);
401
+		pkt->destruct = dstr;
402
+	    } else {
403
+                pkt->stream_index = n;
404
+                pkt->flags |= PKT_FLAG_KEY; // FIXME: We really should read 
405
+		                            //        index for that
406
+	    }
407
+            return size;
410 408
         }
411 409
     }
412 410
     return -1;
... ...
@@ -416,7 +372,6 @@ static int avi_read_close(AVFormatContext *s)
416 416
 {
417 417
     int i;
418 418
     AVIContext *avi = s->priv_data;
419
-    av_free(avi->buf);
420 419
 
421 420
     for(i=0;i<s->nb_streams;i++) {
422 421
         AVStream *st = s->streams[i];
... ...
@@ -424,6 +379,9 @@ static int avi_read_close(AVFormatContext *s)
424 424
         av_free(st->codec.extradata);
425 425
     }
426 426
 
427
+    if (avi->dv_demux)
428
+        av_free(avi->dv_demux);
429
+
427 430
     return 0;
428 431
 }
429 432
 
... ...
@@ -1,4 +1,10 @@
1 1
 /* 
2
+ * General DV muxer/demuxer 
3
+ * Copyright (c) 2003 Roman Shaposhnick
4
+ *
5
+ * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
6
+ * of DV technical info.
7
+ *
2 8
  * Raw DV format
3 9
  * Copyright (c) 2002 Fabrice Bellard.
4 10
  *
... ...
@@ -16,38 +22,696 @@
16 16
  * License along with this library; if not, write to the Free Software
17 17
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 18
  */
19
+#include <time.h>
19 20
 #include "avformat.h"
20
-#include "dvcore.h"
21
+#include "dvdata.h"
21 22
 
22 23
 typedef struct DVDemuxContext {
23
-    int       is_audio;
24
-    uint8_t   buf[144000];    
25
-    int       size;
24
+    AVPacket  audio_pkt;
25
+    AVStream  *vst;
26
+    AVStream  *ast;
26 27
 } DVDemuxContext;
27 28
 
28
-/* raw input */
29
-static int dv_read_header(AVFormatContext *s,
30
-                          AVFormatParameters *ap)
29
+typedef struct DVMuxContext {
30
+    const DVprofile*  sys;    /* Current DV profile. E.g.: 525/60, 625/50 */
31
+    uint8_t     frame_buf[144000]; /* frame under contruction */
32
+    FifoBuffer  audio_data;   /* Fifo for storing excessive amounts of PCM */
33
+    int         frames;       /* Number of a current frame */
34
+    time_t      start_time;   /* Start time of recording */
35
+    uint8_t     aspect;       /* Aspect ID 0 - 4:3, 7 - 16:9 */
36
+    int         has_audio;    /* frame under contruction has audio */
37
+    int         has_video;    /* frame under contruction has video */
38
+} DVMuxContext;
39
+
40
+enum dv_section_type {
41
+     dv_sect_header  = 0x1f,
42
+     dv_sect_subcode = 0x3f,
43
+     dv_sect_vaux    = 0x56,
44
+     dv_sect_audio   = 0x76,
45
+     dv_sect_video   = 0x96,
46
+};
47
+
48
+enum dv_pack_type {
49
+     dv_header525     = 0x3f, /* see dv_write_pack for important details on */ 
50
+     dv_header625     = 0xbf, /* these two packs */
51
+     dv_timecode      = 0x13,
52
+     dv_audio_source  = 0x50,
53
+     dv_audio_control = 0x51,
54
+     dv_audio_recdate = 0x52,
55
+     dv_audio_rectime = 0x53,
56
+     dv_video_source  = 0x60,
57
+     dv_video_control = 0x61,
58
+     dv_viedo_recdate = 0x62,
59
+     dv_video_rectime = 0x63,
60
+     dv_unknown_pack  = 0xff,
61
+};
62
+
63
+
64
+
65
+/*
66
+ * The reason why the following three big ugly looking tables are
67
+ * here is my lack of DV spec IEC 61834. The tables were basically 
68
+ * constructed to make code that places packs in SSYB, VAUX and 
69
+ * AAUX blocks very simple and table-driven. They conform to the
70
+ * SMPTE 314M and the output of my personal DV camcorder, neither
71
+ * of which is sufficient for a reliable DV stream producing. Thus
72
+ * while code is still in development I'll be gathering input from
73
+ * people with different DV equipment and modifying the tables to
74
+ * accommodate all the quirks. Later on, if possible, some of them
75
+ * will be folded into smaller tables and/or switch-if logic. For 
76
+ * now, my only excuse is -- they don't eat up that much of a space.
77
+ */
78
+
79
+static const int dv_ssyb_packs_dist[12][6] = {
80
+    { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
81
+    { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
82
+    { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
83
+    { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
84
+    { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
85
+    { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 },
86
+    { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
87
+    { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
88
+    { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
89
+    { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
90
+    { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
91
+    { 0x13, 0x62, 0x63, 0x13, 0x62, 0x63 },
92
+};
93
+
94
+static const int dv_vaux_packs_dist[12][15] = {
95
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
96
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
97
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
98
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
99
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
100
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
101
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
102
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
103
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
104
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
105
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
106
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
107
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
108
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
109
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
110
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
111
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
112
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
113
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
114
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
115
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
116
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
117
+    { 0x60, 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 
118
+      0x60, 0x61, 0x62, 0x63, 0xff, 0xff },
119
+};
120
+
121
+static const int dv_aaux_packs_dist[12][9] = {
122
+    { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
123
+    { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
124
+    { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
125
+    { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
126
+    { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
127
+    { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
128
+    { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
129
+    { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
130
+    { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
131
+    { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
132
+    { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff },
133
+    { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff },
134
+};
135
+
136
+static inline uint16_t dv_audio_12to16(uint16_t sample)
137
+{
138
+    uint16_t shift, result;
139
+    
140
+    sample = (sample < 0x800) ? sample : sample | 0xf000;
141
+    shift = (sample & 0xf00) >> 8;
142
+
143
+    if (shift < 0x2 || shift > 0xd) {
144
+	result = sample;
145
+    } else if (shift < 0x8) {
146
+        shift--;
147
+	result = (sample - (256 * shift)) << shift;
148
+    } else {
149
+	shift = 0xe - shift;
150
+	result = ((sample + ((256 * shift) + 1)) << shift) - 1;
151
+    }
152
+
153
+    return result;
154
+}
155
+
156
+static int dv_audio_frame_size(const DVprofile* sys, int frame)
31 157
 {
32
-    AVStream *vst, *ast;
33
-    DVDemuxContext *c = s->priv_data;
158
+    return sys->audio_samples_dist[frame % (sizeof(sys->audio_samples_dist)/
159
+		                            sizeof(sys->audio_samples_dist[0]))];
160
+}
34 161
 
35
-    vst = av_new_stream(s, 0);
36
-    if (!vst)
37
-        return AVERROR_NOMEM;
38
-    vst->codec.codec_type = CODEC_TYPE_VIDEO;
39
-    vst->codec.codec_id = CODEC_ID_DVVIDEO;
40
-    vst->codec.bit_rate = 25000000;
162
+static int dv_write_pack(enum dv_pack_type pack_id, DVMuxContext *c, uint8_t* buf)
163
+{
164
+    struct tm tc;
165
+    time_t ct;
166
+    int ltc_frame;
41 167
 
42
-    ast = av_new_stream(s, 1);
43
-    if (!ast)
44
-        return AVERROR_NOMEM;
168
+    buf[0] = (uint8_t)pack_id;
169
+    switch (pack_id) {
170
+    case dv_header525: /* I can't imagine why these two weren't defined as real */
171
+    case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
172
+          buf[1] = 0xf8 |               /* reserved -- always 1 */
173
+	           (0 & 0x07);          /* APT: Track application ID */
174
+          buf[2] = (0 << 7)    | /* TF1: audio data is 0 - valid; 1 - invalid */
175
+	           (0x0f << 3) | /* reserved -- always 1 */
176
+		   (0 & 0x07);   /* AP1: Audio application ID */
177
+          buf[3] = (0 << 7)    | /* TF2: video data is 0 - valid; 1 - invalid */  
178
+	           (0x0f << 3) | /* reserved -- always 1 */
179
+		   (0 & 0x07);   /* AP2: Video application ID */
180
+          buf[4] = (0 << 7)    | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */ 
181
+	           (0x0f << 3) | /* reserved -- always 1 */
182
+		   (0 & 0x07);   /* AP3: Subcode application ID */
183
+	  break;
184
+    case dv_timecode:
185
+          ct = (time_t)(c->frames / ((float)c->sys->frame_rate / 
186
+                                     (float)c->sys->frame_rate_base));
187
+          localtime_r(&ct, &tc);
188
+          /* 
189
+           * LTC drop-frame frame counter drops two frames (0 and 1) every 
190
+           * minute, unless it is exactly divisible by 10
191
+           */
192
+          ltc_frame = (c->frames + 2*ct/60 - 2*ct/600) % c->sys->ltc_divisor;
193
+	  buf[1] = (0 << 7) | /* Color fame: 0 - unsync; 1 - sync mode */
194
+		   (1 << 6) | /* Drop frame timecode: 0 - nondrop; 1 - drop */
195
+		   ((ltc_frame / 10) << 4) | /* Tens of frames */
196
+		   (ltc_frame % 10);         /* Units of frames */
197
+	  buf[2] = (1 << 7) | /* Biphase mark polarity correction: 0 - even; 1 - odd */
198
+		   ((tc.tm_sec / 10) << 4) | /* Tens of seconds */
199
+		   (tc.tm_sec % 10);         /* Units of seconds */
200
+	  buf[3] = (1 << 7) | /* Binary group flag BGF0 */
201
+		   ((tc.tm_min / 10) << 4) | /* Tens of minutes */
202
+		   (tc.tm_min % 10);         /* Units of minutes */
203
+	  buf[4] = (1 << 7) | /* Binary group flag BGF2 */
204
+		   (1 << 6) | /* Binary group flag BGF1 */
205
+	           ((tc.tm_hour / 10) << 4) | /* Tens of hours */
206
+		   (tc.tm_hour % 10);         /* Units of hours */
207
+          break;
208
+    case dv_audio_source:  /* AAUX source pack */
209
+          buf[1] = (0 << 7) | /* locked mode       */
210
+                   (1 << 6) | /* reserved -- always 1 */
211
+	           (dv_audio_frame_size(c->sys, c->frames) -
212
+		    c->sys->audio_min_samples[0]);
213
+	                      /* # of samples      */
214
+          buf[2] = (0 << 7) | /* multi-stereo      */
215
+                   (0 << 5) | /* #of audio channels per block: 0 -- 1 channel */
216
+                   (0 << 4) | /* pair bit: 0 -- one pair of channels */
217
+	            0;        /* audio mode        */
218
+          buf[3] = (1 << 7) | /* res               */
219
+                   (1 << 6) | /* multi-language flag */
220
+	           (c->sys->dsf << 5) | /*  system: 60fields/50fields */
221
+	            0;        /* definition: 0 -- SD (525/625) */
222
+          buf[4] = (1 << 7) | /* emphasis: 1 -- off */
223
+                   (0 << 6) | /* emphasis time constant: 0 -- reserved */
224
+	           (0 << 3) | /* frequency: 0 -- 48Khz, 1 -- 44,1Khz, 2 -- 32Khz */
225
+                    0;        /* quantization: 0 -- 16bit linear, 1 -- 12bit nonlinear */			    
226
+          break;
227
+    case dv_audio_control:
228
+          buf[1] = (0 << 6) | /* copy protection: 0 -- unrestricted */
229
+                   (1 << 4) | /* input source: 1 -- digital input */
230
+	           (3 << 2) | /* compression: 3 -- no information */
231
+	            0;        /* misc. info/SMPTE emphasis off */
232
+          buf[2] = (1 << 7) | /* recording start point: 1 -- no */
233
+                   (1 << 6) | /* recording end point: 1 -- no */
234
+	           (1 << 3) | /* recording mode: 1 -- original */
235
+	            7;         
236
+          buf[3] = (1 << 7) | /* direction: 1 -- forward */
237
+                    0x20;     /* speed */
238
+          buf[4] = (1 << 7) | /* reserved -- always 1 */
239
+                    0x7f;     /* genre category */
240
+	  break;
241
+    case dv_audio_recdate:
242
+    case dv_viedo_recdate:  /* VAUX recording date */
243
+          ct = c->start_time + (time_t)(c->frames / 
244
+	       ((float)c->sys->frame_rate / (float)c->sys->frame_rate_base));
245
+          localtime_r(&ct, &tc);
246
+	  buf[1] = 0xff; /* ds, tm, tens of time zone, units of time zone */
247
+	                 /* 0xff is very likely to be "unknown" */
248
+	  buf[2] = (3 << 6) | /* reserved -- always 1 */
249
+		   ((tc.tm_mday / 10) << 4) | /* Tens of day */
250
+		   (tc.tm_mday % 10);         /* Units of day */
251
+	  buf[3] = /* we set high 4 bits to 0, shouldn't we set them to week? */
252
+		   (tc.tm_mon % 10);         /* Units of month */
253
+	  buf[4] = (((tc.tm_year % 100) / 10) << 4) | /* Tens of year */
254
+		   (tc.tm_year % 10);                 /* Units of year */
255
+          break;
256
+    case dv_audio_rectime:  /* AAUX recording time */
257
+    case dv_video_rectime:  /* VAUX recording time */
258
+          ct = c->start_time + (time_t)(c->frames / 
259
+	       ((float)c->sys->frame_rate / (float)c->sys->frame_rate_base));
260
+          localtime_r(&ct, &tc);
261
+	  buf[1] = (3 << 6) | /* reserved -- always 1 */
262
+		   0x3f; /* tens of frame, units of frame: 0x3f - "unknown" ? */
263
+	  buf[2] = (1 << 7) | /* reserved -- always 1 */ 
264
+		   ((tc.tm_sec / 10) << 4) | /* Tens of seconds */
265
+		   (tc.tm_sec % 10);         /* Units of seconds */
266
+	  buf[3] = (1 << 7) | /* reserved -- always 1 */
267
+		   ((tc.tm_min / 10) << 4) | /* Tens of minutes */
268
+		   (tc.tm_min % 10);         /* Units of minutes */
269
+	  buf[4] = (3 << 6) | /* reserved -- always 1 */ 
270
+	           ((tc.tm_hour / 10) << 4) | /* Tens of hours */
271
+		   (tc.tm_hour % 10);         /* Units of hours */
272
+	  break;
273
+    case dv_video_source:
274
+	  buf[1] = 0xff; /* reserved -- always 1 */
275
+	  buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
276
+		   (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
277
+		   (3 << 4) | /* CLF: color frames id (see ITU-R BT.470-4) */
278
+		   0xf; /* reserved -- always 1 */
279
+	  buf[3] = (3 << 6) | /* reserved -- always 1 */
280
+		   (c->sys->dsf << 5) | /*  system: 60fields/50fields */
281
+		   0; /* signal type video compression */
282
+	  buf[4] = 0xff; /* VISC: 0xff -- no information */
283
+          break;
284
+    case dv_video_control:
285
+	  buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
286
+		   0x3f; /* reserved -- always 1 */
287
+	  buf[2] = 0xc8 | /* reserved -- always b11001xxx */
288
+		   c->aspect;
289
+	  buf[3] = (1 << 7) | /* Frame/field flag 1 -- frame, 0 -- field */
290
+		   (1 << 6) | /* First/second field flag 0 -- field 2, 1 -- field 1 */
291
+		   (1 << 5) | /* Frame change flag 0 -- same picture as before, 1 -- different */
292
+		   (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
293
+		   0xc; /* reserved -- always b1100 */
294
+	  buf[4] = 0xff; /* reserved -- always 1 */
295
+          break;
296
+    default:
297
+          buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
298
+    }
299
+    return 5;
300
+}
45 301
 
46
-    ast->codec.codec_type = CODEC_TYPE_AUDIO;
47
-    ast->codec.codec_id = CODEC_ID_DVAUDIO;
48
-    c->is_audio = 0;
302
+static inline int dv_write_dif_id(enum dv_section_type t, uint8_t seq_num, 
303
+                                  uint8_t dif_num, uint8_t* buf)
304
+{
305
+    buf[0] = (uint8_t)t;    /* Section type */
306
+    buf[1] = (seq_num<<4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */
307
+	     (0 << 3) |     /* FSC: for 50Mb/s 0 - first channel; 1 - second */
308
+	     7;             /* reserved -- always 1 */
309
+    buf[2] = dif_num;       /* DIF block number Video: 0-134, Audio: 0-8 */
310
+    return 3;
311
+}
49 312
 
50
-    return 0;
313
+static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf)
314
+{
315
+    if (syb_num == 0 || syb_num == 6) {
316
+	buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */
317
+		 (0<<4)  | /* AP3 (Subcode application ID) */
318
+		 0x0f;     /* reserved -- always 1 */
319
+    } 
320
+    else if (syb_num == 11) {
321
+	buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */
322
+                 0x7f;     /* reserved -- always 1 */
323
+    }
324
+    else {
325
+	buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */
326
+                 (0<<4)  | /* APT (Track application ID) */
327
+		 0x0f;     /* reserved -- always 1 */
328
+    }
329
+    buf[1] = 0xf0 |            /* reserved -- always 1 */
330
+             (syb_num & 0x0f); /* SSYB number 0 - 11   */
331
+    buf[2] = 0xff;             /* reserved -- always 1 */
332
+    return 3;
333
+}
334
+
335
+static void dv_format_frame(DVMuxContext *c, uint8_t* buf)
336
+{
337
+    int i, j, k;
338
+    
339
+    for (i = 0; i < c->sys->difseg_size; i++) {
340
+       memset(buf, 0xff, 80 * 6); /* First 6 DIF blocks are for control data */
341
+       
342
+       /* DV header: 1DIF */
343
+       buf += dv_write_dif_id(dv_sect_header, i, 0, buf);
344
+       buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
345
+       buf += 72; /* unused bytes */
346
+				   
347
+       /* DV subcode: 2DIFs */
348
+       for (j = 0; j < 2; j++) {
349
+          buf += dv_write_dif_id( dv_sect_subcode, i, j, buf);
350
+	  for (k = 0; k < 6; k++) {
351
+	     buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf);
352
+	     buf += dv_write_pack(dv_ssyb_packs_dist[i][k], c, buf);
353
+	  }
354
+	  buf += 29; /* unused bytes */
355
+       }
356
+       
357
+       /* DV VAUX: 3DIFs */
358
+       for (j = 0; j < 3; j++) {
359
+	  buf += dv_write_dif_id(dv_sect_vaux, i, j, buf);
360
+	  for (k = 0; k < 15 ; k++)
361
+	     buf += dv_write_pack(dv_vaux_packs_dist[i][k], c, buf);
362
+	  buf += 2; /* unused bytes */
363
+       } 
364
+       
365
+       /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
366
+       for (j = 0; j < 135; j++) {
367
+            if (j%15 == 0) {
368
+	        buf += dv_write_dif_id(dv_sect_audio, i, j/15, buf);
369
+	        buf += dv_write_pack(dv_aaux_packs_dist[i][j/15], c, buf);
370
+		buf += 72; /* shuffled PCM audio */
371
+	    }
372
+	    buf += dv_write_dif_id(dv_sect_video, i, j, buf);
373
+	    buf += 77; /* 1 video macro block: 1 bytes control
374
+			                       4 * 14 bytes Y 8x8 data
375
+			                           10 bytes Cr 8x8 data
376
+						   10 bytes Cb 8x8 data */
377
+       }
378
+    }
379
+}
380
+
381
+static void dv_inject_audio(DVMuxContext *c, const uint8_t* pcm, uint8_t* frame_ptr)
382
+{
383
+    int i, j, d, of;
384
+    for (i = 0; i < c->sys->difseg_size; i++) {
385
+       frame_ptr += 6 * 80; /* skip DIF segment header */
386
+       for (j = 0; j < 9; j++) {
387
+          for (d = 8; d < 80; d+=2) {
388
+	     of = c->sys->audio_shuffle[i][j] + (d - 8)/2 * c->sys->audio_stride;
389
+	     frame_ptr[d] = pcm[of*2+1]; // FIXME: may be we have to admit
390
+	     frame_ptr[d+1] = pcm[of*2]; //        that DV is a big endian PCM       
391
+          }
392
+          frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
393
+       }
394
+    }
395
+}
396
+
397
+static void dv_inject_video(DVMuxContext *c, const uint8_t* video_data, uint8_t* frame_ptr)
398
+{
399
+    int i, j;
400
+    int ptr = 0;
401
+
402
+    for (i = 0; i < c->sys->difseg_size; i++) {
403
+       ptr += 6 * 80; /* skip DIF segment header */
404
+       for (j = 0; j < 135; j++) {
405
+            if (j%15 == 0)
406
+	        ptr += 80; /* skip Audio DIF */
407
+	    ptr += 3;
408
+	    memcpy(frame_ptr + ptr, video_data + ptr, 77);
409
+	    ptr += 77;
410
+       }
411
+    }
412
+}
413
+
414
+/* 
415
+ * This is the dumbest implementation of all -- it simply looks at
416
+ * a fixed offset and if pack isn't there -- fails. We might want
417
+ * to have a fallback mechanism for complete search of missing packs.
418
+ */
419
+static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
420
+{
421
+    int offs;
422
+    
423
+    switch (t) {
424
+    case dv_audio_source:
425
+          offs = (80*6 + 80*16*3 + 3);
426
+	  break;
427
+    case dv_audio_control:
428
+          offs = (80*6 + 80*16*4 + 3);
429
+	  break;
430
+    case dv_video_control:
431
+          offs = (80*5 + 48 + 5);
432
+          break;
433
+    default:
434
+          return NULL;
435
+    }   
436
+
437
+    return (frame[offs] == t ? &frame[offs] : NULL);
438
+}
439
+
440
+/* 
441
+ * There's a couple of assumptions being made here:
442
+ * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples.
443
+ *    We can pass them upwards when ffmpeg will be ready to deal with them.
444
+ * 2. We don't do software emphasis.
445
+ * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
446
+ *    are converted into 16bit linear ones.
447
+ */
448
+static int dv_extract_audio(uint8_t* frame, uint8_t* pcm)
449
+{
450
+    int size, i, j, d, of, smpls, freq, quant;
451
+    uint16_t lc, rc;
452
+    const DVprofile* sys;
453
+    const uint8_t* as_pack;
454
+    
455
+    as_pack = dv_extract_pack(frame, dv_audio_source);
456
+    if (!as_pack)    /* No audio ? */
457
+	return 0;
458
+   
459
+    sys = dv_frame_profile(frame);
460
+    smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */
461
+    freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */
462
+    quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
463
+    
464
+    if (quant > 1)
465
+	return -1; /* Unsupported quantization */
466
+
467
+    size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
468
+
469
+    /* for each DIF segment */
470
+    for (i = 0; i < sys->difseg_size; i++) {
471
+       frame += 6 * 80; /* skip DIF segment header */
472
+       for (j = 0; j < 9; j++) {
473
+          for (d = 8; d < 80; d += 2) {
474
+	     if (quant == 0) {  /* 16bit quantization */
475
+		 of = sys->audio_shuffle[i][j] + (d - 8)/2 * sys->audio_stride;
476
+                 if (of*2 >= size)
477
+		     continue;
478
+		 
479
+		 pcm[of*2] = frame[d+1]; // FIXME: may be we have to admit
480
+		 pcm[of*2+1] = frame[d]; //        that DV is a big endian PCM
481
+		 if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
482
+		     pcm[of*2+1] = 0;
483
+	      } else {           /* 12bit quantization */
484
+		 if (i >= sys->difseg_size/2)
485
+	             goto out;  /* We're not doing 4ch at this time */
486
+		       
487
+		 lc = ((uint16_t)frame[d] << 4) | 
488
+		      ((uint16_t)frame[d+2] >> 4);
489
+		 rc = ((uint16_t)frame[d+1] << 4) |
490
+	              ((uint16_t)frame[d+2] & 0x0f);
491
+		 lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
492
+		 rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
493
+
494
+		 of = sys->audio_shuffle[i][j] + (d - 8)/3 * sys->audio_stride;
495
+                 if (of*2 >= size)
496
+		     continue;
497
+
498
+		 pcm[of*2] = lc & 0xff; // FIXME: may be we have to admit
499
+		 pcm[of*2+1] = lc >> 8; //        that DV is a big endian PCM
500
+		 of = sys->audio_shuffle[i+sys->difseg_size/2][j] + 
501
+		      (d - 8)/3 * sys->audio_stride;
502
+		 pcm[of*2] = rc & 0xff; // FIXME: may be we have to admit
503
+		 pcm[of*2+1] = rc >> 8; //        that DV is a big endian PCM
504
+		 ++d;
505
+	      }
506
+	  }
507
+		
508
+	  frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
509
+        }
510
+    }
511
+
512
+out:
513
+    return size;
514
+}
515
+
516
+static int dv_extract_audio_info(uint8_t* frame, AVCodecContext* avctx)
517
+{
518
+    const uint8_t* as_pack;
519
+    const DVprofile* sys;
520
+    int freq, smpls;
521
+
522
+    sys = dv_frame_profile(frame);
523
+    as_pack = dv_extract_pack(frame, dv_audio_source);
524
+    if (!as_pack || !sys)    /* No audio ? */
525
+	return -1;
526
+    
527
+    smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */
528
+    freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */
529
+   
530
+    avctx->sample_rate = dv_audio_frequency[freq];
531
+    avctx->channels = 2;
532
+    avctx->bit_rate = avctx->channels * avctx->sample_rate * 16;
533
+
534
+    return (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */;
535
+}
536
+
537
+static int dv_extract_video_info(uint8_t* frame, AVCodecContext* avctx)
538
+{
539
+    const DVprofile* sys; 
540
+    const uint8_t* vsc_pack;
541
+    int apt;
542
+    int size = 0;
543
+    
544
+    sys = dv_frame_profile(frame);
545
+    if (sys) {
546
+        apt = frame[4] & 0x07;
547
+        avctx->frame_rate = sys->frame_rate;
548
+        avctx->frame_rate_base = sys->frame_rate_base;
549
+        avctx->width = sys->width;
550
+        avctx->height = sys->height;
551
+        avctx->pix_fmt = sys->pix_fmt;
552
+        vsc_pack = dv_extract_pack(frame, dv_video_control);
553
+        if (vsc_pack && (vsc_pack[2] & 0x07) == (apt?0x02:0x07))
554
+            avctx->aspect_ratio = 16.0 / 9.0;
555
+        else
556
+            avctx->aspect_ratio = 4.0 / 3.0;
557
+	size = sys->frame_size;
558
+    }
559
+    return size;
560
+}
561
+
562
+/* 
563
+ * The following 6 functions constitute our interface to the world
564
+ */
565
+
566
+int dv_assemble_frame(DVMuxContext *c, AVStream* st,
567
+                      const uint8_t* data, int data_size, uint8_t** frame)
568
+{
569
+    uint8_t pcm[8192];
570
+    int fsize, reqasize;
571
+   
572
+    *frame = &c->frame_buf[0];
573
+    if (c->has_audio && c->has_video) {  /* must be a stale frame */
574
+        dv_format_frame(c, *frame);
575
+	c->frames++;
576
+	c->has_audio = c->has_video = 0;
577
+    }
578
+    
579
+    if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
580
+        /* FIXME: we have to have more sensible approach than this one */
581
+	if (c->has_video)
582
+	    fprintf(stderr, "Can't process DV frame #%d. Insufficient audio data or severe sync problem.\n", c->frames);
583
+	    
584
+        dv_inject_video(c, data, *frame);
585
+	c->has_video = 1;
586
+	data_size = 0;
587
+    } 
588
+    
589
+    reqasize = 4 * dv_audio_frame_size(c->sys, c->frames);
590
+    fsize = fifo_size(&c->audio_data, c->audio_data.rptr);
591
+    if (st->codec.codec_type == CODEC_TYPE_AUDIO || (c->has_video && fsize >= reqasize)) { 
592
+	if (fsize + data_size >= reqasize && !c->has_audio) {
593
+            if (fsize >= reqasize) {
594
+	        fifo_read(&c->audio_data, &pcm[0], reqasize, &c->audio_data.rptr);
595
+            } else {
596
+	        fifo_read(&c->audio_data, &pcm[0], fsize, &c->audio_data.rptr);
597
+                memcpy(&pcm[fsize], &data[0], reqasize - fsize);
598
+		data += reqasize - fsize;
599
+		data_size -= reqasize - fsize;
600
+	    }
601
+	    dv_inject_audio(c, &pcm[0], *frame);
602
+	    c->has_audio = 1;
603
+	}
604
+    
605
+        /* FIXME: we have to have more sensible approach than this one */
606
+        if (fifo_size(&c->audio_data, c->audio_data.rptr) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE)
607
+	    fprintf(stderr, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames);
608
+	fifo_write(&c->audio_data, (uint8_t *)data, data_size, &c->audio_data.wptr);
609
+    }
610
+
611
+    return (c->has_audio && c->has_video) ? c->sys->frame_size : 0;
612
+}
613
+
614
+DVMuxContext* dv_init_mux(AVFormatContext* s)
615
+{
616
+    DVMuxContext *c;
617
+    AVStream *vst;
618
+    AVStream *ast;
619
+
620
+    c = av_mallocz(sizeof(DVMuxContext));
621
+    if (!c)
622
+        return NULL;
623
+
624
+    if (s->nb_streams != 2)
625
+        goto bail_out;
626
+
627
+    /* We have to sort out where audio and where video stream is */
628
+    if (s->streams[0]->codec.codec_type == CODEC_TYPE_VIDEO &&
629
+        s->streams[1]->codec.codec_type == CODEC_TYPE_AUDIO) {
630
+       vst = s->streams[0];
631
+       ast = s->streams[1];
632
+    }
633
+    else if (s->streams[1]->codec.codec_type == CODEC_TYPE_VIDEO &&
634
+             s->streams[0]->codec.codec_type == CODEC_TYPE_AUDIO) {
635
+           vst = s->streams[1];
636
+           ast = s->streams[0];
637
+    } else
638
+        goto bail_out;
639
+  
640
+    /* Some checks -- DV format is very picky about its incoming streams */
641
+    if (vst->codec.codec_id != CODEC_ID_DVVIDEO ||
642
+	ast->codec.codec_id != CODEC_ID_PCM_S16LE)
643
+       goto bail_out;
644
+    if (ast->codec.sample_rate != 48000 ||
645
+	ast->codec.channels != 2)
646
+       goto bail_out;
647
+
648
+    c->sys = dv_codec_profile(&vst->codec);
649
+    if (!c->sys)
650
+	goto bail_out;
651
+    
652
+    /* Ok, everything seems to be in working order */
653
+    c->frames = 0;
654
+    c->has_audio = c->has_video = 0;
655
+    c->start_time = time(NULL);
656
+    c->aspect = 0; /* 4:3 is the default */
657
+    if (vst->codec.aspect_ratio == 16.0 / 9.0)
658
+        c->aspect = 0x07;
659
+
660
+    if (fifo_init(&c->audio_data, 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) < 0)
661
+        goto bail_out;
662
+
663
+    dv_format_frame(c, &c->frame_buf[0]);
664
+
665
+    return c;
666
+    
667
+bail_out:
668
+    av_free(c);
669
+    return NULL;
670
+}
671
+
672
+void dv_delete_mux(DVMuxContext *c)
673
+{    
674
+    fifo_free(&c->audio_data);
675
+    av_free(c);
676
+}
677
+
678
+DVDemuxContext* dv_init_demux(AVFormatContext *s, int vid, int aid)
679
+{
680
+    DVDemuxContext *c;
681
+
682
+    c = av_mallocz(sizeof(DVDemuxContext));
683
+    if (!c)
684
+        return NULL;
685
+
686
+    c->vst = (vid < s->nb_streams) ? s->streams[vid] : av_new_stream(s, vid);
687
+    c->ast = (aid < s->nb_streams) ? s->streams[aid] : av_new_stream(s, aid);
688
+    if (!c->vst || !c->ast)
689
+        goto fail;
690
+	
691
+    c->vst->codec.codec_type = CODEC_TYPE_VIDEO;
692
+    c->vst->codec.codec_id = CODEC_ID_DVVIDEO;
693
+    c->vst->codec.bit_rate = 25000000;
694
+    
695
+    c->ast->codec.codec_type = CODEC_TYPE_AUDIO;
696
+    c->ast->codec.codec_id = CODEC_ID_PCM_S16LE;
697
+    
698
+    c->audio_pkt.size = 0;
699
+    
700
+    return c;
701
+    
702
+fail:
703
+    if (c->vst)
704
+        av_free(c->vst);
705
+    if (c->ast)
706
+        av_free(c->ast);
707
+    av_free(c);
708
+    return NULL;
51 709
 }
52 710
 
53 711
 static void __destruct_pkt(struct AVPacket *pkt)
... ...
@@ -56,43 +720,99 @@ static void __destruct_pkt(struct AVPacket *pkt)
56 56
     return;
57 57
 }
58 58
 
59
-static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
59
+int dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
60 60
 {
61
-    int ret;
62
-    DVDemuxContext *c = s->priv_data;
63
-    
64
-    if (!c->is_audio) {
65
-        ret = get_buffer(&s->pb, c->buf, 4);
66
-        if (ret <= 0) 
67
-            return -EIO;
68
-	c->size = dv_frame_profile(&c->buf[0])->frame_size;
69
-	
70
-	ret = get_buffer(&s->pb, c->buf + 4, c->size - 4);
71
-	if (ret <= 0)
72
-	    return -EIO;
61
+    int size = -1;
62
+
63
+    if (c->audio_pkt.size) {
64
+        *pkt = c->audio_pkt;
65
+	c->audio_pkt.size = 0;
66
+	size = pkt->size;
73 67
     }
68
+
69
+    return size;
70
+}
71
+
72
+int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, 
73
+                      uint8_t* buf, int buf_size)
74
+{
75
+    int size;
76
+   
77
+    if (buf_size < 4 || buf_size < dv_frame_profile(buf)->frame_size)
78
+        return -1;   /* Broken frame, or not enough data */
79
+
80
+    /* Queueing audio packet */
81
+    /* FIXME: in case of no audio/bad audio we have to do something */
82
+    size = dv_extract_audio_info(buf, &c->ast->codec);
83
+    if (av_new_packet(&c->audio_pkt, size) < 0)
84
+        return AVERROR_NOMEM;
85
+    dv_extract_audio(buf, c->audio_pkt.data);
86
+    c->audio_pkt.size = size;
87
+    c->audio_pkt.stream_index = c->ast->id;
74 88
     
89
+    /* Now it's time to return video packet */
90
+    size = dv_extract_video_info(buf, &c->vst->codec);
75 91
     av_init_packet(pkt);
76 92
     pkt->destruct = __destruct_pkt;
77
-    pkt->data     = c->buf;
78
-    pkt->size     = c->size;
79
-    pkt->stream_index = c->is_audio;
93
+    pkt->data     = buf;
94
+    pkt->size     = size; 
80 95
     pkt->flags   |= PKT_FLAG_KEY;
96
+    pkt->stream_index = c->vst->id;
81 97
     
82
-    c->is_audio = !c->is_audio;
83
-    return c->size;
98
+    return size;
99
+}
100
+                           
101
+/************************************************************
102
+ * Implementation of the easiest DV storage of all -- raw DV.
103
+ ************************************************************/
104
+ 
105
+typedef struct RawDVContext {
106
+    void*     dv_demux;
107
+    uint8_t   buf[144000];
108
+} RawDVContext;
109
+
110
+static int dv_read_header(AVFormatContext *s,
111
+                          AVFormatParameters *ap)
112
+{
113
+    RawDVContext *c = s->priv_data;
114
+    c->dv_demux = dv_init_demux(s, 0, 1);
115
+   
116
+    return c->dv_demux ? 0 : -1;
117
+}
118
+
119
+
120
+static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
121
+{
122
+    int size;
123
+    RawDVContext *c = s->priv_data; 
124
+  
125
+    size = dv_get_packet(c->dv_demux, pkt);
126
+    
127
+    if (size < 0) {
128
+        if (get_buffer(&s->pb, c->buf, 4) <= 0) 
129
+            return -EIO;
130
+    
131
+        size = dv_frame_profile(c->buf)->frame_size;
132
+        if (get_buffer(&s->pb, c->buf + 4, size - 4) <= 0)
133
+	    return -EIO;
134
+
135
+	size = dv_produce_packet(c->dv_demux, pkt, c->buf, size);
136
+    } 
137
+    
138
+    return size;
84 139
 }
85 140
 
86 141
 static int dv_read_close(AVFormatContext *s)
87 142
 {
143
+    RawDVContext *c = s->priv_data;
144
+    av_free(c->dv_demux);
88 145
     return 0;
89 146
 }
90 147
 
91
-int dv_write_header(struct AVFormatContext *s)
148
+static int dv_write_header(AVFormatContext *s)
92 149
 {
93
-    DVMuxContext *c = s->priv_data;
94
-    
95
-    if (s->nb_streams != 2 || dv_core_init(c, s->streams) != 0) {
150
+    s->priv_data = dv_init_mux(s);
151
+    if (!s->priv_data) {
96 152
         fprintf(stderr, "Can't initialize DV format!\n"
97 153
 		    "Make sure that you supply exactly two streams:\n"
98 154
 		    "     video: 25fps or 29.97fps, audio: 2ch/48Khz/PCM\n");
... ...
@@ -101,23 +821,20 @@ int dv_write_header(struct AVFormatContext *s)
101 101
     return 0;
102 102
 }
103 103
 
104
-int dv_write_packet(struct AVFormatContext *s, 
105
-                    int stream_index,
106
-                    const uint8_t *buf, int size, int64_t pts)
104
+static int dv_write_packet(struct AVFormatContext *s, 
105
+                           int stream_index,
106
+                           const uint8_t *buf, int size, int64_t pts)
107 107
 {
108
-    DVMuxContext *c = s->priv_data;
108
+    uint8_t* frame;
109
+    int fsize;
109 110
    
110
-    if (stream_index == c->vst)
111
-        dv_assemble_frame(c, buf, NULL, 0);
112
-    else
113
-        dv_assemble_frame(c, NULL, buf, size);
114
-   
115
-    if (c->has_audio && c->has_video) {
116
-        put_buffer(&s->pb, &c->frame_buf[0], c->sys->frame_size);
111
+    fsize = dv_assemble_frame((DVMuxContext *)s->priv_data, s->streams[stream_index],
112
+                              buf, size, &frame);
113
+    if (fsize > 0) {
114
+        put_buffer(&s->pb, frame, fsize); 
117 115
         put_flush_packet(&s->pb);
118
-    }
119
-    
120
-    return 0;
116
+    } 
117
+    return fsize;
121 118
 }
122 119
 
123 120
 /* 
... ...
@@ -126,16 +843,16 @@ int dv_write_packet(struct AVFormatContext *s,
126 126
  * Currently we simply drop the last frame. I don't know whether this 
127 127
  * is the best strategy of all
128 128
  */
129
-int dv_write_trailer(struct AVFormatContext *s)
129
+static int dv_write_trailer(struct AVFormatContext *s)
130 130
 {
131
-    dv_core_delete((DVMuxContext *)s->priv_data);
131
+    dv_delete_mux((DVMuxContext *)s->priv_data);
132 132
     return 0;
133 133
 }
134 134
 
135 135
 static AVInputFormat dv_iformat = {
136 136
     "dv",
137 137
     "DV video format",
138
-    sizeof(DVDemuxContext),
138
+    sizeof(RawDVContext),
139 139
     NULL,
140 140
     dv_read_header,
141 141
     dv_read_packet,
... ...
@@ -143,7 +860,7 @@ static AVInputFormat dv_iformat = {
143 143
     .extensions = "dv",
144 144
 };
145 145
 
146
-AVOutputFormat dv_oformat = {
146
+static AVOutputFormat dv_oformat = {
147 147
     "dv",
148 148
     "DV video format",
149 149
     NULL,
150 150
new file mode 100644
... ...
@@ -0,0 +1,32 @@
0
+/* 
1
+ * General DV muxer/demuxer 
2
+ * Copyright (c) 2003 Roman Shaposhnick
3
+ *
4
+ * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
5
+ * of DV technical info.
6
+ *
7
+ * Raw DV format
8
+ * Copyright (c) 2002 Fabrice Bellard.
9
+ *
10
+ * This library is free software; you can redistribute it and/or
11
+ * modify it under the terms of the GNU Lesser General Public
12
+ * License as published by the Free Software Foundation; either
13
+ * version 2 of the License, or (at your option) any later version.
14
+ *
15
+ * This library is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
+ * Lesser General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU Lesser General Public
21
+ * License along with this library; if not, write to the Free Software
22
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
+ */
24
+ 
25
+void* dv_init_demux(AVFormatContext *s, int vid, int aid);
26
+int dv_get_packet(void*, AVPacket *);
27
+int dv_produce_packet(void*, AVPacket*, uint8_t*, int);
28
+
29
+void* dv_init_mux(AVFormatContext* s);
30
+int dv_assemble_frame(void *c, AVStream*, const uint8_t*, int, uint8_t**);
31
+void dv_delete_mux(void*);
... ...
@@ -31,13 +31,11 @@
31 31
 #undef DV1394_DEBUG
32 32
 
33 33
 #include "dv1394.h"
34
+#include "dv.h"
34 35
 
35 36
 struct dv1394_data {
36 37
     int fd;
37 38
     int channel;
38
-    int width, height;
39
-    int frame_rate;
40
-    int frame_size;
41 39
     int format;
42 40
 
43 41
     void *ring; /* Ring buffer */
... ...
@@ -45,9 +43,9 @@ struct dv1394_data {
45 45
     int avail;  /* Number of frames available for reading */
46 46
     int done;   /* Number of completed frames */
47 47
 
48
-    int stream; /* Current stream. 0 - video, 1 - audio */
49 48
     int64_t pts;  /* Current timestamp */
50
-    AVStream *vst, *ast;
49
+
50
+    void* dv_demux; /* Generic DV muxing/demuxing context */
51 51
 };
52 52
 
53 53
 /* 
... ...
@@ -69,7 +67,6 @@ static int dv1394_reset(struct dv1394_data *dv)
69 69
         return -1;
70 70
 
71 71
     dv->avail  = dv->done = 0;
72
-    dv->stream = 0;
73 72
     return 0;
74 73
 }
75 74
 
... ...
@@ -88,14 +85,9 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
88 88
     struct dv1394_data *dv = context->priv_data;
89 89
     const char *video_device;
90 90
 
91
-    dv->vst = av_new_stream(context, 0);
92
-    if (!dv->vst)
93
-        return -ENOMEM;
94
-    dv->ast = av_new_stream(context, 1);
95
-    if (!dv->ast) {
96
-        av_free(dv->vst);
97
-        return -ENOMEM;
98
-    }
91
+    dv->dv_demux = dv_init_demux(context, 0, 1);
92
+    if (!dv->dv_demux)
93
+        goto failed;
99 94
 
100 95
     if (ap->standard && !strcasecmp(ap->standard, "pal"))
101 96
 	dv->format = DV1394_PAL;
... ...
@@ -107,17 +99,6 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
107 107
     else
108 108
         dv->channel = DV1394_DEFAULT_CHANNEL;
109 109
 
110
-    dv->width = DV1394_WIDTH;
111
-    if (dv->format == DV1394_NTSC) {
112
-	dv->height = DV1394_NTSC_HEIGHT;
113
-        dv->frame_size = DV1394_NTSC_FRAME_SIZE;
114
-        dv->frame_rate = 30;
115
-    } else {
116
-	dv->height = DV1394_PAL_HEIGHT;
117
-        dv->frame_size = DV1394_PAL_FRAME_SIZE;
118
-        dv->frame_rate = 25;
119
-    }
120
-
121 110
     /* Open and initialize DV1394 device */
122 111
     video_device = ap->device;
123 112
     if (!video_device)
... ...
@@ -140,21 +121,6 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
140 140
         goto failed;
141 141
     }
142 142
 
143
-    dv->stream = 0;
144
-
145
-    dv->vst->codec.codec_type = CODEC_TYPE_VIDEO;
146
-    dv->vst->codec.codec_id   = CODEC_ID_DVVIDEO;
147
-    dv->vst->codec.width      = dv->width;
148
-    dv->vst->codec.height     = dv->height;
149
-    dv->vst->codec.frame_rate = dv->frame_rate;
150
-    dv->vst->codec.frame_rate_base = 1;
151
-    dv->vst->codec.bit_rate   = 25000000;  /* Consumer DV is 25Mbps */
152
-
153
-    dv->ast->codec.codec_type = CODEC_TYPE_AUDIO;
154
-    dv->ast->codec.codec_id   = CODEC_ID_DVAUDIO;
155
-    dv->ast->codec.channels   = 2;
156
-    dv->ast->codec.sample_rate= 48000;
157
-
158 143
     av_set_pts_info(context, 48, 1, 1000000);
159 144
 
160 145
     if (dv1394_start(dv) < 0)
... ...
@@ -164,55 +130,17 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
164 164
 
165 165
 failed:
166 166
     close(dv->fd);
167
-    av_free(dv->vst);
168
-    av_free(dv->ast);
169 167
     return -EIO;
170 168
 }
171 169
 
172
-static void __destruct_pkt(struct AVPacket *pkt)
173
-{
174
-    pkt->data = NULL; pkt->size = 0;
175
-    return;
176
-}
177
-
178
-static inline int __get_frame(struct dv1394_data *dv, AVPacket *pkt)
179
-{
180
-    char *ptr = dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE);
181
-
182
-    if (dv->stream) {
183
-        dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
184
-        dv->done++; dv->avail--;
185
-    } else {
186
-        dv->pts = av_gettime() & ((1LL << 48) - 1);
187
-    }
188
-
189
-    dv->format = ((ptr[3] & 0x80) == 0) ? DV1394_NTSC : DV1394_PAL;
190
-    if (dv->format == DV1394_NTSC) {
191
-        dv->frame_size = DV1394_NTSC_FRAME_SIZE;
192
-        dv->vst->codec.height = dv->height = DV1394_NTSC_HEIGHT;
193
-        dv->vst->codec.frame_rate = dv->frame_rate = 30;
194
-    } else {
195
-        dv->frame_size = DV1394_PAL_FRAME_SIZE;
196
-        dv->vst->codec.height = dv->height = DV1394_PAL_HEIGHT;
197
-        dv->vst->codec.frame_rate = dv->frame_rate = 25;
198
-    }
199
-	
200
-    av_init_packet(pkt);
201
-    pkt->destruct = __destruct_pkt;
202
-    pkt->data     = ptr;
203
-    pkt->size     = dv->frame_size;
204
-    pkt->pts      = dv->pts;
205
-    pkt->stream_index = dv->stream;
206
-    pkt->flags   |= PKT_FLAG_KEY;
207
-
208
-    dv->stream ^= 1;
209
-
210
-    return dv->frame_size;
211
-}
212
-
213 170
 static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt)
214 171
 {
215 172
     struct dv1394_data *dv = context->priv_data;
173
+    int size;
174
+
175
+    size = dv_get_packet(dv->dv_demux, pkt);
176
+    if (size > 0)
177
+        goto out;
216 178
 
217 179
     if (!dv->avail) {
218 180
         struct dv1394_status s;
... ...
@@ -276,7 +204,16 @@ restart_poll:
276 276
             dv->done);
277 277
 #endif
278 278
 
279
-    return __get_frame(dv, pkt);
279
+    size = dv_produce_packet(dv->dv_demux, pkt, 
280
+                             dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE), 
281
+			     DV1394_PAL_FRAME_SIZE);
282
+    dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
283
+    dv->done++; dv->avail--;
284
+    dv->pts = av_gettime() & ((1LL << 48) - 1);
285
+    
286
+out:
287
+    pkt->pts = dv->pts;
288
+    return size;
280 289
 }
281 290
 
282 291
 static int dv1394_close(AVFormatContext * context)
... ...
@@ -292,6 +229,7 @@ static int dv1394_close(AVFormatContext * context)
292 292
         perror("Failed to munmap DV1394 ring buffer");
293 293
 
294 294
     close(dv->fd);
295
+    av_free(dv->dv_demux);
295 296
 
296 297
     return 0;
297 298
 }