FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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 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 <poll.h>
27
#include <sys/ioctl.h>
28
#include <sys/mman.h>
29
30
#include "
libavutil/internal.h
"
31
#include "
libavutil/log.h
"
32
#include "
libavutil/opt.h
"
33
#include "
avdevice.h
"
34
#include "
libavformat/dv.h
"
35
#include "
dv1394.h
"
36
37
struct
dv1394_data
{
38
AVClass
*
class
;
39
int
fd
;
40
int
channel
;
41
int
format
;
42
43
uint8_t
*
ring
;
/* Ring buffer */
44
int
index
;
/* Current frame index */
45
int
avail
;
/* Number of frames available for reading */
46
int
done
;
/* Number of completed frames */
47
48
DVDemuxContext
*
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
av_log
(NULL,
AV_LOG_ERROR
,
"Failed to start receiver: %s\n"
, strerror(errno));
78
return
-1;
79
}
80
return
0;
81
}
82
83
static
int
dv1394_read_header
(
AVFormatContext
* context)
84
{
85
struct
dv1394_data
*dv = context->
priv_data
;
86
87
dv->
dv_demux
=
avpriv_dv_init_demux
(context);
88
if
(!dv->
dv_demux
)
89
goto
failed;
90
91
/* Open and initialize DV1394 device */
92
dv->
fd
=
avpriv_open
(context->
filename
, O_RDONLY);
93
if
(dv->
fd
< 0) {
94
av_log
(context,
AV_LOG_ERROR
,
"Failed to open DV interface: %s\n"
, strerror(errno));
95
goto
failed;
96
}
97
98
if
(
dv1394_reset
(dv) < 0) {
99
av_log
(context,
AV_LOG_ERROR
,
"Failed to initialize DV interface: %s\n"
, strerror(errno));
100
goto
failed;
101
}
102
103
dv->
ring
= mmap(NULL,
DV1394_PAL_FRAME_SIZE
*
DV1394_RING_FRAMES
,
104
PROT_READ, MAP_PRIVATE, dv->
fd
, 0);
105
if
(dv->
ring
== MAP_FAILED) {
106
av_log
(context,
AV_LOG_ERROR
,
"Failed to mmap DV ring buffer: %s\n"
, strerror(errno));
107
goto
failed;
108
}
109
110
if
(
dv1394_start
(dv) < 0)
111
goto
failed;
112
113
return
0;
114
115
failed:
116
close
(dv->
fd
);
117
return
AVERROR
(EIO);
118
}
119
120
static
int
dv1394_read_packet
(
AVFormatContext
*context,
AVPacket
*
pkt
)
121
{
122
struct
dv1394_data
*dv = context->
priv_data
;
123
int
size
;
124
125
size =
avpriv_dv_get_packet
(dv->
dv_demux
, pkt);
126
if
(size > 0)
127
return
size
;
128
129
if
(!dv->
avail
) {
130
struct
dv1394_status
s;
131
struct
pollfd p;
132
133
if
(dv->
done
) {
134
/* Request more frames */
135
if
(ioctl(dv->
fd
,
DV1394_RECEIVE_FRAMES
, dv->
done
) < 0) {
136
/* This usually means that ring buffer overflowed.
137
* We have to reset :(.
138
*/
139
140
av_log
(context,
AV_LOG_ERROR
,
"DV1394: Ring buffer overflow. Reseting ..\n"
);
141
142
dv1394_reset
(dv);
143
dv1394_start
(dv);
144
}
145
dv->
done
= 0;
146
}
147
148
/* Wait until more frames are available */
149
restart_poll:
150
p.fd = dv->
fd
;
151
p.events = POLLIN | POLLERR | POLLHUP;
152
if
(poll(&p, 1, -1) < 0) {
153
if
(errno == EAGAIN || errno == EINTR)
154
goto
restart_poll;
155
av_log
(context,
AV_LOG_ERROR
,
"Poll failed: %s\n"
, strerror(errno));
156
return
AVERROR
(EIO);
157
}
158
159
if
(ioctl(dv->
fd
,
DV1394_GET_STATUS
, &s) < 0) {
160
av_log
(context,
AV_LOG_ERROR
,
"Failed to get status: %s\n"
, strerror(errno));
161
return
AVERROR
(EIO);
162
}
163
av_dlog
(context,
"DV1394: status\n"
164
"\tactive_frame\t%d\n"
165
"\tfirst_clear_frame\t%d\n"
166
"\tn_clear_frames\t%d\n"
167
"\tdropped_frames\t%d\n"
,
168
s.
active_frame
, s.
first_clear_frame
,
169
s.
n_clear_frames
, s.
dropped_frames
);
170
171
dv->
avail
= s.
n_clear_frames
;
172
dv->
index
= s.
first_clear_frame
;
173
dv->
done
= 0;
174
175
if
(s.
dropped_frames
) {
176
av_log
(context,
AV_LOG_ERROR
,
"DV1394: Frame drop detected (%d). Reseting ..\n"
,
177
s.
dropped_frames
);
178
179
dv1394_reset
(dv);
180
dv1394_start
(dv);
181
}
182
}
183
184
av_dlog
(context,
"index %d, avail %d, done %d\n"
, dv->
index
, dv->
avail
,
185
dv->
done
);
186
187
size =
avpriv_dv_produce_packet
(dv->
dv_demux
, pkt,
188
dv->
ring
+ (dv->
index
*
DV1394_PAL_FRAME_SIZE
),
189
DV1394_PAL_FRAME_SIZE
, -1);
190
dv->
index
= (dv->
index
+ 1) %
DV1394_RING_FRAMES
;
191
dv->
done
++; dv->
avail
--;
192
193
return
size
;
194
}
195
196
static
int
dv1394_close
(
AVFormatContext
* context)
197
{
198
struct
dv1394_data
*dv = context->
priv_data
;
199
200
/* Shutdown DV1394 receiver */
201
if
(ioctl(dv->
fd
,
DV1394_SHUTDOWN
, 0) < 0)
202
av_log
(context,
AV_LOG_ERROR
,
"Failed to shutdown DV1394: %s\n"
, strerror(errno));
203
204
/* Unmap ring buffer */
205
if
(munmap(dv->
ring
,
DV1394_NTSC_FRAME_SIZE
*
DV1394_RING_FRAMES
) < 0)
206
av_log
(context,
AV_LOG_ERROR
,
"Failed to munmap DV1394 ring buffer: %s\n"
, strerror(errno));
207
208
close
(dv->
fd
);
209
av_free
(dv->
dv_demux
);
210
211
return
0;
212
}
213
214
static
const
AVOption
options
[] = {
215
{
"standard"
,
""
, offsetof(
struct
dv1394_data
,
format
),
AV_OPT_TYPE_INT
, {.i64 =
DV1394_NTSC
},
DV1394_NTSC
,
DV1394_PAL
,
AV_OPT_FLAG_DECODING_PARAM
,
"standard"
},
216
{
"PAL"
,
""
, 0,
AV_OPT_TYPE_CONST
, {.i64 =
DV1394_PAL
}, 0, 0,
AV_OPT_FLAG_DECODING_PARAM
,
"standard"
},
217
{
"NTSC"
,
""
, 0,
AV_OPT_TYPE_CONST
, {.i64 =
DV1394_NTSC
}, 0, 0,
AV_OPT_FLAG_DECODING_PARAM
,
"standard"
},
218
{
"channel"
,
""
, offsetof(
struct
dv1394_data
,
channel
),
AV_OPT_TYPE_INT
, {.i64 =
DV1394_DEFAULT_CHANNEL
}, 0, INT_MAX,
AV_OPT_FLAG_DECODING_PARAM
},
219
{ NULL },
220
};
221
222
static
const
AVClass
dv1394_class
= {
223
.
class_name
=
"DV1394 indev"
,
224
.item_name =
av_default_item_name
,
225
.option =
options
,
226
.version =
LIBAVUTIL_VERSION_INT
,
227
};
228
229
AVInputFormat
ff_dv1394_demuxer
= {
230
.
name
=
"dv1394"
,
231
.long_name =
NULL_IF_CONFIG_SMALL
(
"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
.priv_class = &
dv1394_class
,
238
};
Generated on Sun Mar 23 2014 23:50:06 for FFmpeg by
1.8.2