]> git.sesse.net Git - ffmpeg/blob - libavdevice/dv1394.c
raw GSM demuxer (does not work yet as parser is missing)
[ffmpeg] / libavdevice / dv1394.c
1 /*
2  * Linux DV1394 interface
3  * Copyright (c) 2003 Max Krasnyansky <maxk@qualcomm.com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "config.h"
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #include <sys/ioctl.h>
27 #include <sys/mman.h>
28 #include <sys/poll.h>
29 #include <sys/time.h>
30 #include <time.h>
31
32 #include "avformat.h"
33
34 #undef DV1394_DEBUG
35
36 #include "dv1394.h"
37 #include "dv.h"
38
39 struct dv1394_data {
40     int fd;
41     int channel;
42     int format;
43
44     uint8_t *ring; /* Ring buffer */
45     int index;  /* Current frame index */
46     int avail;  /* Number of frames available for reading */
47     int done;   /* Number of completed frames */
48
49     DVDemuxContext* dv_demux; /* Generic DV muxing/demuxing context */
50 };
51
52 /*
53  * The trick here is to kludge around well known problem with kernel Ooopsing
54  * when you try to capture PAL on a device node configure for NTSC. That's
55  * why we have to configure the device node for PAL, and then read only NTSC
56  * amount of data.
57  */
58 static int dv1394_reset(struct dv1394_data *dv)
59 {
60     struct dv1394_init init;
61
62     init.channel     = dv->channel;
63     init.api_version = DV1394_API_VERSION;
64     init.n_frames    = DV1394_RING_FRAMES;
65     init.format      = DV1394_PAL;
66
67     if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
68         return -1;
69
70     dv->avail  = dv->done = 0;
71     return 0;
72 }
73
74 static int dv1394_start(struct dv1394_data *dv)
75 {
76     /* Tell DV1394 driver to enable receiver */
77     if (ioctl(dv->fd, DV1394_START_RECEIVE, 0) < 0) {
78         av_log(NULL, AV_LOG_ERROR, "Failed to start receiver: %s\n", strerror(errno));
79         return -1;
80     }
81     return 0;
82 }
83
84 static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
85 {
86     struct dv1394_data *dv = context->priv_data;
87
88     dv->dv_demux = dv_init_demux(context);
89     if (!dv->dv_demux)
90         goto failed;
91
92     if (ap->standard && !strcasecmp(ap->standard, "pal"))
93         dv->format = DV1394_PAL;
94     else
95         dv->format = DV1394_NTSC;
96
97     if (ap->channel)
98         dv->channel = ap->channel;
99     else
100         dv->channel = DV1394_DEFAULT_CHANNEL;
101
102     /* Open and initialize DV1394 device */
103     dv->fd = open(context->filename, O_RDONLY);
104     if (dv->fd < 0) {
105         av_log(context, AV_LOG_ERROR, "Failed to open DV interface: %s\n", strerror(errno));
106         goto failed;
107     }
108
109     if (dv1394_reset(dv) < 0) {
110         av_log(context, AV_LOG_ERROR, "Failed to initialize DV interface: %s\n", strerror(errno));
111         goto failed;
112     }
113
114     dv->ring = mmap(NULL, DV1394_PAL_FRAME_SIZE * DV1394_RING_FRAMES,
115                     PROT_READ, MAP_PRIVATE, dv->fd, 0);
116     if (dv->ring == MAP_FAILED) {
117         av_log(context, AV_LOG_ERROR, "Failed to mmap DV ring buffer: %s\n", strerror(errno));
118         goto failed;
119     }
120
121     if (dv1394_start(dv) < 0)
122         goto failed;
123
124     return 0;
125
126 failed:
127     close(dv->fd);
128     return AVERROR(EIO);
129 }
130
131 static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt)
132 {
133     struct dv1394_data *dv = context->priv_data;
134     int size;
135
136     size = dv_get_packet(dv->dv_demux, pkt);
137     if (size > 0)
138         return size;
139
140     if (!dv->avail) {
141         struct dv1394_status s;
142         struct pollfd p;
143
144         if (dv->done) {
145             /* Request more frames */
146             if (ioctl(dv->fd, DV1394_RECEIVE_FRAMES, dv->done) < 0) {
147                 /* This usually means that ring buffer overflowed.
148                  * We have to reset :(.
149                  */
150
151                 av_log(context, AV_LOG_ERROR, "DV1394: Ring buffer overflow. Reseting ..\n");
152
153                 dv1394_reset(dv);
154                 dv1394_start(dv);
155             }
156             dv->done = 0;
157         }
158
159         /* Wait until more frames are available */
160 restart_poll:
161         p.fd = dv->fd;
162         p.events = POLLIN | POLLERR | POLLHUP;
163         if (poll(&p, 1, -1) < 0) {
164             if (errno == EAGAIN || errno == EINTR)
165                 goto restart_poll;
166             av_log(context, AV_LOG_ERROR, "Poll failed: %s\n", strerror(errno));
167             return AVERROR(EIO);
168         }
169
170         if (ioctl(dv->fd, DV1394_GET_STATUS, &s) < 0) {
171             av_log(context, AV_LOG_ERROR, "Failed to get status: %s\n", strerror(errno));
172             return AVERROR(EIO);
173         }
174 #ifdef DV1394_DEBUG
175         av_log(context, AV_LOG_DEBUG, "DV1394: status\n"
176                 "\tactive_frame\t%d\n"
177                 "\tfirst_clear_frame\t%d\n"
178                 "\tn_clear_frames\t%d\n"
179                 "\tdropped_frames\t%d\n",
180                 s.active_frame, s.first_clear_frame,
181                 s.n_clear_frames, s.dropped_frames);
182 #endif
183
184         dv->avail = s.n_clear_frames;
185         dv->index = s.first_clear_frame;
186         dv->done  = 0;
187
188         if (s.dropped_frames) {
189             av_log(context, AV_LOG_ERROR, "DV1394: Frame drop detected (%d). Reseting ..\n",
190                     s.dropped_frames);
191
192             dv1394_reset(dv);
193             dv1394_start(dv);
194         }
195     }
196
197 #ifdef DV1394_DEBUG
198     av_log(context, AV_LOG_DEBUG, "index %d, avail %d, done %d\n", dv->index, dv->avail,
199             dv->done);
200 #endif
201
202     size = dv_produce_packet(dv->dv_demux, pkt,
203                              dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE),
204                              DV1394_PAL_FRAME_SIZE);
205     dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
206     dv->done++; dv->avail--;
207
208     return size;
209 }
210
211 static int dv1394_close(AVFormatContext * context)
212 {
213     struct dv1394_data *dv = context->priv_data;
214
215     /* Shutdown DV1394 receiver */
216     if (ioctl(dv->fd, DV1394_SHUTDOWN, 0) < 0)
217         av_log(context, AV_LOG_ERROR, "Failed to shutdown DV1394: %s\n", strerror(errno));
218
219     /* Unmap ring buffer */
220     if (munmap(dv->ring, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES) < 0)
221         av_log(context, AV_LOG_ERROR, "Failed to munmap DV1394 ring buffer: %s\n", strerror(errno));
222
223     close(dv->fd);
224     av_free(dv->dv_demux);
225
226     return 0;
227 }
228
229 AVInputFormat dv1394_demuxer = {
230     .name           = "dv1394",
231     .long_name      = "dv1394 A/V grab",
232     .priv_data_size = sizeof(struct dv1394_data),
233     .read_header    = dv1394_read_header,
234     .read_packet    = dv1394_read_packet,
235     .read_close     = dv1394_close,
236     .flags          = AVFMT_NOFILE
237 };