Browse code

dv patch by Max Krasnyansky (maxk at qualcomm dot com)

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

Max Krasnyansky authored on 2003/01/23 07:40:52
Showing 7 changed files
... ...
@@ -53,6 +53,7 @@ gprof="no"
53 53
 v4l="yes"
54 54
 audio_oss="yes"
55 55
 audio_beos="no"
56
+dv1394="yes"
56 57
 network="yes"
57 58
 zlib="yes"
58 59
 mp3lame="no"
... ...
@@ -103,6 +104,7 @@ SHFLAGS=-nostart
103 103
 # disable linux things
104 104
 audio_oss="no"
105 105
 v4l="no"
106
+dv1394="no"
106 107
 # enable beos things
107 108
 audio_beos="yes"
108 109
 # no need for libm, but the inet stuff
... ...
@@ -117,6 +119,7 @@ fi ;;
117 117
 SunOS)
118 118
 v4l="no"
119 119
 audio_oss="no"
120
+dv1394="no"
120 121
 make="gmake"
121 122
 LDFLAGS=""
122 123
 FFSLDFLAGS=""
... ...
@@ -126,12 +129,14 @@ extralibs="$extralibs -lsocket -lnsl"
126 126
 FreeBSD)
127 127
 v4l="no"
128 128
 audio_oss="yes"
129
+dv1394="no"
129 130
 make="gmake"
130 131
 LDFLAGS="$LDFLAGS -export-dynamic"
131 132
 ;;
132 133
 BSD/OS)
133 134
 v4l="no"
134 135
 audio_oss="yes"
136
+dv1394="no"
135 137
 extralibs="-lpoll -lgnugetopt -lm"
136 138
 make="gmake"
137 139
 ;;
... ...
@@ -139,6 +144,7 @@ Darwin)
139 139
 cc="cc"
140 140
 v4l="no"
141 141
 audio_oss="no"
142
+dv1394="no"
142 143
 SHFLAGS="-dynamiclib"
143 144
 extralibs=""
144 145
 darwin="yes"
... ...
@@ -158,6 +164,7 @@ esac
158 158
 MINGW32*)
159 159
 v4l="no"
160 160
 audio_oss="no"
161
+dv1394="no"
161 162
 ffserver="no"
162 163
 network="no"
163 164
 mingw32="yes"
... ...
@@ -165,6 +172,7 @@ mingw32="yes"
165 165
 CYGWIN*)
166 166
 v4l="no"
167 167
 audio_oss="yes"
168
+dv1394="no"
168 169
 extralibs=""
169 170
 cygwin="yes"
170 171
 test -f /usr/include/inttypes.h || \
... ...
@@ -190,6 +198,7 @@ SLIBSUF=".dll"
190 190
 extralibs=""
191 191
 v4l="no"
192 192
 audio_oss="no"
193
+dv1394="no"
193 194
 network="no"
194 195
 ffserver="no"
195 196
 os2="yes"
... ...
@@ -287,6 +296,8 @@ for opt do
287 287
   ;;
288 288
   --disable-audio-beos) audio_beos="no"
289 289
   ;;
290
+  --disable-dv1394) dv1394="no"
291
+  ;;
290 292
   --disable-network) network="no"
291 293
   ;;
292 294
   --disable-zlib) zlib="no"
... ...
@@ -375,6 +386,7 @@ if test "$win32" = "yes" ; then
375 375
     cross_prefix="i386-mingw32msvc-"
376 376
     v4l="no"
377 377
     audio_oss="no"
378
+    dv1394="no"
378 379
     network="no"
379 380
 fi
380 381
 
... ...
@@ -382,6 +394,7 @@ if test "$mingw32" = "yes" ; then
382 382
     cross_prefix=""
383 383
     v4l="no"
384 384
     audio_oss="no"
385
+    dv1394="no"
385 386
     network="no"
386 387
 fi
387 388
 
... ...
@@ -543,6 +556,7 @@ echo "  --disable-altivec        disable AltiVec usage"
543 543
 echo "  --disable-audio-oss      disable OSS audio support [default=no]"
544 544
 echo "  --disable-audio-beos     disable BeOS audio support [default=no]"
545 545
 echo "  --disable-v4l            disable video4linux grabbing [default=no]"
