Browse code

patch for DV capturing by Dan Dennedy <dan at dennedy dot org>

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

Roman Shaposhnik authored on 2003/08/06 14:40:38
Showing 2 changed files
... ...
@@ -47,8 +47,15 @@ struct dv1394_data {
47 47
 
48 48
     int stream; /* Current stream. 0 - video, 1 - audio */
49 49
     int64_t pts;  /* Current timestamp */
50
+    AVStream *vst, *ast;
50 51
 };
51 52
 
53
+/* 
54
+ * The trick here is to kludge around well known problem with kernel Ooopsing
55
+ * when you try to capture PAL on a device node configure for NTSC. That's 
56
+ * why we have to configure the device node for PAL, and then read only NTSC
57
+ * amount of data.
58
+ */
52 59
 static int dv1394_reset(struct dv1394_data *dv)
53 60
 {
54 61
     struct dv1394_init init;
... ...
@@ -56,7 +63,7 @@ static int dv1394_reset(struct dv1394_data *dv)
56 56
     init.channel     = dv->channel;
57 57
     init.api_version = DV1394_API_VERSION;
58 58
     init.n_frames    = DV1394_RING_FRAMES;
59
-    init.format      = dv->format;
59
+    init.format      = DV1394_PAL;
60 60
 
61 61
     if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
62 62
         return -1;
... ...
@@ -79,15 +86,14 @@ static int dv1394_start(struct dv1394_data *dv)
79 79
 static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
80 80
 {
81 81
     struct dv1394_data *dv = context->priv_data;
82
-    AVStream *vst, *ast;
83 82
     const char *video_device;
84 83
 
85
-    vst = av_new_stream(context, 0);
86
-    if (!vst)
84
+    dv->vst = av_new_stream(context, 0);
85
+    if (!dv->vst)
87 86
         return -ENOMEM;
88
-    ast = av_new_stream(context, 1);
89
-    if (!ast) {
90
-        av_free(vst);
87
+    dv->ast = av_new_stream(context, 1);
88
+    if (!dv->ast) {
89
+        av_free(dv->vst);
91 90
         return -ENOMEM;
92 91
     }
93 92
 
... ...
@@ -127,27 +133,27 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
127 127
         goto failed;
128 128
     }
129 129
 
130
-    dv->ring = mmap(NULL, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES,
130
+    dv->ring = mmap(NULL, DV1394_PAL_FRAME_SIZE * DV1394_RING_FRAMES,
131 131
                     PROT_READ, MAP_PRIVATE, dv->fd, 0);
132
-    if (!dv->ring) {
132
+    if (dv->ring == MAP_FAILED) {
133 133
         perror("Failed to mmap DV ring buffer");
134 134
         goto failed;
135 135
     }
136 136
 
137 137
     dv->stream = 0;
138 138
 
139
-    vst->codec.codec_type = CODEC_TYPE_VIDEO;
140
-    vst->codec.codec_id   = CODEC_ID_DVVIDEO;
141
-    vst->codec.width      = dv->width;
142
-    vst->codec.height     = dv->height;
143
-    vst->codec.frame_rate = dv->frame_rate;
144
-    vst->codec.frame_rate_base = 1;
145
-    vst->codec.bit_rate   = 25000000;  /* Consumer DV is 25Mbps */
139
+    dv->vst->codec.codec_type = CODEC_TYPE_VIDEO;
140
+    dv->vst->codec.codec_id   = CODEC_ID_DVVIDEO;
141
+    dv->vst->codec.width      = dv->width;
142
+    dv->vst->codec.height     = dv->height;
143
+    dv->vst->codec.frame_rate = dv->frame_rate;
144
+    dv->vst->codec.frame_rate_base = 1;
145
+    dv->vst->codec.bit_rate   = 25000000;  /* Consumer DV is 25Mbps */
146 146
 
147
-    ast->codec.codec_type = CODEC_TYPE_AUDIO;
148
-    ast->codec.codec_id   = CODEC_ID_DVAUDIO;
149
-    ast->codec.channels   = 2;
150
-    ast->codec.sample_rate= 48000;
147
+    dv->ast->codec.codec_type = CODEC_TYPE_AUDIO;
148
+    dv->ast->codec.codec_id   = CODEC_ID_DVAUDIO;
149
+    dv->ast->codec.channels   = 2;
150
+    dv->ast->codec.sample_rate= 48000;
151 151
 
152 152
     av_set_pts_info(context, 48, 1, 1000000);
153 153
 
... ...
@@ -158,8 +164,8 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
158 158
 
159 159
 failed:
160 160
     close(dv->fd);
161
-    av_free(vst);
162
-    av_free(ast);
161
+    av_free(dv->vst);
162
+    av_free(dv->ast);
163 163
     return -EIO;
164 164
 }
165 165
 
... ...
@@ -171,7 +177,7 @@ static void __destruct_pkt(struct AVPacket *pkt)
171 171
 
172 172
 static inline int __get_frame(struct dv1394_data *dv, AVPacket *pkt)
173 173
 {
174
-    char *ptr = dv->ring + (dv->index * dv->frame_size);
174
+    char *ptr = dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE);
175 175
 
176 176
     if (dv->stream) {
177 177
         dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
... ...
@@ -180,6 +186,17 @@ static inline int __get_frame(struct dv1394_data *dv, AVPacket *pkt)
180 180
         dv->pts = av_gettime() & ((1LL << 48) - 1);
181 181
     }
182 182
 
183
+    dv->format = ((ptr[3] & 0x80) == 0) ? DV1394_NTSC : DV1394_PAL;
184
+    if (dv->format == DV1394_NTSC) {
185
+        dv->frame_size = DV1394_NTSC_FRAME_SIZE;
186
+        dv->vst->codec.height = dv->height = DV1394_NTSC_HEIGHT;
187
+        dv->vst->codec.frame_rate = dv->frame_rate = 30;
188
+    } else {
189
+        dv->frame_size = DV1394_PAL_FRAME_SIZE;
190
+        dv->vst->codec.height = dv->height = DV1394_PAL_HEIGHT;
191
+        dv->vst->codec.frame_rate = dv->frame_rate = 25;
192
+    }
193
+	
183 194
     av_init_packet(pkt);
184 195
     pkt->destruct = __destruct_pkt;
185 196
     pkt->data     = ptr;
... ...
@@ -26,7 +26,7 @@
26 26
 #ifndef _DV_1394_H
27 27
 #define _DV_1394_H
28 28
 
29
-#define DV1394_DEFAULT_CHANNEL 0x63
29
+#define DV1394_DEFAULT_CHANNEL 63
30 30
 #define DV1394_DEFAULT_CARD    0
31 31
 #define DV1394_RING_FRAMES     20
32 32
 
... ...
@@ -199,12 +199,12 @@
199 199
 #define DV1394_MAX_FRAMES 32
200 200
 
201 201
 /* number of *full* isochronous packets per DV frame */
202
-#define DV1394_NTSC_PACKETS_PER_FRAME 300
203
-#define DV1394_PAL_PACKETS_PER_FRAME  250
202
+#define DV1394_NTSC_PACKETS_PER_FRAME 250
203
+#define DV1394_PAL_PACKETS_PER_FRAME  300
204 204
 
205 205
 /* size of one frame's worth of DV data, in bytes */
206 206
 #define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME)
207
-#define DV1394_PAL_FRAME_SIZE  (576 * DV1394_PAL_PACKETS_PER_FRAME)
207
+#define DV1394_PAL_FRAME_SIZE  (480 * DV1394_PAL_PACKETS_PER_FRAME)
208 208
 
209 209
 
210 210
 /* ioctl() commands */