1
/* v4l2-api: low-level wrapper around v4l2 devices
3
* Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program 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
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
#include <sys/ioctl.h>
28
bool v4l2::open(const QString &device, bool useWrapper)
31
m_useWrapper = useWrapper;
32
m_fd = ::open(device.toAscii(), O_RDWR | O_NONBLOCK);
34
error("Cannot open " + device);
37
if (!querycap(m_capability)) {
40
error(device + " is not a V4L2 device");
45
int fd = ::v4l2_fd_open(m_fd, V4L2_ENABLE_ENUM_FMT_EMULATION);
49
error("Cannot use libv4l2 wrapper for " + device);
64
int v4l2::ioctl(unsigned cmd, void *arg)
67
return v4l2_ioctl(m_fd, cmd, arg);
68
return ::ioctl(m_fd, cmd, arg);
71
bool v4l2::ioctl(const QString &descr, unsigned cmd, void *arg)
74
int err = ioctl(cmd, arg);
77
QString s = strerror(errno);
78
error(descr + ": " + s);
83
int v4l2::read(unsigned char *p, int size)
86
return v4l2_read(m_fd, p, size);
87
return ::read(m_fd, p, size);
90
void *v4l2::mmap(size_t length, __off64_t offset)
93
return v4l2_mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, offset);
94
return ::mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, offset);
97
int v4l2::munmap(void *start, size_t length)
100
return v4l2_munmap(start, length);
101
return ::munmap(start, length);
104
void v4l2::error(const QString &error)
106
if (!error.isEmpty())
107
fprintf(stderr, "%s\n", error.toAscii().data());
110
QString v4l2::pixfmt2s(unsigned id)
114
pixfmt += (char)(id & 0xff);
115
pixfmt += (char)((id >> 8) & 0xff);
116
pixfmt += (char)((id >> 16) & 0xff);
117
pixfmt += (char)((id >> 24) & 0xff);
121
bool v4l2::querycap(v4l2_capability &cap)
123
memset(&cap, 0, sizeof(cap));
124
return ioctl(VIDIOC_QUERYCAP, &cap) >= 0;
127
bool v4l2::queryctrl(v4l2_queryctrl &qc)
129
return ioctl(VIDIOC_QUERYCTRL, &qc) >= 0;
132
bool v4l2::querymenu(v4l2_querymenu &qm)
134
return ioctl(VIDIOC_QUERYMENU, &qm) >= 0;
137
bool v4l2::g_tuner(v4l2_tuner &tuner)
139
memset(&tuner, 0, sizeof(tuner));
140
if (ioctl(VIDIOC_G_TUNER, &tuner) < 0)
142
if (tuner.rangehigh > INT_MAX)
143
tuner.rangehigh = INT_MAX;
147
bool v4l2::g_input(int &input)
149
return ioctl(VIDIOC_G_INPUT, &input) >= 0;
152
bool v4l2::s_input(int input)
154
return ioctl("Set Input", VIDIOC_S_INPUT, &input);
157
bool v4l2::g_output(int &output)
159
return ioctl(VIDIOC_G_OUTPUT, &output) >= 0;
162
bool v4l2::s_output(int output)
164
return ioctl("Set Output", VIDIOC_S_OUTPUT, &output);
167
bool v4l2::g_audio(v4l2_audio &audio)
169
memset(&audio, 0, sizeof(audio));
170
return ioctl(VIDIOC_G_AUDIO, &audio) >= 0;
173
bool v4l2::s_audio(int input)
177
memset(&audio, 0, sizeof(audio));
179
return ioctl("Set Audio Input", VIDIOC_S_AUDIO, &audio);
182
bool v4l2::g_audout(v4l2_audioout &audout)
184
memset(&audout, 0, sizeof(audout));
185
return ioctl(VIDIOC_G_AUDOUT, &audout) >= 0;
188
bool v4l2::s_audout(int output)
190
v4l2_audioout audout;
192
memset(&audout, 0, sizeof(audout));
193
audout.index = output;
194
return ioctl("Set Audio Output", VIDIOC_S_AUDOUT, &audout);
197
bool v4l2::g_std(v4l2_std_id &std)
199
return ioctl(VIDIOC_G_STD, &std) >= 0;
202
bool v4l2::s_std(v4l2_std_id std)
204
return ioctl("Set TV Standard", VIDIOC_S_STD, &std);
207
bool v4l2::g_frequency(v4l2_frequency &freq)
209
memset(&freq, 0, sizeof(freq));
210
freq.type = V4L2_TUNER_ANALOG_TV;
211
return ioctl(VIDIOC_G_FREQUENCY, &freq) >= 0;
214
bool v4l2::s_frequency(v4l2_frequency &freq)
216
return ioctl("Set Frequency", VIDIOC_S_FREQUENCY, &freq);
219
bool v4l2::s_frequency(int val)
223
memset(&f, 0, sizeof(f));
224
f.type = V4L2_TUNER_ANALOG_TV;
226
return s_frequency(f);
229
bool v4l2::g_fmt_cap(v4l2_format &fmt)
231
memset(&fmt, 0, sizeof(fmt));
232
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
233
return ioctl(VIDIOC_G_FMT, &fmt) >= 0;
236
bool v4l2::g_fmt_out(v4l2_format &fmt)
238
memset(&fmt, 0, sizeof(fmt));
239
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
240
return ioctl(VIDIOC_G_FMT, &fmt) >= 0;
243
bool v4l2::try_fmt(v4l2_format &fmt)
245
return ioctl("Try Capture Format", VIDIOC_TRY_FMT, &fmt);
248
bool v4l2::s_fmt(v4l2_format &fmt)
250
return ioctl("Set Capture Format", VIDIOC_S_FMT, &fmt);
253
bool v4l2::enum_input(v4l2_input &in, bool init)
256
memset(&in, 0, sizeof(in));
259
return ioctl(VIDIOC_ENUMINPUT, &in) >= 0;
262
bool v4l2::enum_output(v4l2_output &out, bool init)
265
memset(&out, 0, sizeof(out));
268
return ioctl(VIDIOC_ENUMOUTPUT, &out) >= 0;
271
bool v4l2::enum_audio(v4l2_audio &audio, bool init)
274
memset(&audio, 0, sizeof(audio));
277
return ioctl(VIDIOC_ENUMAUDIO, &audio) >= 0;
280
bool v4l2::enum_audout(v4l2_audioout &audout, bool init)
283
memset(&audout, 0, sizeof(audout));
286
return ioctl(VIDIOC_ENUMAUDOUT, &audout) >= 0;
289
bool v4l2::enum_std(v4l2_standard &std, bool init, int index)
292
memset(&std, 0, sizeof(std));
297
return ioctl(VIDIOC_ENUMSTD, &std) >= 0;
300
bool v4l2::enum_fmt_cap(v4l2_fmtdesc &fmt, bool init, int index)
303
memset(&fmt, 0, sizeof(fmt));
308
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
309
return ioctl(VIDIOC_ENUM_FMT, &fmt) >= 0;
312
bool v4l2::enum_fmt_out(v4l2_fmtdesc &fmt, bool init, int index)
315
memset(&fmt, 0, sizeof(fmt));
320
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
321
return ioctl(VIDIOC_ENUM_FMT, &fmt) >= 0;
324
bool v4l2::enum_framesizes(v4l2_frmsizeenum &frm, __u32 init_pixfmt, int index)
327
memset(&frm, 0, sizeof(frm));
328
frm.pixel_format = init_pixfmt;
333
return ioctl(VIDIOC_ENUM_FRAMESIZES, &frm) >= 0;
336
bool v4l2::enum_frameintervals(v4l2_frmivalenum &frm, __u32 init_pixfmt, __u32 w, __u32 h, int index)
339
memset(&frm, 0, sizeof(frm));
340
frm.pixel_format = init_pixfmt;
347
return ioctl(VIDIOC_ENUM_FRAMEINTERVALS, &frm) >= 0;
350
bool v4l2::reqbufs_user_cap(v4l2_requestbuffers &reqbuf, int count)
352
memset(&reqbuf, 0, sizeof (reqbuf));
353
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
354
reqbuf.memory = V4L2_MEMORY_USERPTR;
355
reqbuf.count = count;
357
return ioctl(VIDIOC_REQBUFS, &reqbuf) >= 0;
360
bool v4l2::reqbufs_mmap_cap(v4l2_requestbuffers &reqbuf, int count)
362
memset(&reqbuf, 0, sizeof (reqbuf));
363
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
364
reqbuf.memory = V4L2_MEMORY_MMAP;
365
reqbuf.count = count;
367
return ioctl(VIDIOC_REQBUFS, &reqbuf) >= 0;
370
bool v4l2::dqbuf_mmap_cap(v4l2_buffer &buf)
372
memset(&buf, 0, sizeof(buf));
373
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
374
buf.memory = V4L2_MEMORY_MMAP;
375
return ioctl(VIDIOC_DQBUF, &buf) >= 0;
378
bool v4l2::dqbuf_user_cap(v4l2_buffer &buf)
380
memset(&buf, 0, sizeof(buf));
381
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
382
buf.memory = V4L2_MEMORY_USERPTR;
383
return ioctl(VIDIOC_DQBUF, &buf) >= 0;
386
bool v4l2::qbuf(v4l2_buffer &buf)
388
return ioctl(VIDIOC_QBUF, &buf) >= 0;
391
bool v4l2::qbuf_mmap_cap(int index)
395
memset(&buf, 0, sizeof(buf));
396
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
397
buf.memory = V4L2_MEMORY_MMAP;
402
bool v4l2::qbuf_user_cap(int index, void *ptr, int length)
406
memset(&buf, 0, sizeof(buf));
407
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
408
buf.memory = V4L2_MEMORY_USERPTR;
409
buf.m.userptr = (unsigned long)ptr;
415
bool v4l2::streamon_cap()
417
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
419
return ioctl("Start Capture", VIDIOC_STREAMON, &type);
422
bool v4l2::streamoff_cap()
424
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
426
return ioctl("Stop Capture", VIDIOC_STREAMOFF, &type);
429
bool v4l2::reqbufs_user_out(v4l2_requestbuffers &reqbuf)
431
memset(&reqbuf, 0, sizeof (reqbuf));
432
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
433
reqbuf.memory = V4L2_MEMORY_USERPTR;
435
return ioctl(VIDIOC_REQBUFS, &reqbuf) >= 0;
438
bool v4l2::reqbufs_mmap_out(v4l2_requestbuffers &reqbuf, int count)
440
memset(&reqbuf, 0, sizeof (reqbuf));
441
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
442
reqbuf.memory = V4L2_MEMORY_MMAP;
443
reqbuf.count = count;
445
return ioctl(VIDIOC_REQBUFS, &reqbuf) >= 0;
448
bool v4l2::dqbuf_mmap_out(v4l2_buffer &buf)
450
memset(&buf, 0, sizeof(buf));
451
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
452
buf.memory = V4L2_MEMORY_MMAP;
453
return ioctl("dqbuf", VIDIOC_DQBUF, &buf);
456
bool v4l2::dqbuf_user_out(v4l2_buffer &buf)
458
memset(&buf, 0, sizeof(buf));
459
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
460
buf.memory = V4L2_MEMORY_USERPTR;
461
return ioctl(VIDIOC_DQBUF, &buf) >= 0;
464
bool v4l2::qbuf_mmap_out(int index, int bytesused)
468
memset(&buf, 0, sizeof(buf));
469
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
470
buf.memory = V4L2_MEMORY_MMAP;
472
buf.bytesused = bytesused;
476
bool v4l2::qbuf_user_out(void *ptr, int length)
480
memset(&buf, 0, sizeof(buf));
481
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
482
buf.memory = V4L2_MEMORY_USERPTR;
483
buf.m.userptr = (unsigned long)ptr;
488
bool v4l2::streamon_out()
490
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
492
return ioctl("Start Output", VIDIOC_STREAMON, &type);
495
bool v4l2::streamoff_out()
497
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
499
return ioctl("Stop Output", VIDIOC_STREAMOFF, &type);