546
+echo "  --disable-dv1394         disable DV1394 grabbing [default=no]"
546 547
 echo "  --disable-network        disable network support [default=no]"
547 548
 echo "  --disable-zlib           disable zlib [default=no]"
548 549
 echo "  --disable-simple_idct    disable simple IDCT routines [default=no]"
... ...
@@ -705,6 +719,11 @@ if test "$v4l" = "yes" ; then
705 705
   echo "CONFIG_VIDEO4LINUX=yes" >> config.mak
706 706
 fi
707 707
 
708
+if test "$dv1394" = "yes" ; then
709
+  echo "#define CONFIG_DV1394 1" >> $TMPH
710
+  echo "CONFIG_DV1394=yes" >> config.mak
711
+fi
712
+
708 713
 if test "$dlopen" = "yes" ; then
709 714
   echo "#define CONFIG_HAVE_DLOPEN 1" >> $TMPH
710 715
 fi
... ...
@@ -158,14 +158,14 @@ static char *pass_logfilename = NULL;
158 158
 static int audio_stream_copy = 0;
159 159
 static int video_stream_copy = 0;
160 160
 
161
+static char *video_grab_format = "video4linux";
162
+static char *audio_grab_format = "audio_device";
163
+
161 164
 #define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
162 165
 
163 166
 #if !defined(CONFIG_AUDIO_OSS) && !defined(CONFIG_AUDIO_BEOS)
164 167
 const char *audio_device = "none";
165 168
 #endif
166
-#ifndef CONFIG_VIDEO4LINUX
167
-const char *v4l_device = "none";
168
-#endif
169 169
 
170 170
 typedef struct AVOutputStream {
171 171
     int file_index;          /* file index */
... ...
@@ -1870,7 +1870,7 @@ void opt_audio_channels(const char *arg)
1870 1870
 
1871 1871
 void opt_video_device(const char *arg)
1872 1872
 {
1873
-    v4l_device = strdup(arg);
1873
+    video_device = strdup(arg);
1874 1874
 }
1875 1875
 
1876 1876
 void opt_audio_device(const char *arg)
... ...
@@ -1878,6 +1878,12 @@ void opt_audio_device(const char *arg)
1878 1878
     audio_device = strdup(arg);
1879 1879
 }
1880 1880
 
1881
+void opt_dv1394(const char *arg)
1882
+{
1883
+    video_grab_format = "dv1394";
1884
+    audio_grab_format = "none";
1885
+}
1886
+
1881 1887
 void opt_audio_codec(const char *arg)
