Statistics
| Branch: | Revision:

ffmpeg / libavformat / dv1394.c @ 7458ccbb

History | View | Annotate | Download (6.64 KB)

1
/*
2
 * Linux DV1394 interface
3
 * Copyright (c) 2003 Max Krasnyansky <maxk@qualcomm.com>
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19

    
20
#include <unistd.h>
21
#include <fcntl.h>
22
#include <errno.h>
23
#include <sys/ioctl.h>
24
#include <sys/mman.h>
25
#include <sys/poll.h>
26
#include <sys/time.h>
27
#include <time.h>
28

    
29
#include "avformat.h"
30

    
31
#undef DV1394_DEBUG
32

    
33
#include "dv1394.h"
34
#include "dv.h"
35

    
36
struct dv1394_data {
37
    int fd;
38
    int channel;
39
    int format;
40

    
41
    void *ring; /* Ring buffer */
42
    int index;  /* Current frame index */
43
    int avail;  /* Number of frames available for reading */
44
    int done;   /* Number of completed frames */
45

    
46
    int64_t pts;  /* Current timestamp */
47

    
48
    void* dv_demux; /* Generic DV muxing/demuxing context */
49
};
50

    
51
/* 
52
 * The trick here is to kludge around well known problem with kernel Ooopsing
53
 * when you try to capture PAL on a device node configure for NTSC. That's 
54
 * why we have to configure the device node for PAL, and then read only NTSC
55
 * amount of data.
56
 */
57
static int dv1394_reset(struct dv1394_data *dv)
58
{
59
    struct dv1394_init init;
60

    
61
    init.channel     = dv->channel;
62
    init.api_version = DV1394_API_VERSION;
63
    init.n_frames    = DV1394_RING_FRAMES;
64
    init.format      = DV1394_PAL;
65

    
66
    if (ioctl(dv->fd, DV1394_INIT, &init) < 0)
67
        return -1;
68

    
69
    dv->avail  = dv->done = 0;
70
    return 0;
71
}
72

    
73
static int dv1394_start(struct dv1394_data *dv)
74
{
75
    /* Tell DV1394 driver to enable receiver */
76
    if (ioctl(dv->fd, DV1394_START_RECEIVE, 0) < 0) {
77
        perror("Failed to start receiver");
78
        return -1;
79
    }
80
    return 0;
81
}
82

    
83
static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
84
{
85
    struct dv1394_data *dv = context->priv_data;
86
    const char *video_device;
87

    
88
    dv->dv_demux = dv_init_demux(context, 0, 1);
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
    video_device = ap->device;
104
    if (!video_device)
105
        video_device = "/dev/dv1394/0";
106
    dv->fd = open(video_device, O_RDONLY);
107
    if (dv->fd < 0) {
108
        perror("Failed to open DV interface");
109
        goto failed;
110
    }
111

    
112
    if (dv1394_reset(dv) < 0) {
113
        perror("Failed to initialize DV interface");
114
        goto failed;
115
    }
116

    
117
    dv->ring = mmap(NULL, DV1394_PAL_FRAME_SIZE * DV1394_RING_FRAMES,
118
                    PROT_READ, MAP_PRIVATE, dv->fd, 0);
119
    if (dv->ring == MAP_FAILED) {
120
        perror("Failed to mmap DV ring buffer");
121
        goto failed;
122
    }
123

    
124
    av_set_pts_info(context, 48, 1, 1000000);
125

    
126
    if (dv1394_start(dv) < 0)
127
        goto failed;
128

    
129
    return 0;
130

    
131
failed:
132
    close(dv->fd);
133
    return -EIO;
134
}
135

    
136
static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt)
137
{
138
    struct dv1394_data *dv = context->priv_data;
139
    int size;
140

    
141
    size = dv_get_packet(dv->dv_demux, pkt);
142
    if (size > 0)
143
        goto out;
144

    
145
    if (!dv->avail) {
146
        struct dv1394_status s;
147
        struct pollfd p;
148

    
149
        if (dv->done) {
150
            /* Request more frames */
151
            if (ioctl(dv->fd, DV1394_RECEIVE_FRAMES, dv->done) < 0) {
152
                /* This usually means that ring buffer overflowed.
153
                 * We have to reset :(.
154
                 */
155
  
156
                fprintf(stderr, "DV1394: Ring buffer overflow. Reseting ..\n");
157
 
158
                dv1394_reset(dv);
159
                dv1394_start(dv);
160
            }
161
            dv->done = 0;
162
        }
163

    
164
        /* Wait until more frames are available */
165
restart_poll:
166
        p.fd = dv->fd;
167
        p.events = POLLIN | POLLERR | POLLHUP;
168
        if (poll(&p, 1, -1) < 0) {
169
            if (errno == EAGAIN || errno == EINTR)
170
                goto restart_poll;
171
            perror("Poll failed");
172
            return -EIO;
173
        }
174

    
175
        if (ioctl(dv->fd, DV1394_GET_STATUS, &s) < 0) {
176
            perror("Failed to get status");
177
            return -EIO;
178
        }
179
#ifdef DV1394_DEBUG
180
        fprintf(stderr, "DV1394: status\n"
181
                "\tactive_frame\t%d\n"
182
                "\tfirst_clear_frame\t%d\n"
183
                "\tn_clear_frames\t%d\n"
184
                "\tdropped_frames\t%d\n",
185
                s.active_frame, s.first_clear_frame,
186
                s.n_clear_frames, s.dropped_frames);
187
#endif
188

    
189
        dv->avail = s.n_clear_frames;
190
        dv->index = s.first_clear_frame;
191
        dv->done  = 0;
192

    
193
        if (s.dropped_frames) {
194
            fprintf(stderr, "DV1394: Frame drop detected (%d). Reseting ..\n",
195
                    s.dropped_frames);
196

    
197
            dv1394_reset(dv);
198
            dv1394_start(dv);
199
        }
200
    }
201

    
202
#ifdef DV1394_DEBUG
203
    fprintf(stderr, "index %d, avail %d, done %d\n", dv->index, dv->avail,
204
            dv->done);
205
#endif
206

    
207
    size = dv_produce_packet(dv->dv_demux, pkt, 
208
                             dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE), 
209
                             DV1394_PAL_FRAME_SIZE);
210
    dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
211
    dv->done++; dv->avail--;
212
    dv->pts = av_gettime() & ((1LL << 48) - 1);
213
    
214
out:
215
    pkt->pts = dv->pts;
216
    return size;
217
}
218

    
219
static int dv1394_close(AVFormatContext * context)
220
{
221
    struct dv1394_data *dv = context->priv_data;
222

    
223
    /* Shutdown DV1394 receiver */
224
    if (ioctl(dv->fd, DV1394_SHUTDOWN, 0) < 0)
225
        perror("Failed to shutdown DV1394");
226

    
227
    /* Unmap ring buffer */
228
    if (munmap(dv->ring, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES) < 0)
229
        perror("Failed to munmap DV1394 ring buffer");
230

    
231
    close(dv->fd);
232
    av_free(dv->dv_demux);
233

    
234
    return 0;
235
}
236

    
237
static AVInputFormat dv1394_format = {
238
    .name           = "dv1394",
239
    .long_name      = "dv1394 A/V grab",
240
    .priv_data_size = sizeof(struct dv1394_data),
241
    .read_header    = dv1394_read_header,
242
    .read_packet    = dv1394_read_packet,
243
    .read_close     = dv1394_close,
244
    .flags          = AVFMT_NOFILE
245
};
246

    
247
int dv1394_init(void)
248
{
249
    av_register_input_format(&dv1394_format);
250
    return 0;
251
}