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