1882 1888
 {
1883 1889
     AVCodec *p;
... ...
@@ -2455,7 +2461,7 @@ void prepare_grab(void)
2455 2455
     
2456 2456
     if (has_video) {
2457 2457
         AVInputFormat *fmt1;
2458
-        fmt1 = av_find_input_format("video_grab_device");
2458
+        fmt1 = av_find_input_format(video_grab_format);
2459 2459
         if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) {
2460 2460
             fprintf(stderr, "Could not find video grab device\n");
2461 2461
             exit(1);
... ...
@@ -2463,12 +2469,12 @@ void prepare_grab(void)
2463 2463
         /* by now video grab has one stream */
2464 2464
         ic->streams[0]->r_frame_rate = ap->frame_rate;
2465 2465
         input_files[nb_input_files] = ic;
2466
-        dump_format(ic, nb_input_files, v4l_device, 0);
2466
+        dump_format(ic, nb_input_files, video_device, 0);
2467 2467
         nb_input_files++;
2468 2468
     }
2469 2469
     if (has_audio) {
2470 2470
         AVInputFormat *fmt1;
2471
-        fmt1 = av_find_input_format("audio_device");
2471
+        fmt1 = av_find_input_format(audio_grab_format);
2472 2472
         if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) {
2473 2473
             fprintf(stderr, "Could not find audio grab device\n");
2474 2474
             exit(1);
... ...
@@ -2692,6 +2698,7 @@ const OptionDef options[] = {
2692 2692
     { "minrate", HAS_ARG, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" },
2693 2693
     { "bufsize", HAS_ARG, {(void*)opt_video_buffer_size}, "set ratecontrol buffere size (in kbit)", "size" },
2694 2694
     { "vd", HAS_ARG | OPT_EXPERT, {(void*)opt_video_device}, "set video grab device", "device" },
2695
+    { "dv1394", OPT_EXPERT, {(void*)opt_dv1394}, "set DV1394 options", "[channel]" },
2695 2696
     { "vcodec", HAS_ARG | OPT_EXPERT, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
2696 2697
     { "me", HAS_ARG | OPT_EXPERT, {(void*)opt_motion_estimation}, "set motion estimation method", 
2697 2698
       "method" },
... ...
@@ -28,6 +28,10 @@ ifeq ($(CONFIG_VIDEO4LINUX),yes)
28 28
 OBJS+= grab.o
29 29
 endif
30 30
 
31
+ifeq ($(CONFIG_DV1394),yes)
32
+OBJS+= dv1394.o
33
+endif
34
+
31 35
 ifeq ($(CONFIG_AUDIO_OSS),yes)
32 36
 OBJS+= audio.o 
33 37
 endif
... ...
@@ -21,6 +21,8 @@
21 21
 /* If you do not call this function, then you can select exactly which
22 22
    formats you want to support */
23 23
 
24
+char *video_device = "none";
25
+
24 26
 /**
25 27
  * Initialize libavcodec and register all the codecs and formats.
26 28
  */
... ...
@@ -62,6 +64,10 @@ void av_register_all(void)
62 62
     audio_init();
63 63
 #endif
64 64
 
65
+#ifdef CONFIG_DV1394
66
+    dv1394_init();
67
+#endif
68
+
65 69
     /* image formats */
66 70
     av_register_image_format(&pnm_image_format);
67 71
     av_register_image_format(&pbm_image_format);
68 72
new file mode 100644
... ...
@@ -0,0 +1,249 @@
0
+/*
1
+ * Linux DV1394 interface
2
+ * Copyright (c) 2003 Max Krasnyansky <maxk@qualcomm.com>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
+ */
18
+
19
+#include <unistd.h>
20
+#include <fcntl.h>
21
+#include <sys/ioctl.h>
22
+#include <sys/mman.h>
23
+#include <sys/poll.h>
24
+#include <sys/time.h>
25
+#include <time.h>
26
+
27
+#include "avformat.h"
28
+
29
+#undef DV1394_DEBUG
30
+
31
+#include "dv1394.h"
32
+
33
+int dv1394_channel = DV1394_DEFAULT_CHANNEL;
34
+
35
+struct dv1394_data {
36
+    int fd;
37
+    int channel;
38
+    int width, height;
39
+    int frame_rate;
40
+    int frame_size;
41
+
42
+    void *ring; /* Ring buffer */
43
+    int index;  /* Current frame index */
44
+    int avail;  /* Number of frames available for reading */
45
+    int done;   /* Number of completed frames */
46
+};
47
+
48
+static int dv1394_reset(struct dv1394_data *dv)
49
+{
50
+    struct dv1394_init init;
51
+
52
+    init.channel = dv->channel;
53
+    init.api_version = DV1394_API_VERSION;
54
+    init.n_frames = DV1394_RING_FRAMES;
55
+    init.format = DV1394_NTSC;
56
+
57
+    if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
58
+        return -1;
59
+
60
+    dv->avail = 0;
61
+    return 0;
62
+}
63
+
64
+static int dv1394_start(struct dv1394_data *dv)
65
+{
66
+    /* Tell DV1394 driver to enable receiver */
67
+    if (ioctl(dv->fd, DV1394_START_RECEIVE, 0) < 0) {
68
+        perror("Failed to start receiver");
69
+        return -1;
70
+    }
71
+    return 0;
72
+}
73
+
74
+static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
75
+{
76
+    struct dv1394_data *dv = context->priv_data;
77
+    AVStream *st;
78
+
79
+    st = av_new_stream(context, 0);
80
+    if (!st)
81
+        return -ENOMEM;
82
+
83
+    dv->width   = DV1394_WIDTH;
84
+    dv->height  = DV1394_HEIGHT;
85
+    dv->channel = dv1394_channel;
86
+
87
+    dv->frame_rate = 30;
88
+
89
+    dv->frame_size = DV1394_NTSC_FRAME_SIZE;
90
+
91
+    /* Open and initialize DV1394 device */
92
+
93
+    dv->fd = open(video_device, O_RDONLY);
94
+    if (dv->fd < 0) {
95
+        perror("Failed to open DV interface");
96
+        goto failed;
97
+    }
98
+
99
+    if (dv1394_reset(dv) < 0) {
100
+        perror("Failed to initialize DV interface");
101
+        goto failed;
102
+    }
103
+
104
+    dv->ring = mmap(NULL, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES,
105
+                    PROT_READ, MAP_PRIVATE, dv->fd, 0);
106
+    if (!dv->ring) {
107
+        perror("Failed to mmap DV ring buffer");
108
+        goto failed;
109
+    }
110
+
111
+    st->codec.codec_type = CODEC_TYPE_VIDEO;
112
+    st->codec.codec_id   = CODEC_ID_DVVIDEO;
113
+    st->codec.width      = dv->width;
114
+    st->codec.height     = dv->height;
115
+    st->codec.frame_rate = dv->frame_rate * FRAME_RATE_BASE;
116
+
117
+    st->codec.bit_rate   = 25000000;  /* Consumer DV is 25Mbps */
118
+
119
+    av_set_pts_info(context, 48, 1, 1000000);
120
+
121
+    if (dv1394_start(dv) < 0)
122
+        goto failed;
123
+
124
+    return 0;
125
+
126
+failed:
127
+    close(dv->fd);
128
+    av_free(st);
129
+    return -EIO;
130
+}
131
+
132
+static inline int __copy_frame(struct dv1394_data *dv, void *buf)
133
+{
134
+    char *ptr = dv->ring + (dv->index * dv->frame_size);
135
+
136
+    memcpy(buf, ptr, dv->frame_size);
137
+
138
+    dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
139
+    dv->avail--;
140
+    dv->done++;
141
+
142
+    return dv->frame_size;
143
+}
144
+
145
+static int dv1394_read_packet(AVFormatContext * context, AVPacket * pkt)
146
+{
147
+    struct dv1394_data *dv = context->priv_data;
148
+    int len;
149
+
150
+    if (!dv->avail) {
151
+        struct dv1394_status s;
152
+        struct pollfd p;
153
+        p.fd = dv->fd;
154
+        p.events = POLLIN | POLLERR | POLLHUP;
155
+
156
+        /* Wait until more frames are available */
157
+        if (poll(&p, 1, -1) < 0) {
158
+            perror("Poll failed");
159
+            return -EIO;
160
+        }
161
+
162
+        if (ioctl(dv->fd, DV1394_GET_STATUS, &s) < 0) {
163
+            perror("Failed to get status");
164
+            return -EIO;
165
+        }
166
+#ifdef DV1394_DEBUG
167
+        fprintf(stderr, "DV1394: status\n"
168
+                "\tactive_frame\t%d\n"
169
+                "\tfirst_clear_frame\t%d\n"
170
+                "\tn_clear_frames\t%d\n"
171
+                "\tdropped_frames\t%d\n",
172
+                s.active_frame, s.first_clear_frame,
173
+                s.n_clear_frames, s.dropped_frames);
174
+#endif
175
+
176
+        dv->avail = s.n_clear_frames;
177
+        dv->index = s.first_clear_frame;
178
+        dv->done = 0;
179
+
180
+        if (s.dropped_frames) {
181
+            fprintf(stderr, "DV1394: Frame drop detected (%d). Reseting ..\n",
182
+                    s.dropped_frames);
183
+
184
+            dv1394_reset(dv);
185
+            dv1394_start(dv);
186
+        }
187
+    }
188
+
189
+    if (av_new_packet(pkt, dv->frame_size) < 0)
190
+        return -EIO;
191
+
192
+#ifdef DV1394_DEBUG
193
+    fprintf(stderr, "index %d, avail %d, done %d\n", dv->index, dv->avail,
194
+            dv->done);
195
+#endif
196
+
197
+    len = __copy_frame(dv, pkt->data);
198
+    pkt->pts = av_gettime() & ((1LL << 48) - 1);
199
+
200
+    if (!dv->avail && dv->done) {
201
+        /* Request more frames */
202
+        if (ioctl(dv->fd, DV1394_RECEIVE_FRAMES, dv->done) < 0) {
203
+            /* This usually means that ring buffer overflowed.
204
+             * We have to reset :(.
205
+             */
206
+
207
+            fprintf(stderr, "DV1394: Ring buffer overflow. Reseting ..\n");
208
+
209
+            dv1394_reset(dv);
210
+            dv1394_start(dv);
211
+        }
212
+    }
213
+
214
+    return len;
215
+}
216
+
217
+static int dv1394_close(AVFormatContext * context)
218
+{
219
+    struct dv1394_data *dv = context->priv_data;
220
+
221
+    /* Shutdown DV1394 receiver */
222
+    if (ioctl(dv->fd, DV1394_SHUTDOWN, 0) < 0)
223
+        perror("Failed to shutdown DV1394");
224
+
225
+    /* Unmap ring buffer */
226
+    if (munmap(dv->ring, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES) < 0)
227
+        perror("Failed to munmap DV1394 ring buffer");
228
+
229
+    close(dv->fd);
230
+
231
+    return 0;
232
+}
233
+
234
+static AVInputFormat dv1394_format = {
235
+    .name           = "dv1394",
236
+    .long_name      = "dv1394 A/V grab",
237
+    .priv_data_size = sizeof(struct dv1394_data),
238
+    .read_header    = dv1394_read_header,
239
+    .read_packet    = dv1394_read_packet,
240
+    .read_close     = dv1394_close,
241
+    .flags          = AVFMT_NOFILE
242
+};
243
+
244
+int dv1394_init(void)
245
+{
246
+    av_register_input_format(&dv1394_format);
247
+    return 0;
248
+}
0 249
new file mode 100644
... ...
@@ -0,0 +1,353 @@
0
+/*
1
+ * dv1394.h - DV input/output over IEEE 1394 on OHCI chips
2
+ *   Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
3
+ *     receive, proc_fs by Dan Dennedy <dan@dennedy.org>
4
+ *
5
+ * based on:
6
+ *   video1394.h - driver for OHCI 1394 boards
7
+ *   Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
8
+ *                          Peter Schlaile <udbz@rz.uni-karlsruhe.de>
9
+ *
10
+ * This program is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program 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
18
+ * GNU General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU General Public License
21
+ * along with this program; if not, write to the Free Software Foundation,
22
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
+ */
24
+
25
+#ifndef _DV_1394_H
26
+#define _DV_1394_H
27
+
28
+#define DV1394_DEFAULT_CHANNEL 0x63
29
+#define DV1394_DEFAULT_CARD    0
30
+#define DV1394_RING_FRAMES     20
31
+
32
+#define DV1394_WIDTH  720
33
+#define DV1394_HEIGHT 480
34
+
35
+/* This is the public user-space interface. Try not to break it. */
36
+
37
+#define DV1394_API_VERSION 0x20011127
38
+
39
+/* ********************
40
+   **                **
41
+   **   DV1394 API   **
42
+   **                **
43
+   ********************
44
+
45
+   There are two methods of operating the DV1394 DV output device.
46
+
47
+   1)
48
+
49
+   The simplest is an interface based on write(): simply write
50
+   full DV frames of data to the device, and they will be transmitted
51
+   as quickly as possible. The FD may be set for non-blocking I/O,
52
+   in which case you can use select() or poll() to wait for output
53
+   buffer space.
54
+
55
+   To set the DV output parameters (e.g. whether you want NTSC or PAL
56
+   video), use the DV1394_INIT ioctl, passing in the parameters you
57
+   want in a struct dv1394_init.
58
+ 
59
+   Example 1:
60
+         To play a raw .DV file:   cat foo.DV > /dev/dv1394
61
+	 (cat will use write() internally)
62
+
63
+   Example 2:
64
+           static struct dv1394_init init = {
65
+	      0x63,        (broadcast channel)
66
+              4,           (four-frame ringbuffer)
67
+	      DV1394_NTSC, (send NTSC video)
68
+	      0, 0         (default empty packet rate)
69
+           }
70
+
71
+	   ioctl(fd, DV1394_INIT, &init);
72
+
73
+	   while(1) {
74
+	          read( <a raw DV file>, buf, DV1394_NTSC_FRAME_SIZE );
75
+		  write( <the dv1394 FD>, buf, DV1394_NTSC_FRAME_SIZE );
76
+           }
77
+
78
+   2)
79
+
80
+   For more control over buffering, and to avoid unnecessary copies
81
+   of the DV data, you can use the more sophisticated the mmap() interface. 
82
+   First, call the DV1394_INIT ioctl to specify your parameters, 
83
+   including the number of frames in the ringbuffer. Then, calling mmap() 
84
+   on the dv1394 device will give you direct access to the ringbuffer
85
+   from which the DV card reads your frame data.
86
+
87
+   The ringbuffer is simply one large, contiguous region of memory
88
+   containing two or more frames of packed DV data. Each frame of DV data
89
+   is 120000 bytes (NTSC) or 144000 bytes (PAL).
90
+
91
+   Fill one or more frames in the ringbuffer, then use the DV1394_SUBMIT_FRAMES
92
+   ioctl to begin I/O. You can use either the DV1394_WAIT_FRAMES ioctl
93
+   or select()/poll() to wait until the frames are transmitted. Next, you'll
94
+   need to call the DV1394_GET_STATUS ioctl to determine which ringbuffer
95
+   frames are clear (ready to be filled with new DV data). Finally, use
96
+   DV1394_SUBMIT_FRAMES again to send the new data to the DV output.
97
+
98
+
99
+   Example: here is what a four-frame ringbuffer might look like
100
+            during DV transmission:
101
+
102
+
103
+         frame 0   frame 1   frame 2   frame 3
104
+
105
+	*--------------------------------------*
106
+        | CLEAR   | DV data | DV data | CLEAR  |
107
+        *--------------------------------------*
108
+                   <ACTIVE> 
109
+
110
+	transmission goes in this direction --->>>
111
+
112
+
113
+   The DV hardware is currently transmitting the data in frame 1.
114
+   Once frame 1 is finished, it will automatically transmit frame 2.
115
+   (if frame 2 finishes before frame 3 is submitted, the device
116
+   will continue to transmit frame 2, and will increase the dropped_frames
117
+   counter each time it repeats the transmission).
118
+
119
+ 
120
+   If you called DV1394_GET_STATUS at this instant, you would
121
+   receive the following values:
122
+   
123
+                  n_frames          = 4
124
+		  active_frame      = 1
125
+		  first_clear_frame = 3
126
+		  n_clear_frames    = 2
127
+
128
+   At this point, you should write new DV data into frame 3 and optionally
129
+   frame 0. Then call DV1394_SUBMIT_FRAMES to inform the device that
130
+   it may transmit the new frames.
131
+
132
+   ERROR HANDLING
133
+
134
+   An error (buffer underflow/overflow or a break in the DV stream due
135
+   to a 1394 bus reset) can be detected by checking the dropped_frames
136
+   field of struct dv1394_status (obtained through the
137
+   DV1394_GET_STATUS ioctl).
138
+
139
+   The best way to recover from such an error is to re-initialize
140
+   dv1394, either by using the DV1394_INIT ioctl call, or closing the
141
+   file descriptor and opening it again. (note that you must unmap all
142
+   ringbuffer mappings when closing the file descriptor, or else
143
+   dv1394 will still be considered 'in use').
144
+
145
+   MAIN LOOP
146
+
147
+   For maximum efficiency and robustness against bus errors, you are
148
+   advised to model the main loop of your application after the
149
+   following pseudo-code example:
150
+
151
+   (checks of system call return values omitted for brevity; always
152
+   check return values in your code!)
153
+   
154
+   while( frames left ) {
155
+   
156
+    struct pollfd *pfd = ...;
157
+
158
+    pfd->fd = dv1394_fd;
159
+    pfd->revents = 0;
160
+    pfd->events = POLLOUT | POLLIN; (OUT for transmit, IN for receive)
161
+
162
+    (add other sources of I/O here)
163
+    
164
+    poll(pfd, 1, -1); (or select(); add a timeout if you want)
165
+
166
+    if(pfd->revents) {
167
+         struct dv1394_status status;
168
+	 
169
+         ioctl(dv1394_fd, DV1394_GET_STATUS, &status);
170
+
171
+	 if(status.dropped_frames > 0) {
172
+	      reset_dv1394();
173
+         } else {
174
+              for(int i = 0; i < status.n_clear_frames; i++) {
175
+	          copy_DV_frame();
176
+              }
177
+         }
178
+    }
179
+   }
180
+
181
+   where copy_DV_frame() reads or writes on the dv1394 file descriptor
182
+   (read/write mode) or copies data to/from the mmap ringbuffer and
183
+   then calls ioctl(DV1394_SUBMIT_FRAMES) to notify dv1394 that new
184
+   frames are availble (mmap mode).
185
+
186
+   reset_dv1394() is called in the event of a buffer
187
+   underflow/overflow or a halt in the DV stream (e.g. due to a 1394
188
+   bus reset). To guarantee recovery from the error, this function
189
+   should close the dv1394 file descriptor (and munmap() all
190
+   ringbuffer mappings, if you are using them), then re-open the
191
+   dv1394 device (and re-map the ringbuffer).
192
+   
193
+*/
194
+
195
+
196
+/* maximum number of frames in the ringbuffer */
197
+#define DV1394_MAX_FRAMES 32
198
+
199
+/* number of *full* isochronous packets per DV frame */
200
+#define DV1394_NTSC_PACKETS_PER_FRAME 250
201
+#define DV1394_PAL_PACKETS_PER_FRAME  300
202
+
203
+/* size of one frame's worth of DV data, in bytes */
204
+#define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME)
205
+#define DV1394_PAL_FRAME_SIZE  (480 * DV1394_PAL_PACKETS_PER_FRAME)
206
+
207
+
208
+/* ioctl() commands */
209
+
210
+enum {
211
+	/* I don't like using 0 as a valid ioctl() */
212
+	DV1394_INVALID = 0,
213
+
214
+
215
+	/* get the driver ready to transmit video.
216
+	   pass a struct dv1394_init* as the parameter (see below),
217
+	   or NULL to get default parameters */
218
+	DV1394_INIT,
219
+
220
+
221
+	/* stop transmitting video and free the ringbuffer */
222
+	DV1394_SHUTDOWN,
223
+
224
+
225
+	/* submit N new frames to be transmitted, where
226
+	   the index of the first new frame is first_clear_buffer,
227
+	   and the index of the last new frame is
228
+	   (first_clear_buffer + N) % n_frames */
229
+	DV1394_SUBMIT_FRAMES,
230
+
231
+
232
+	/* block until N buffers are clear (pass N as the parameter)
233
+	   Because we re-transmit the last frame on underrun, there
234
+	   will at most be n_frames - 1 clear frames at any time */
235
+	DV1394_WAIT_FRAMES,
236
+
237
+	/* capture new frames that have been received, where
238
+	   the index of the first new frame is first_clear_buffer,
239
+	   and the index of the last new frame is
240
+	   (first_clear_buffer + N) % n_frames */
241
+	DV1394_RECEIVE_FRAMES,
242
+
243
+
244
+	DV1394_START_RECEIVE,
245
+
246
+
247
+	/* pass a struct dv1394_status* as the parameter (see below) */
248
+	DV1394_GET_STATUS,
249
+};
250
+
251
+
252
+
253
+enum pal_or_ntsc {
254
+	DV1394_NTSC = 0,
255
+	DV1394_PAL
256
+};
257
+
258
+
259
+
260
+
261
+/* this is the argument to DV1394_INIT */
262
+struct dv1394_init {
263
+	/* DV1394_API_VERSION */
264
+	unsigned int api_version;
265
+	
266
+	/* isochronous transmission channel to use */
267
+	unsigned int channel;
268
+
269
+	/* number of frames in the ringbuffer. Must be at least 2
270
+	   and at most DV1394_MAX_FRAMES. */
271
+	unsigned int n_frames;
272
+
273
+	/* send/receive PAL or NTSC video format */
274
+	enum pal_or_ntsc format;
275
+
276
+	/* the following are used only for transmission */
277
+ 
278
+	/* set these to zero unless you want a
279
+	   non-default empty packet rate (see below) */
280
+	unsigned long cip_n;
281
+	unsigned long cip_d;
282
+
283
+	/* set this to zero unless you want a
284
+	   non-default SYT cycle offset (default = 3 cycles) */
285
+	unsigned int syt_offset;
286
+};
287
+
288
+/* NOTE: you may only allocate the DV frame ringbuffer once each time
289
+   you open the dv1394 device. DV1394_INIT will fail if you call it a
290
+   second time with different 'n_frames' or 'format' arguments (which
291
+   would imply a different size for the ringbuffer). If you need a
292
+   different buffer size, simply close and re-open the device, then
293
+   initialize it with your new settings. */
294
+   
295
+/* Q: What are cip_n and cip_d? */
296
+
297
+/*
298
+  A: DV video streams do not utilize 100% of the potential bandwidth offered
299
+  by IEEE 1394 (FireWire). To achieve the correct rate of data transmission,
300
+  DV devices must periodically insert empty packets into the 1394 data stream.
301
+  Typically there is one empty packet per 14-16 data-carrying packets.
302
+
303
+  Some DV devices will accept a wide range of empty packet rates, while others
304
+  require a precise rate. If the dv1394 driver produces empty packets at
305
+  a rate that your device does not accept, you may see ugly patterns on the
306
+  DV output, or even no output at all.
307
+
308
+  The default empty packet insertion rate seems to work for many people; if
309
+  your DV output is stable, you can simply ignore this discussion. However,
310
+  we have exposed the empty packet rate as a parameter to support devices that
311
+  do not work with the default rate. 
312
+
313
+  The decision to insert an empty packet is made with a numerator/denominator
314
+  algorithm. Empty packets are produced at an average rate of CIP_N / CIP_D.
315
+  You can alter the empty packet rate by passing non-zero values for cip_n
316
+  and cip_d to the INIT ioctl.
317
+  
318
+ */
319
+
320
+
321
+
322
+struct dv1394_status {
323
+	/* this embedded init struct returns the current dv1394
324
+	   parameters in use */
325
+	struct dv1394_init init;
326
+
327
+	/* the ringbuffer frame that is currently being
328
+	   displayed. (-1 if the device is not transmitting anything) */
329
+	int active_frame;
330
+
331
+	/* index of the first buffer (ahead of active_frame) that
332
+	   is ready to be filled with data */
333
+	unsigned int first_clear_frame;
334
+
335
+	/* how many buffers, including first_clear_buffer, are
336
+	   ready to be filled with data */
337
+	unsigned int n_clear_frames;
338
+
339
+	/* how many times the DV stream has underflowed, overflowed,
340
+	   or otherwise encountered an error, since the previous call
341
+	   to DV1394_GET_STATUS */
342
+	unsigned int dropped_frames;
343
+
344
+	/* N.B. The dropped_frames counter is only a lower bound on the actual
345
+	   number of dropped frames, with the special case that if dropped_frames
346
+	   is zero, then it is guaranteed that NO frames have been dropped
347
+	   since the last call to DV1394_GET_STATUS.
348
+	*/
349
+};
350
+
351
+
352
+#endif /* _DV_1394_H */
... ...
@@ -53,8 +53,6 @@ static int aiw_init(VideoData *s);
53 53
 static int aiw_read_picture(VideoData *s, uint8_t *data);
54 54
 static int aiw_close(VideoData *s);
55 55
 
56
-const char *v4l_device = "/dev/video";
57
-
58 56
 static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
59 57
 {
60 58
     VideoData *s = s1->priv_data;
... ...
@@ -80,9 +78,9 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
80 80
     s->height = height;
81 81
     s->frame_rate = frame_rate;
82 82
 
83
-    video_fd = open(v4l_device, O_RDWR);
83
+    video_fd = open(video_device, O_RDWR);
84 84
     if (video_fd < 0) {
85
-        perror(v4l_device);
85
+        perror(video_device);
86 86
         goto fail;
87 87
     }
88 88
     
... ...
@@ -339,7 +337,7 @@ static int grab_read_close(AVFormatContext *s1)
339 339
 }
340 340
 
341 341
 static AVInputFormat video_grab_device_format = {
342
-    "video_grab_device",
342
+    "video4linux",
343 343
     "video grab",
344 344
     sizeof(VideoData),
345 345
     NULL,