Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavdevice
dv1394.c
Go to the documentation of this file.
1
/*
2
* Linux DV1394 interface
3
* Copyright (c) 2003 Max Krasnyansky <maxk@qualcomm.com>
4
*
5
* This file is part of Libav.
6
*
7
* Libav 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
* Libav 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 Libav; 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 <poll.h>
27
#include <sys/ioctl.h>
28
#include <sys/mman.h>
29
#include <sys/time.h>
30
#include <time.h>
31
32
#include "
libavutil/log.h
"
33
#include "
libavutil/opt.h
"
34
#include "
libavformat/avformat.h
"
35
#include "
libavformat/dv.h
"
36
#include "
dv1394.h
"
37
38
struct
dv1394_data
{
39
AVClass
*
class
;
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
=
avpriv_dv_init_demux
(context);
89
if
(!dv->
dv_demux
)
90
goto
failed;
91
92
/* Open and initialize DV1394 device */
93
dv->
fd
= open(context->
filename
, O_RDONLY);
94
if
(dv->
fd
< 0) {
95
av_log
(context,
AV_LOG_ERROR
,
"Failed to open DV interface: %s\n"
, strerror(errno));
96
goto
failed;
97
}
98
99
if
(
dv1394_reset
(dv) < 0) {
100
av_log
(context,
AV_LOG_ERROR
,
"Failed to initialize DV interface: %s\n"
, strerror(errno));
101
goto
failed;
102
}
103
104
dv->
ring
= mmap(
NULL
,
DV1394_PAL_FRAME_SIZE
*
DV1394_RING_FRAMES
,
105
PROT_READ, MAP_PRIVATE, dv->
fd
, 0);
106
if
(dv->
ring
== MAP_FAILED) {
107
av_log
(context,
AV_LOG_ERROR
,
"Failed to mmap DV ring buffer: %s\n"
, strerror(errno));
108
goto
failed;
109
}
110
111
if
(
dv1394_start
(dv) < 0)
112
goto
failed;
113
114
return
0;
115
116
failed:
117
close
(dv->
fd
);
118
return
AVERROR
(EIO);
119
}
120
121
static
int
dv1394_read_packet
(
AVFormatContext
*context,
AVPacket
*pkt)
122
{
123
struct
dv1394_data
*dv = context->
priv_data
;
124
int
size
;
125
126
size =
avpriv_dv_get_packet
(dv->
dv_demux
, pkt);
127
if
(size > 0)
128
return
size
;
129
130
if
(!dv->
avail
) {
131
struct
dv1394_status
s;
132
struct
pollfd p;
133
134
if
(dv->
done
) {
135
/* Request more frames */
136
if
(ioctl(dv->
fd
,
DV1394_RECEIVE_FRAMES
, dv->
done
) < 0) {
137
/* This usually means that ring buffer overflowed.
138
* We have to reset :(.
139
*/
140
141
av_log
(context,
AV_LOG_ERROR
,
"DV1394: Ring buffer overflow. Reseting ..\n"
);
142
143
dv1394_reset
(dv);
144
dv1394_start
(dv);
145
}
146
dv->
done
= 0;
147
}
148
149
/* Wait until more frames are available */
150
restart_poll:
151
p.fd = dv->
fd
;
152
p.events = POLLIN | POLLERR | POLLHUP;
153
if
(poll(&p, 1, -1) < 0) {
154
if
(errno == EAGAIN || errno == EINTR)
155
goto
restart_poll;
156
av_log
(context,
AV_LOG_ERROR
,
"Poll failed: %s\n"
, strerror(errno));
157
return
AVERROR
(EIO);
158
}
159
160
if
(ioctl(dv->
fd
,
DV1394_GET_STATUS
, &s) < 0) {
161
av_log
(context,
AV_LOG_ERROR
,
"Failed to get status: %s\n"
, strerror(errno));
162
return
AVERROR
(EIO);
163
}
164
av_dlog
(context,
"DV1394: status\n"
165
"\tactive_frame\t%d\n"
166
"\tfirst_clear_frame\t%d\n"
167
"\tn_clear_frames\t%d\n"
168
"\tdropped_frames\t%d\n"
,
169
s.
active_frame
, s.
first_clear_frame
,
170
s.
n_clear_frames
, s.
dropped_frames
);
171
172
dv->
avail
= s.
n_clear_frames
;
173
dv->
index
= s.
first_clear_frame
;
174
dv->
done
= 0;
175
176
if
(s.
dropped_frames
) {
177
av_log
(context,
AV_LOG_ERROR
,
"DV1394: Frame drop detected (%d). Reseting ..\n"
,
178
s.
dropped_frames
);
179
180
dv1394_reset
(dv);
181
dv1394_start
(dv);
182
}
183
}
184
185
av_dlog
(context,
"index %d, avail %d, done %d\n"
, dv->
index
, dv->
avail
,
186
dv->
done
);
187
188
size =
avpriv_dv_produce_packet
(dv->
dv_demux
, pkt,
189
dv->
ring
+ (dv->
index
*
DV1394_PAL_FRAME_SIZE
),
190
DV1394_PAL_FRAME_SIZE
);
191
dv->
index
= (dv->
index
+ 1) %
DV1394_RING_FRAMES
;
192
dv->
done
++; dv->
avail
--;
193
194
return
size
;
195
}
196
197
static
int
dv1394_close
(
AVFormatContext
* context)
198
{
199
struct
dv1394_data
*dv = context->
priv_data
;
200
201
/* Shutdown DV1394 receiver */
202
if
(ioctl(dv->
fd
,
DV1394_SHUTDOWN
, 0) < 0)
203
av_log
(context,
AV_LOG_ERROR
,
"Failed to shutdown DV1394: %s\n"
, strerror(errno));
204
205
/* Unmap ring buffer */
206
if
(munmap(dv->
ring
,
DV1394_NTSC_FRAME_SIZE
*
DV1394_RING_FRAMES
) < 0)
207
av_log
(context,
AV_LOG_ERROR
,
"Failed to munmap DV1394 ring buffer: %s\n"
, strerror(errno));
208
209
close
(dv->
fd
);
210
av_free
(dv->
dv_demux
);
211
212
return
0;
213
}
214
215
static
const
AVOption
options
[] = {
216
{
"standard"
,
""
, offsetof(
struct
dv1394_data
,
format
),
AV_OPT_TYPE_INT
, {.dbl =
DV1394_NTSC
},
DV1394_PAL
,
DV1394_NTSC
,
AV_OPT_FLAG_DECODING_PARAM
,
"standard"
},
217
{
"PAL"
,
""
, 0,
AV_OPT_TYPE_CONST
, {.dbl =
DV1394_PAL
}, 0, 0,
AV_OPT_FLAG_DECODING_PARAM
,
"standard"
},
218
{
"NTSC"
,
""
, 0,
AV_OPT_TYPE_CONST
, {.dbl =
DV1394_NTSC
}, 0, 0,
AV_OPT_FLAG_DECODING_PARAM
,
"standard"
},
219
{
"channel"
,
""
, offsetof(
struct
dv1394_data
,
channel
),
AV_OPT_TYPE_INT
, {.dbl =
DV1394_DEFAULT_CHANNEL
}, 0, INT_MAX,
AV_OPT_FLAG_DECODING_PARAM
},
220
{
NULL
},
221
};
222
223
static
const
AVClass
dv1394_class
= {
224
.
class_name
=
"DV1394 indev"
,
225
.item_name =
av_default_item_name
,
226
.option =
options
,
227
.version =
LIBAVUTIL_VERSION_INT
,
228
};
229
230
AVInputFormat
ff_dv1394_demuxer
= {
231
.
name
=
"dv1394"
,
232
.long_name =
NULL_IF_CONFIG_SMALL
(
"DV1394 A/V grab"
),
233
.priv_data_size =
sizeof
(
struct
dv1394_data
),
234
.read_header =
dv1394_read_header
,
235
.read_packet =
dv1394_read_packet
,
236
.read_close =
dv1394_close
,
237
.flags =
AVFMT_NOFILE
,
238
.priv_class = &
dv1394_class
,
239
};