1 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2 /*
3 * V4L2 C++ helper header providing wrappers to simplify access to the various
4 * v4l2 functions.
5 *
6 * Copyright 2014-2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
7 */
8
9 #ifndef _CV4L_HELPERS_H_
10 #define _CV4L_HELPERS_H_
11
12 #include <limits.h>
13 #include <v4l-helpers.h>
14
15 #define cv4l_ioctl(cmd, arg) v4l_named_ioctl(g_v4l_fd(), #cmd, cmd, arg)
16
17 class cv4l_fd : v4l_fd {
18 public:
cv4l_fd()19 cv4l_fd()
20 {
21 v4l_fd_init(this);
22 }
cv4l_fd(cv4l_fd * fd)23 cv4l_fd(cv4l_fd *fd)
24 {
25 *this = *fd;
26 }
27 cv4l_fd &operator= (const cv4l_fd &_fd)
28 {
29 memcpy(this, &_fd, sizeof(_fd));
30 if (_fd.fd >= 0)
31 fd = dup(_fd.fd);
32 return *this;
33 }
34
is_subdev()35 bool is_subdev() const { return v4l_fd_is_subdev(this); }
is_media()36 bool is_media() const { return v4l_fd_is_media(this); }
is_v4l2()37 bool is_v4l2() const { return v4l_fd_is_v4l2(this); }
g_type()38 __u32 g_type() const { return type; }
s_type(__u32 type)39 void s_type(__u32 type) { v4l_s_type(this, type); }
g_selection_type()40 __u32 g_selection_type() const { return v4l_g_selection_type(this); }
g_caps()41 __u32 g_caps() const { return caps; }
g_fd()42 int g_fd() const { return fd; }
g_v4l_fd()43 v4l_fd *g_v4l_fd() { return this; }
g_direct()44 bool g_direct() const { return v4l_fd_g_direct(this); }
s_direct(bool direct)45 void s_direct(bool direct) { v4l_fd_s_direct(this, direct); }
g_trace()46 unsigned int g_trace() const { return v4l_fd_g_trace(this); }
s_trace(unsigned int trace)47 void s_trace(unsigned int trace) { v4l_fd_s_trace(this, trace); }
48
49 int open(const char *devname, bool non_blocking = false) { return v4l_open(this, devname, non_blocking); }
s_fd(int fd,const char * devname,bool direct)50 int s_fd(int fd, const char *devname, bool direct) { return v4l_s_fd(this, fd, devname, direct); }
51 int subdev_open(const char *devname, bool non_blocking = false) { return v4l_subdev_open(this, devname, non_blocking); }
subdev_s_fd(int fd,const char * devname)52 int subdev_s_fd(int fd, const char *devname) { return v4l_subdev_s_fd(this, fd, devname); }
53 int media_open(const char *devname, bool non_blocking = false) { return v4l_media_open(this, devname, non_blocking); }
media_s_fd(int fd,const char * devname)54 int media_s_fd(int fd, const char *devname) { return v4l_media_s_fd(this, fd, devname); }
close()55 int close() { return v4l_close(this); }
56 int reopen(bool non_blocking = false) { return v4l_reopen(this, non_blocking); }
read(void * buffer,size_t n)57 ssize_t read(void *buffer, size_t n) { return v4l_read(this, buffer, n); }
write(const void * buffer,size_t n)58 ssize_t write(const void *buffer, size_t n) { return v4l_write(this, buffer, n); }
mmap(size_t length,off_t offset)59 void *mmap(size_t length, off_t offset) { return v4l_mmap(this, length, offset); }
munmap(void * start,size_t length)60 int munmap(void *start, size_t length) { return v4l_munmap(this, start, length); }
61
has_vid_cap()62 bool has_vid_cap() const { return v4l_has_vid_cap(this); }
has_vid_out()63 bool has_vid_out() const { return v4l_has_vid_out(this); }
has_vid_m2m()64 bool has_vid_m2m() const { return v4l_has_vid_m2m(this); }
has_vid_mplane()65 bool has_vid_mplane() const { return v4l_has_vid_mplane(this); }
has_overlay_cap()66 bool has_overlay_cap() const { return v4l_has_overlay_cap(this); }
has_overlay_out()67 bool has_overlay_out() const { return v4l_has_overlay_out(this); }
has_raw_vbi_cap()68 bool has_raw_vbi_cap() const { return v4l_has_raw_vbi_cap(this); }
has_sliced_vbi_cap()69 bool has_sliced_vbi_cap() const { return v4l_has_sliced_vbi_cap(this); }
has_vbi_cap()70 bool has_vbi_cap() const { return v4l_has_vbi_cap(this); }
has_raw_vbi_out()71 bool has_raw_vbi_out() const { return v4l_has_raw_vbi_out(this); }
has_sliced_vbi_out()72 bool has_sliced_vbi_out() const { return v4l_has_sliced_vbi_out(this); }
has_vbi_out()73 bool has_vbi_out() const { return v4l_has_vbi_out(this); }
has_vbi()74 bool has_vbi() const { return v4l_has_vbi(this); }
has_radio_rx()75 bool has_radio_rx() const { return v4l_has_radio_rx(this); }
has_radio_tx()76 bool has_radio_tx() const { return v4l_has_radio_tx(this); }
has_rds_cap()77 bool has_rds_cap() const { return v4l_has_rds_cap(this); }
has_rds_out()78 bool has_rds_out() const { return v4l_has_rds_out(this); }
has_sdr_cap()79 bool has_sdr_cap() const { return v4l_has_sdr_cap(this); }
has_sdr_out()80 bool has_sdr_out() const { return v4l_has_sdr_out(this); }
has_touch()81 bool has_touch() const { return v4l_has_touch(this); }
has_meta_cap()82 bool has_meta_cap() const { return v4l_has_meta_cap(this); }
has_meta_out()83 bool has_meta_out() const { return v4l_has_meta_out(this); }
has_hwseek()84 bool has_hwseek() const { return v4l_has_hwseek(this); }
has_rw()85 bool has_rw() const { return v4l_has_rw(this); }
has_streaming()86 bool has_streaming() const { return v4l_has_streaming(this); }
has_ext_pix_format()87 bool has_ext_pix_format() const { return v4l_has_ext_pix_format(this); }
has_streams()88 bool has_streams() const { return have_streams; }
has_ival_uses_which()89 bool has_ival_uses_which() const { return ival_uses_which; }
90
91 int querycap(v4l2_capability &cap, bool force = false)
92 {
93 if (force)
94 return cv4l_ioctl(VIDIOC_QUERYCAP, &cap);
95 cap = this->cap;
96 return 0;
97 }
98
queryctrl(v4l2_queryctrl & qc)99 int queryctrl(v4l2_queryctrl &qc)
100 {
101 return cv4l_ioctl(VIDIOC_QUERYCTRL, &qc);
102 }
103
querymenu(v4l2_querymenu & qm)104 int querymenu(v4l2_querymenu &qm)
105 {
106 return cv4l_ioctl(VIDIOC_QUERYMENU, &qm);
107 }
108
109 int query_ext_ctrl(v4l2_query_ext_ctrl &qec, bool next_ctrl = false, bool next_compound = false)
110 {
111 return v4l_query_ext_ctrl(this, &qec, next_ctrl, next_compound);
112 }
113
g_ctrl(v4l2_control & ctrl)114 int g_ctrl(v4l2_control &ctrl)
115 {
116 return cv4l_ioctl(VIDIOC_G_CTRL, &ctrl);
117 }
118
s_ctrl(v4l2_control & ctrl)119 int s_ctrl(v4l2_control &ctrl)
120 {
121 return cv4l_ioctl(VIDIOC_S_CTRL, &ctrl);
122 }
123
g_ext_ctrls(v4l2_ext_controls & ec)124 int g_ext_ctrls(v4l2_ext_controls &ec)
125 {
126 return v4l_g_ext_ctrls(this, &ec);
127 }
128
try_ext_ctrls(v4l2_ext_controls & ec)129 int try_ext_ctrls(v4l2_ext_controls &ec)
130 {
131 return v4l_try_ext_ctrls(this, &ec);
132 }
133
s_ext_ctrls(v4l2_ext_controls & ec)134 int s_ext_ctrls(v4l2_ext_controls &ec)
135 {
136 return v4l_s_ext_ctrls(this, &ec);
137 }
138
139 int g_fmt(v4l2_format &fmt, unsigned type = 0)
140 {
141 return v4l_g_fmt(this, &fmt, type);
142 }
143
144 int try_fmt(v4l2_format &fmt, bool zero_bpl = true)
145 {
146 return v4l_try_fmt(this, &fmt, zero_bpl);
147 }
148
149 int s_fmt(v4l2_format &fmt, bool zero_bpl = true)
150 {
151 return v4l_s_fmt(this, &fmt, zero_bpl);
152 }
153
g_selection(v4l2_selection & sel)154 int g_selection(v4l2_selection &sel)
155 {
156 return v4l_g_selection(this, &sel);
157 }
158
s_selection(v4l2_selection & sel)159 int s_selection(v4l2_selection &sel)
160 {
161 return v4l_s_selection(this, &sel);
162 }
163
g_frame_selection(v4l2_selection & sel,__u32 field)164 int g_frame_selection(v4l2_selection &sel, __u32 field)
165 {
166 return v4l_g_frame_selection(this, &sel, field);
167 }
168
s_frame_selection(v4l2_selection & sel,__u32 field)169 int s_frame_selection(v4l2_selection &sel, __u32 field)
170 {
171 return v4l_s_frame_selection(this, &sel, field);
172 }
173
174 int g_tuner(v4l2_tuner &tuner, unsigned index = 0)
175 {
176 memset(&tuner, 0, sizeof(tuner));
177 tuner.index = index;
178 int ret = cv4l_ioctl(VIDIOC_G_TUNER, &tuner);
179 if (ret == 0 && tuner.rangehigh > INT_MAX)
180 tuner.rangehigh = INT_MAX;
181 return ret;
182 }
183
s_tuner(v4l2_tuner & tuner)184 int s_tuner(v4l2_tuner &tuner)
185 {
186 return cv4l_ioctl(VIDIOC_S_TUNER, &tuner);
187 }
188
189 int g_modulator(v4l2_modulator &modulator, unsigned index = 0)
190 {
191 memset(&modulator, 0, sizeof(modulator));
192 modulator.index = index;
193 return cv4l_ioctl(VIDIOC_G_MODULATOR, &modulator);
194 }
195
s_modulator(v4l2_modulator & modulator)196 int s_modulator(v4l2_modulator &modulator)
197 {
198 return cv4l_ioctl(VIDIOC_S_MODULATOR, &modulator);
199 }
200
201 int enum_input(v4l2_input &in, bool init = false, int index = 0)
202 {
203 if (init) {
204 memset(&in, 0, sizeof(in));
205 in.index = index;
206 } else {
207 in.index++;
208 }
209 return cv4l_ioctl(VIDIOC_ENUMINPUT, &in);
210 }
211
212 int enum_output(v4l2_output &out, bool init = false, int index = 0)
213 {
214 if (init) {
215 memset(&out, 0, sizeof(out));
216 out.index = index;
217 } else {
218 out.index++;
219 }
220 return cv4l_ioctl(VIDIOC_ENUMOUTPUT, &out);
221 }
222
223 int enum_audio(v4l2_audio &audio, bool init = false, int index = 0)
224 {
225 if (init) {
226 memset(&audio, 0, sizeof(audio));
227 audio.index = index;
228 } else {
229 audio.index++;
230 }
231 return cv4l_ioctl(VIDIOC_ENUMAUDIO, &audio);
232 }
233
234 int enum_audout(v4l2_audioout &audout, bool init = false, int index = 0)
235 {
236 if (init) {
237 memset(&audout, 0, sizeof(audout));
238 audout.index = index;
239 } else {
240 audout.index++;
241 }
242 return cv4l_ioctl(VIDIOC_ENUMAUDOUT, &audout);
243 }
244
has_crop()245 bool has_crop()
246 {
247 v4l2_selection sel;
248
249 memset(&sel, 0, sizeof(sel));
250 sel.type = g_selection_type();
251 sel.target = V4L2_SEL_TGT_CROP;
252 return g_selection(sel) != ENOTTY;
253 }
254
has_compose()255 bool has_compose()
256 {
257 v4l2_selection sel;
258
259 memset(&sel, 0, sizeof(sel));
260 sel.type = g_selection_type();
261 sel.target = V4L2_SEL_TGT_COMPOSE;
262 return g_selection(sel) != ENOTTY;
263 }
264
cur_io_has_crop()265 bool cur_io_has_crop()
266 {
267 v4l2_selection sel;
268
269 memset(&sel, 0, sizeof(sel));
270 sel.type = g_selection_type();
271 sel.target = V4L2_SEL_TGT_CROP;
272 return g_selection(sel) == 0;
273 }
274
cur_io_has_compose()275 bool cur_io_has_compose()
276 {
277 v4l2_selection sel;
278
279 memset(&sel, 0, sizeof(sel));
280 sel.type = g_selection_type();
281 sel.target = V4L2_SEL_TGT_COMPOSE;
282 return g_selection(sel) == 0;
283 }
284
subscribe_event(v4l2_event_subscription & sub)285 int subscribe_event(v4l2_event_subscription &sub)
286 {
287 return cv4l_ioctl(VIDIOC_SUBSCRIBE_EVENT, &sub);
288 }
289
unsubscribe_event(v4l2_event_subscription & sub)290 int unsubscribe_event(v4l2_event_subscription &sub)
291 {
292 return cv4l_ioctl(VIDIOC_UNSUBSCRIBE_EVENT, &sub);
293 }
294
dqevent(v4l2_event & ev)295 int dqevent(v4l2_event &ev)
296 {
297 return cv4l_ioctl(VIDIOC_DQEVENT, &ev);
298 }
299
g_input(__u32 & input)300 int g_input(__u32 &input)
301 {
302 return cv4l_ioctl(VIDIOC_G_INPUT, &input);
303 }
304
s_input(__u32 input)305 int s_input(__u32 input)
306 {
307 return cv4l_ioctl(VIDIOC_S_INPUT, &input);
308 }
309
g_output(__u32 & output)310 int g_output(__u32 &output)
311 {
312 return cv4l_ioctl(VIDIOC_G_OUTPUT, &output);
313 }
314
s_output(__u32 output)315 int s_output(__u32 output)
316 {
317 return cv4l_ioctl(VIDIOC_S_OUTPUT, &output);
318 }
319
g_audio(v4l2_audio & audio)320 int g_audio(v4l2_audio &audio)
321 {
322 memset(&audio, 0, sizeof(audio));
323 return cv4l_ioctl(VIDIOC_G_AUDIO, &audio);
324 }
325
s_audio(__u32 input)326 int s_audio(__u32 input)
327 {
328 v4l2_audio audio;
329
330 memset(&audio, 0, sizeof(audio));
331 audio.index = input;
332 return cv4l_ioctl(VIDIOC_S_AUDIO, &audio);
333 }
334
g_audout(v4l2_audioout & audout)335 int g_audout(v4l2_audioout &audout)
336 {
337 memset(&audout, 0, sizeof(audout));
338 return cv4l_ioctl(VIDIOC_G_AUDOUT, &audout);
339 }
340
s_audout(__u32 output)341 int s_audout(__u32 output)
342 {
343 v4l2_audioout audout;
344
345 memset(&audout, 0, sizeof(audout));
346 audout.index = output;
347 return cv4l_ioctl(VIDIOC_S_AUDOUT, &audout);
348 }
349
g_std(v4l2_std_id & std)350 int g_std(v4l2_std_id &std)
351 {
352 return cv4l_ioctl(VIDIOC_G_STD, &std);
353 }
354
s_std(v4l2_std_id std)355 int s_std(v4l2_std_id std)
356 {
357 return cv4l_ioctl(VIDIOC_S_STD, &std);
358 }
359
query_std(v4l2_std_id & std)360 int query_std(v4l2_std_id &std)
361 {
362 return cv4l_ioctl(VIDIOC_QUERYSTD, &std);
363 }
364
dv_timings_cap(v4l2_dv_timings_cap & cap)365 int dv_timings_cap(v4l2_dv_timings_cap &cap)
366 {
367 cap.pad = 0;
368 memset(cap.reserved, 0, sizeof(cap.reserved));
369 return cv4l_ioctl(VIDIOC_DV_TIMINGS_CAP, &cap);
370 }
371
g_dv_timings(v4l2_dv_timings & timings)372 int g_dv_timings(v4l2_dv_timings &timings)
373 {
374 return cv4l_ioctl(VIDIOC_G_DV_TIMINGS, &timings);
375 }
376
s_dv_timings(v4l2_dv_timings & timings)377 int s_dv_timings(v4l2_dv_timings &timings)
378 {
379 if (timings.type == V4L2_DV_BT_656_1120)
380 memset(timings.bt.reserved, 0,
381 sizeof(timings.bt.reserved));
382 return cv4l_ioctl(VIDIOC_S_DV_TIMINGS, &timings);
383 }
384
query_dv_timings(v4l2_dv_timings & timings)385 int query_dv_timings(v4l2_dv_timings &timings)
386 {
387 return cv4l_ioctl(VIDIOC_QUERY_DV_TIMINGS, &timings);
388 }
389
390 int g_frequency(v4l2_frequency &freq, unsigned index = 0)
391 {
392 memset(&freq, 0, sizeof(freq));
393 freq.tuner = index;
394 freq.type = V4L2_TUNER_ANALOG_TV;
395 return cv4l_ioctl(VIDIOC_G_FREQUENCY, &freq);
396 }
397
s_frequency(v4l2_frequency & freq)398 int s_frequency(v4l2_frequency &freq)
399 {
400 return cv4l_ioctl(VIDIOC_S_FREQUENCY, &freq);
401 }
402
g_priority(__u32 & prio)403 int g_priority(__u32 &prio)
404 {
405 return cv4l_ioctl(VIDIOC_G_PRIORITY, &prio);
406 }
407
408 int s_priority(__u32 prio = V4L2_PRIORITY_DEFAULT)
409 {
410 return cv4l_ioctl(VIDIOC_S_PRIORITY, &prio);
411 }
412
413 int streamon(__u32 type = 0)
414 {
415 if (type == 0)
416 type = g_type();
417 return cv4l_ioctl(VIDIOC_STREAMON, &type);
418 }
419
420 int streamoff(__u32 type = 0)
421 {
422 if (type == 0)
423 type = g_type();
424 return cv4l_ioctl(VIDIOC_STREAMOFF, &type);
425 }
426
querybuf(v4l_buffer & buf)427 int querybuf(v4l_buffer &buf)
428 {
429 return v4l_buffer_querybuf(this, &buf,
430 v4l_buffer_g_index(&buf));
431 }
432
querybuf(v4l_buffer & buf,unsigned index)433 int querybuf(v4l_buffer &buf, unsigned index)
434 {
435 return v4l_buffer_querybuf(this, &buf, index);
436 }
437
dqbuf(v4l_buffer & buf)438 int dqbuf(v4l_buffer &buf)
439 {
440 return v4l_buffer_dqbuf(this, &buf);
441 }
442
qbuf(v4l_buffer & buf)443 int qbuf(v4l_buffer &buf)
444 {
445 return v4l_buffer_qbuf(this, &buf);
446 }
447
prepare_buf(v4l_buffer & buf)448 int prepare_buf(v4l_buffer &buf)
449 {
450 return v4l_buffer_prepare_buf(this, &buf);
451 }
452
453 int enum_std(v4l2_standard &std, bool init = false, int index = 0)
454 {
455 if (init) {
456 memset(&std, 0, sizeof(std));
457 std.index = index;
458 } else {
459 std.index++;
460 }
461 return cv4l_ioctl(VIDIOC_ENUMSTD, &std);
462 }
463
464 int enum_freq_bands(v4l2_frequency_band &band, unsigned tuner, bool init = false, int index = 0)
465 {
466 if (init) {
467 memset(&band, 0, sizeof(band));
468 band.index = index;
469 } else {
470 band.index++;
471 }
472 band.tuner = tuner;
473 if (has_radio_tx() || has_radio_rx())
474 band.type = V4L2_TUNER_RADIO;
475 else
476 band.type = V4L2_TUNER_ANALOG_TV;
477 return cv4l_ioctl(VIDIOC_ENUM_FREQ_BANDS, &band);
478 }
479
480 int enum_dv_timings(v4l2_enum_dv_timings &timings, bool init = false, int index = 0)
481 {
482 if (init) {
483 memset(&timings, 0, sizeof(timings));
484 timings.index = index;
485 } else {
486 timings.index++;
487 }
488 return cv4l_ioctl(VIDIOC_ENUM_DV_TIMINGS, &timings);
489 }
490
491 int enum_fmt(v4l2_fmtdesc &fmt, bool init = false, int index = 0, unsigned type = 0, __u32 mbus_code = 0)
492 {
493 if (init) {
494 memset(&fmt, 0, sizeof(fmt));
495 fmt.type = type ? type : g_type();
496 fmt.index = index;
497 fmt.mbus_code = mbus_code;
498 } else {
499 fmt.index++;
500 }
501 return cv4l_ioctl(VIDIOC_ENUM_FMT, &fmt);
502 }
503
504 int enum_framesizes(v4l2_frmsizeenum &frm, __u32 init_pixfmt = 0, int index = 0)
505 {
506 if (init_pixfmt) {
507 memset(&frm, 0, sizeof(frm));
508 frm.pixel_format = init_pixfmt;
509 frm.index = index;
510 } else {
511 frm.index++;
512 }
513 return cv4l_ioctl(VIDIOC_ENUM_FRAMESIZES, &frm);
514 }
515
516 int enum_frameintervals(v4l2_frmivalenum &frm, __u32 init_pixfmt = 0, __u32 w = 0, __u32 h = 0, int index = 0)
517 {
518 if (init_pixfmt) {
519 memset(&frm, 0, sizeof(frm));
520 frm.pixel_format = init_pixfmt;
521 frm.width = w;
522 frm.height = h;
523 frm.index = index;
524 } else {
525 frm.index++;
526 }
527 return cv4l_ioctl(VIDIOC_ENUM_FRAMEINTERVALS, &frm);
528 }
529
530 int set_interval(v4l2_fract interval, unsigned type = 0)
531 {
532 v4l2_streamparm parm;
533
534 parm.type = type ? type : g_type();
535 memset(parm.parm.capture.reserved, 0, sizeof(parm.parm.capture.reserved));
536 if (cv4l_ioctl(VIDIOC_G_PARM, &parm) ||
537 !(parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME))
538 return -1;
539
540 parm.parm.capture.timeperframe = interval;
541
542 return cv4l_ioctl(VIDIOC_S_PARM, &parm);
543 }
544
545 int get_interval(v4l2_fract &interval, unsigned type = 0)
546 {
547 v4l2_streamparm parm;
548
549 parm.type = type ? type : g_type();
550 memset(parm.parm.capture.reserved, 0, sizeof(parm.parm.capture.reserved));
551 if (cv4l_ioctl(VIDIOC_G_PARM, &parm) == 0 &&
552 (parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) {
553 interval = parm.parm.capture.timeperframe;
554 return 0;
555 }
556
557 return -1;
558 }
559
g_fbuf(v4l2_framebuffer & fbuf)560 int g_fbuf(v4l2_framebuffer &fbuf)
561 {
562 return cv4l_ioctl(VIDIOC_G_FBUF, &fbuf);
563 }
564
s_fbuf(v4l2_framebuffer & fbuf)565 int s_fbuf(v4l2_framebuffer &fbuf)
566 {
567 fbuf.fmt.priv = 0;
568 return cv4l_ioctl(VIDIOC_S_FBUF, &fbuf);
569 }
570
overlay(bool enable)571 int overlay(bool enable)
572 {
573 int ena = enable;
574
575 return cv4l_ioctl(VIDIOC_OVERLAY, &ena);
576 }
577
g_jpegcomp(v4l2_jpegcompression & jpeg)578 int g_jpegcomp(v4l2_jpegcompression &jpeg)
579 {
580 return cv4l_ioctl(VIDIOC_G_JPEGCOMP, &jpeg);
581 }
582
s_jpegcomp(v4l2_jpegcompression & jpeg)583 int s_jpegcomp(v4l2_jpegcompression &jpeg)
584 {
585 return cv4l_ioctl(VIDIOC_S_JPEGCOMP, &jpeg);
586 }
587
g_edid(v4l2_edid & edid)588 int g_edid(v4l2_edid &edid)
589 {
590 memset(edid.reserved, 0, sizeof(edid.reserved));
591 return cv4l_ioctl(VIDIOC_G_EDID, &edid);
592 }
593
s_edid(v4l2_edid & edid)594 int s_edid(v4l2_edid &edid)
595 {
596 memset(edid.reserved, 0, sizeof(edid.reserved));
597 return cv4l_ioctl(VIDIOC_S_EDID, &edid);
598 }
599
g_sliced_vbi_cap(v4l2_sliced_vbi_cap & cap)600 int g_sliced_vbi_cap(v4l2_sliced_vbi_cap &cap)
601 {
602 memset(cap.reserved, 0, sizeof(cap.reserved));
603 return cv4l_ioctl(VIDIOC_G_SLICED_VBI_CAP, &cap);
604 }
605
g_enc_index(v4l2_enc_idx & enc_idx)606 int g_enc_index(v4l2_enc_idx &enc_idx)
607 {
608 return cv4l_ioctl(VIDIOC_G_ENC_INDEX, &enc_idx);
609 }
610
s_hw_freq_seek(v4l2_hw_freq_seek & seek)611 int s_hw_freq_seek(v4l2_hw_freq_seek &seek)
612 {
613 memset(seek.reserved, 0, sizeof(seek.reserved));
614 return cv4l_ioctl(VIDIOC_S_HW_FREQ_SEEK, &seek);
615 }
616
log_status()617 int log_status()
618 {
619 return cv4l_ioctl(VIDIOC_LOG_STATUS, NULL);
620 }
621
encoder_cmd(v4l2_encoder_cmd & cmd)622 int encoder_cmd(v4l2_encoder_cmd &cmd)
623 {
624 memset(&cmd.raw, 0, sizeof(cmd.raw));
625 return cv4l_ioctl(VIDIOC_ENCODER_CMD, &cmd);
626 }
627
try_encoder_cmd(v4l2_encoder_cmd & cmd)628 int try_encoder_cmd(v4l2_encoder_cmd &cmd)
629 {
630 memset(&cmd.raw, 0, sizeof(cmd.raw));
631 return cv4l_ioctl(VIDIOC_TRY_ENCODER_CMD, &cmd);
632 }
633
decoder_cmd(v4l2_decoder_cmd & cmd)634 int decoder_cmd(v4l2_decoder_cmd &cmd)
635 {
636 return cv4l_ioctl(VIDIOC_DECODER_CMD, &cmd);
637 }
638
try_decoder_cmd(v4l2_decoder_cmd & cmd)639 int try_decoder_cmd(v4l2_decoder_cmd &cmd)
640 {
641 return cv4l_ioctl(VIDIOC_TRY_DECODER_CMD, &cmd);
642 }
643
644 v4l2_fract g_pixel_aspect(unsigned &width, unsigned &height, unsigned type = 0)
645 {
646 v4l2_cropcap ratio;
647 v4l2_dv_timings timings;
648 v4l2_std_id std;
649 static const v4l2_fract square = { 1, 1 };
650 static const v4l2_fract hz50 = { 11, 12 };
651 static const v4l2_fract hz60 = { 11, 10 };
652
653 ratio.type = type ? type : g_selection_type();
654 if (cv4l_ioctl(VIDIOC_CROPCAP, &ratio) == 0) {
655 width = ratio.defrect.width;
656 height = ratio.defrect.height;
657 if (ratio.pixelaspect.numerator && ratio.pixelaspect.denominator)
658 return ratio.pixelaspect;
659 }
660
661 width = 720;
662 height = 480;
663 if (!g_std(std)) {
664 if (std & V4L2_STD_525_60)
665 return hz60;
666 if (std & V4L2_STD_625_50) {
667 height = 576;
668 return hz50;
669 }
670 }
671
672 if (!g_dv_timings(timings)) {
673 width = timings.bt.width;
674 height = timings.bt.height;
675 if (width == 720 && height == 480)
676 return hz60;
677 if (width == 720 && height == 576) {
678 height = 576;
679 return hz50;
680 }
681 return square;
682 }
683 width = 0;
684 height = 0;
685 return square;
686 }
687 };
688
689 class cv4l_fmt : public v4l2_format {
690 public:
691 cv4l_fmt(unsigned _type = 0)
692 {
693 v4l_format_init(this, _type);
694 }
cv4l_fmt(const v4l2_format & _fmt)695 cv4l_fmt(const v4l2_format &_fmt)
696 {
697 memcpy(this, &_fmt, sizeof(_fmt));
698 }
699
g_type()700 __u32 g_type() { return type; }
s_type(unsigned type)701 void s_type(unsigned type) { v4l_format_init(this, type); }
g_width()702 __u32 g_width() const { return v4l_format_g_width(this); }
s_width(__u32 width)703 void s_width(__u32 width) { v4l_format_s_width(this, width); }
g_height()704 __u32 g_height() const { return v4l_format_g_height(this); }
s_height(__u32 height)705 void s_height(__u32 height) { v4l_format_s_height(this, height); }
g_frame_height()706 __u32 g_frame_height() const { return v4l_format_g_frame_height(this); }
s_frame_height(__u32 height)707 void s_frame_height(__u32 height) { v4l_format_s_frame_height(this, height); }
g_pixelformat()708 __u32 g_pixelformat() const { return v4l_format_g_pixelformat(this); }
s_pixelformat(__u32 pixelformat)709 void s_pixelformat(__u32 pixelformat) { v4l_format_s_pixelformat(this, pixelformat); }
g_colorspace()710 unsigned g_colorspace() const { return v4l_format_g_colorspace(this); }
s_colorspace(unsigned colorspace)711 void s_colorspace(unsigned colorspace) { v4l_format_s_colorspace(this, colorspace); }
g_xfer_func()712 unsigned g_xfer_func() const { return v4l_format_g_xfer_func(this); }
s_xfer_func(unsigned xfer_func)713 void s_xfer_func(unsigned xfer_func) { v4l_format_s_xfer_func(this, xfer_func); }
g_ycbcr_enc()714 unsigned g_ycbcr_enc() const { return v4l_format_g_ycbcr_enc(this); }
g_hsv_enc()715 unsigned g_hsv_enc() const { return v4l_format_g_hsv_enc(this); }
s_ycbcr_enc(unsigned ycbcr_enc)716 void s_ycbcr_enc(unsigned ycbcr_enc) { v4l_format_s_ycbcr_enc(this, ycbcr_enc); }
g_quantization()717 unsigned g_quantization() const { return v4l_format_g_quantization(this); }
s_quantization(unsigned quantization)718 void s_quantization(unsigned quantization) { v4l_format_s_quantization(this, quantization); }
g_flags()719 unsigned g_flags() const { return v4l_format_g_flags(this); }
s_flags(unsigned flags)720 void s_flags(unsigned flags) { v4l_format_s_flags(this, flags); }
g_num_planes()721 __u8 g_num_planes() const { return v4l_format_g_num_planes(this); }
s_num_planes(__u8 num_planes)722 void s_num_planes(__u8 num_planes) { v4l_format_s_num_planes(this, num_planes); }
723 __u32 g_bytesperline(unsigned plane = 0) const { return v4l_format_g_bytesperline(this, plane); }
724 void s_bytesperline(__u32 bytesperline, unsigned plane = 0) { v4l_format_s_bytesperline(this, plane, bytesperline); }
725 __u32 g_sizeimage(unsigned plane = 0) const { return v4l_format_g_sizeimage(this, plane); }
726 void s_sizeimage(__u32 sizeimage, unsigned plane = 0) { v4l_format_s_sizeimage(this, plane, sizeimage); }
g_field()727 unsigned g_field() const { return v4l_format_g_field(this); }
s_field(unsigned field)728 void s_field(unsigned field) { v4l_format_s_field(this, field); }
g_first_field(v4l2_std_id std)729 unsigned g_first_field(v4l2_std_id std) const { return v4l_format_g_first_field(this, std); }
g_flds_per_frm()730 unsigned g_flds_per_frm() const { return v4l_format_g_flds_per_frm(this); }
731 };
732
733 class cv4l_buffer;
734
735 class cv4l_queue : v4l_queue {
736 friend class cv4l_buffer;
737 public:
738 cv4l_queue(unsigned type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
739 unsigned memory = V4L2_MEMORY_MMAP)
740 {
741 v4l_queue_init(this, type, memory);
742 }
~cv4l_queue()743 ~cv4l_queue() { v4l_queue_free_bufs_info(this); }
init(unsigned type,unsigned memory)744 void init(unsigned type, unsigned memory)
745 {
746 v4l_queue_init(this, type, memory);
747 }
g_type()748 unsigned g_type() const { return v4l_queue_g_type(this); }
g_memory()749 unsigned g_memory() const { return v4l_queue_g_memory(this); }
g_buffers()750 unsigned g_buffers() const { return v4l_queue_g_buffers(this); }
g_max_num_buffers()751 unsigned g_max_num_buffers() const { return v4l_queue_g_max_num_buffers(this); }
g_num_planes()752 unsigned g_num_planes() const { return v4l_queue_g_num_planes(this); }
g_capabilities()753 unsigned g_capabilities() const { return v4l_queue_g_capabilities(this); }
g_length(unsigned plane)754 unsigned g_length(unsigned plane) const { return v4l_queue_g_length(this, plane); }
g_mem_offset(unsigned index,unsigned plane)755 unsigned g_mem_offset(unsigned index, unsigned plane) const { return v4l_queue_g_mem_offset(this, index, plane); }
g_mmapping(unsigned index,unsigned plane)756 void *g_mmapping(unsigned index, unsigned plane) const { return v4l_queue_g_mmapping(this, index, plane); }
s_mmapping(unsigned index,unsigned plane,void * m)757 void s_mmapping(unsigned index, unsigned plane, void *m) { v4l_queue_s_mmapping(this, index, plane, m); }
g_userptr(unsigned index,unsigned plane)758 void *g_userptr(unsigned index, unsigned plane) const { return v4l_queue_g_userptr(this, index, plane); }
s_userptr(unsigned index,unsigned plane,void * m)759 void s_userptr(unsigned index, unsigned plane, void *m) { v4l_queue_s_userptr(this, index, plane, m); }
g_dataptr(unsigned index,unsigned plane)760 void *g_dataptr(unsigned index, unsigned plane) const { return v4l_queue_g_dataptr(this, index, plane); }
g_fd(unsigned index,unsigned plane)761 int g_fd(unsigned index, unsigned plane) const { return v4l_queue_g_fd(this, index, plane); }
s_fd(unsigned index,unsigned plane,int fd)762 void s_fd(unsigned index, unsigned plane, int fd) { v4l_queue_s_fd(this, index, plane, fd); }
763
764 int reqbufs(cv4l_fd *fd, unsigned count = 0, unsigned int flags = 0)
765 {
766 return v4l_queue_reqbufs(fd->g_v4l_fd(), this, count, flags);
767 }
768 int remove_bufs(cv4l_fd *fd, unsigned index = 0, unsigned count = 0)
769 {
770 return v4l_queue_remove_bufs(fd->g_v4l_fd(), this, index, count);
771 }
has_create_bufs(cv4l_fd * fd)772 bool has_create_bufs(cv4l_fd *fd) const
773 {
774 return v4l_queue_has_create_bufs(fd->g_v4l_fd(), this);
775 }
776 int create_bufs(cv4l_fd *fd, unsigned count, const v4l2_format *fmt = NULL, unsigned int flags = 0)
777 {
778 return v4l_queue_create_bufs(fd->g_v4l_fd(), this, count, fmt, flags);
779 }
780 int mmap_bufs(cv4l_fd *fd, unsigned from = 0)
781 {
782 return v4l_queue_mmap_bufs(fd->g_v4l_fd(), this, from);
783 }
784 int munmap_bufs(cv4l_fd *fd, unsigned from = 0)
785 {
786 return v4l_queue_munmap_bufs(fd->g_v4l_fd(), this, from);
787 }
788 int alloc_bufs(cv4l_fd *fd, unsigned from = 0)
789 {
790 return v4l_queue_alloc_bufs(fd->g_v4l_fd(), this, from);
791 }
792 int free_bufs(unsigned from = 0)
793 {
794 return v4l_queue_free_bufs(this, from);
795 }
796 int obtain_bufs(cv4l_fd *fd, unsigned from = 0)
797 {
798 return v4l_queue_obtain_bufs(fd->g_v4l_fd(), this, from);
799 }
800 int release_bufs(cv4l_fd *fd, unsigned from = 0)
801 {
802 return v4l_queue_release_bufs(fd->g_v4l_fd(), this, from);
803 }
has_expbuf(cv4l_fd * fd)804 bool has_expbuf(cv4l_fd *fd)
805 {
806 return v4l_queue_has_expbuf(fd->g_v4l_fd());
807 }
export_bufs(cv4l_fd * fd,unsigned exp_type)808 int export_bufs(cv4l_fd *fd, unsigned exp_type)
809 {
810 return v4l_queue_export_bufs(fd->g_v4l_fd(), this, exp_type);
811 }
close_exported_fds()812 void close_exported_fds()
813 {
814 v4l_queue_close_exported_fds(this);
815 }
free(cv4l_fd * fd)816 void free(cv4l_fd *fd)
817 {
818 v4l_queue_free(fd->g_v4l_fd(), this);
819 }
buffer_init(v4l_buffer & buf,unsigned index)820 void buffer_init(v4l_buffer &buf, unsigned index) const
821 {
822 v4l_queue_buffer_init(this, &buf, index);
823 }
buffer_update(v4l_buffer & buf,unsigned index)824 void buffer_update(v4l_buffer &buf, unsigned index) const
825 {
826 v4l_queue_buffer_update(this, &buf, index);
827 }
828 int queue_all(cv4l_fd *fd);
829 };
830
831 class cv4l_buffer : public v4l_buffer {
832 public:
833 cv4l_buffer(unsigned type = 0, unsigned memory = 0, unsigned index = 0)
834 {
835 init(type, memory, index);
836 }
837 cv4l_buffer(const cv4l_queue &q, unsigned index = 0)
838 {
839 init(q, index);
840 }
cv4l_buffer(const cv4l_buffer & b)841 cv4l_buffer(const cv4l_buffer &b)
842 {
843 init(b);
844 }
845 cv4l_buffer operator= (const cv4l_buffer &b)
846 {
847 v4l_buffer *dst = this;
848 const v4l_buffer *src = &b;
849 memcpy(dst, src, sizeof(*src));
850 return *this;
851 }
~cv4l_buffer()852 virtual ~cv4l_buffer() {}
853
854 void init(unsigned type = 0, unsigned memory = 0, unsigned index = 0)
855 {
856 v4l_buffer_init(this, type, memory, index);
857 }
858 void init(const cv4l_queue &q, unsigned index = 0)
859 {
860 q.buffer_init(*this, index);
861 }
init(const cv4l_buffer & b)862 void init(const cv4l_buffer &b)
863 {
864 memcpy((v4l2_buffer *)this, (v4l2_buffer *)&b, sizeof(b));
865 if (v4l_type_is_planar(g_type()))
866 buf.m.planes = planes;
867 }
868 void update(const cv4l_queue &q, unsigned index = 0)
869 {
870 q.buffer_update(*this, index);
871 }
872
g_index()873 __u32 g_index() const { return v4l_buffer_g_index(this); }
s_index(unsigned index)874 void s_index(unsigned index) { v4l_buffer_s_index(this, index); }
g_request_fd()875 __s32 g_request_fd() const { return v4l_buffer_g_request_fd(this); }
s_request_fd(__s32 request_fd)876 void s_request_fd(__s32 request_fd) { v4l_buffer_s_request_fd(this, request_fd); }
g_type()877 unsigned g_type() const { return v4l_buffer_g_type(this); }
g_memory()878 unsigned g_memory() const { return v4l_buffer_g_memory(this); }
g_flags()879 __u32 g_flags() const { return v4l_buffer_g_flags(this); }
s_flags(__u32 flags)880 void s_flags(__u32 flags) { v4l_buffer_s_flags(this, flags); }
or_flags(__u32 flags)881 void or_flags(__u32 flags) { v4l_buffer_or_flags(this, flags); }
g_field()882 unsigned g_field() const { return v4l_buffer_g_field(this); }
s_field(unsigned field)883 void s_field(unsigned field) { v4l_buffer_s_field(this, field); }
884
g_num_planes()885 unsigned g_num_planes() const { return v4l_buffer_g_num_planes(this); }
886 __u32 g_mem_offset(unsigned plane = 0) const { return v4l_buffer_g_mem_offset(this, plane); }
887 void *g_userptr(unsigned plane = 0) const { return v4l_buffer_g_userptr(this, plane); }
888 void s_userptr(void *userptr, unsigned plane = 0) { v4l_buffer_s_userptr(this, plane, userptr); }
889 int g_fd(unsigned plane = 0) const { return v4l_buffer_g_fd(this, plane); }
890 void s_fd(int fd, unsigned plane = 0) { v4l_buffer_s_fd(this, plane, fd); }
891 __u32 g_bytesused(unsigned plane = 0) const { return v4l_buffer_g_bytesused(this, plane); }
892 void s_bytesused(__u32 bytesused, unsigned plane = 0) { v4l_buffer_s_bytesused(this, plane, bytesused); }
893 __u32 g_data_offset(unsigned plane = 0) const { return v4l_buffer_g_data_offset(this, plane); }
894 void s_data_offset(__u32 data_offset, unsigned plane = 0) { v4l_buffer_s_data_offset(this, plane, data_offset); }
895 __u32 g_length(unsigned plane = 0) const { return v4l_buffer_g_length(this, plane); }
896 void s_length(unsigned length, unsigned plane = 0) { return v4l_buffer_s_length(this, plane, length); }
897
g_sequence()898 __u32 g_sequence() const { return v4l_buffer_g_sequence(this); }
g_timestamp_type()899 __u32 g_timestamp_type() const { return v4l_buffer_g_timestamp_type(this); }
g_timestamp_src()900 __u32 g_timestamp_src() const { return v4l_buffer_g_timestamp_src(this); }
s_timestamp_src(__u32 src)901 void s_timestamp_src(__u32 src) { v4l_buffer_s_timestamp_src(this, src); }
ts_is_copy()902 bool ts_is_copy() const { return v4l_buffer_is_copy(this); }
g_timestamp()903 const timeval &g_timestamp() const { return *v4l_buffer_g_timestamp(this); }
g_timestamp_ns()904 __u64 g_timestamp_ns() const { return v4l2_timeval_to_ns(v4l_buffer_g_timestamp(this)); }
s_timestamp(const timeval & tv)905 void s_timestamp(const timeval &tv) { v4l_buffer_s_timestamp(this, &tv); }
s_timestamp_ts(const timespec & ts)906 void s_timestamp_ts(const timespec &ts) { v4l_buffer_s_timestamp_ts(this, &ts); }
s_timestamp_clock()907 void s_timestamp_clock() { v4l_buffer_s_timestamp_clock(this); }
g_timecode()908 const v4l2_timecode &g_timecode() const { return *v4l_buffer_g_timecode(this); }
s_timecode(const v4l2_timecode & tc)909 void s_timecode(const v4l2_timecode &tc) { v4l_buffer_s_timecode(this, &tc); }
910 };
911
queue_all(cv4l_fd * fd)912 inline int cv4l_queue::queue_all(cv4l_fd *fd)
913 {
914 cv4l_buffer buf;
915
916 for (unsigned i = 0; i < g_buffers(); i++) {
917 buf.init(*this, i);
918 int ret = fd->qbuf(buf);
919 if (ret)
920 return ret;
921 }
922 return 0;
923 }
924
925 #endif
926