From: Hans Verkuil Date: Sun, 20 Jul 2014 12:20:09 +0000 (+0200) Subject: v4l2-compliance: reworked the (c)v4l-helpers.h headers X-Git-Tag: v4l-utils-1.3.90~76 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=36799043d6e732d30143a5cd2991e514d6f9165b;p=platform%2Fupstream%2Fv4l-utils.git v4l2-compliance: reworked the (c)v4l-helpers.h headers These headers were designed to easy coding for the V4L2 API, in particular hiding the complexity relating to single and multiplanar formats. These reworked headers resolve a number of design issues and they are now ready to be used elsewhere. As an example, the C++ code below works for single and multiplanar video capture and output, vbi capture and output and sdr capture. By replacing V4L2_MEMORY_MMAP with _USERPTR it will work with userptr streaming as well. But note that the code is missing error handling, so a real application will need to do a bit more. int main(int argc, char **argv) { cv4l_fd fd; unsigned cnt = 0; fd.open(argc >= 2 ? argv[1] : "/dev/video0"); cv4l_queue q(fd.g_type(), V4L2_MEMORY_MMAP); q.reqbufs(&fd, 4); q.obtain_bufs(&fd); q.queue_all(&fd); fd.streamon(); cv4l_buffer buf(q); while (fd.dqbuf(buf) == 0) { printf("seqnr: %u bytesused[0]: %u bytesused[1]: %u\n", buf.g_sequence(), buf.g_bytesused(0), buf.g_bytesused(1)); fd.qbuf(buf); if (cnt++ >= 60) break; } q.free(&fd); fd.close(); } Signed-off-by: Hans Verkuil --- diff --git a/utils/v4l2-compliance/cv4l-helpers.h b/utils/v4l2-compliance/cv4l-helpers.h index 9fb9370..0702766 100644 --- a/utils/v4l2-compliance/cv4l-helpers.h +++ b/utils/v4l2-compliance/cv4l-helpers.h @@ -1,139 +1,512 @@ #ifndef _CV4L_HELPERS_H_ #define _CV4L_HELPERS_H_ +#include #include -class cv4l_fmt : public v4l2_format { +#define cv4l_ioctl(cmd, arg) v4l_named_ioctl(g_v4l_fd(), #cmd, cmd, arg) + +class cv4l_fd : v4l_fd { public: - cv4l_fmt() + cv4l_fd() + { + v4l_fd_init(this); + } + cv4l_fd(cv4l_fd *fd) + { + *this = *fd; + } + + __u32 g_type() const { return type; } + void s_type(__u32 type) { v4l_s_type(this, type); } + __u32 g_selection_type() const { return v4l_g_selection_type(this); } + __u32 g_caps() const { return caps; } + int g_fd() const { return fd; } + v4l_fd *g_v4l_fd() { return this; } + bool g_direct() const { return v4l_fd_g_direct(this); } + void s_direct(bool direct) { v4l_fd_s_direct(this, direct); } + bool g_trace() const { return v4l_fd_g_trace(this); } + void s_trace(bool trace) { v4l_fd_s_trace(this, trace); } + + int open(const char *devname, bool non_blocking = false) { return v4l_open(this, devname, non_blocking); } + int close() { return v4l_close(this); } + int reopen(bool non_blocking = false) { return v4l_reopen(this, non_blocking); } + ssize_t read(void *buffer, size_t n) { return v4l_read(this, buffer, n); } + ssize_t write(const void *buffer, size_t n) { return v4l_write(this, buffer, n); } + void *mmap(size_t length, off_t offset) { return v4l_mmap(this, length, offset); } + int munmap(void *start, size_t length) { return v4l_munmap(this, start, length); } + + bool has_vid_cap() const { return v4l_has_vid_cap(this); } + bool has_vid_out() const { return v4l_has_vid_out(this); } + bool has_vid_m2m() const { return v4l_has_vid_m2m(this); } + bool has_vid_mplane() const { return v4l_has_vid_mplane(this); } + bool has_overlay_cap() const { return v4l_has_overlay_cap(this); } + bool has_overlay_out() const { return v4l_has_overlay_out(this); } + bool has_raw_vbi_cap() const { return v4l_has_raw_vbi_cap(this); } + bool has_sliced_vbi_cap() const { return v4l_has_sliced_vbi_cap(this); } + bool has_vbi_cap() const { return v4l_has_vbi_cap(this); } + bool has_raw_vbi_out() const { return v4l_has_raw_vbi_out(this); } + bool has_sliced_vbi_out() const { return v4l_has_sliced_vbi_out(this); } + bool has_vbi_out() const { return v4l_has_vbi_out(this); } + bool has_vbi() const { return v4l_has_vbi(this); } + bool has_radio_rx() const { return v4l_has_radio_rx(this); } + bool has_radio_tx() const { return v4l_has_radio_tx(this); } + bool has_rds_cap() const { return v4l_has_rds_cap(this); } + bool has_rds_out() const { return v4l_has_rds_out(this); } + bool has_sdr_cap() const { return v4l_has_sdr_cap(this); } + bool has_hwseek() const { return v4l_has_hwseek(this); } + bool has_rw() const { return v4l_has_rw(this); } + bool has_streaming() const { return v4l_has_streaming(this); } + bool has_ext_pix_format() const { return v4l_has_ext_pix_format(this); } + + int queryctrl(v4l2_queryctrl &qc) + { + return cv4l_ioctl(VIDIOC_QUERYCTRL, &qc); + } + + int querymenu(v4l2_querymenu &qm) + { + return cv4l_ioctl(VIDIOC_QUERYMENU, &qm); + } + + int g_fmt(v4l2_format &fmt, unsigned type = 0) { - fd = NULL; - type = 0; - memset(&fmt, 0, sizeof(fmt)); + return v4l_g_fmt(this, &fmt, type); } - cv4l_fmt(v4l_fd *_fd, unsigned _type = 0) + + int try_fmt(v4l2_format &fmt) { - fd = _fd; - memset(&fmt, 0, sizeof(fmt)); - if (_type == 0) - type = v4l_buf_type_g_vid_cap(fd); - else - type = _type; + return v4l_try_fmt(this, &fmt); } - cv4l_fmt(v4l_fd *_fd, const v4l2_format &_fmt) + + int s_fmt(v4l2_format &fmt) { - fd = _fd; - type = _fmt.type; - fmt = _fmt.fmt; + return v4l_s_fmt(this, &fmt); } - cv4l_fmt(const cv4l_fmt &_fmt) + + int g_tuner(v4l2_tuner &tuner, unsigned index = 0) { - fd = _fmt.fd; - type = _fmt.type; - fmt = _fmt.fmt; + memset(&tuner, 0, sizeof(tuner)); + tuner.index = index; + int ret = cv4l_ioctl(VIDIOC_G_TUNER, &tuner); + if (ret == 0 && tuner.rangehigh > INT_MAX) + tuner.rangehigh = INT_MAX; + return ret; } - void init(v4l_fd *_fd, unsigned _type = 0) + + int s_tuner(v4l2_tuner &tuner) { - fd = _fd; - memset(&fmt, 0, sizeof(fmt)); - if (_type == 0) - type = v4l_buf_type_g_vid_cap(fd); - else - type = _type; + return cv4l_ioctl(VIDIOC_S_TUNER, &tuner); } - void init(v4l_fd *_fd, const v4l2_format &_fmt) + + int g_modulator(v4l2_modulator &modulator) { - fd = _fd; - type = _fmt.type; - fmt = _fmt.fmt; + memset(&modulator, 0, sizeof(modulator)); + return cv4l_ioctl(VIDIOC_G_MODULATOR, &modulator); } - int g_fmt(unsigned _type = 0) + + int s_modulator(v4l2_modulator &modulator) { - return v4l_g_fmt(fd, this, _type ? _type : type); + return cv4l_ioctl(VIDIOC_S_MODULATOR, &modulator); } - int try_fmt() + + int enum_input(v4l2_input &in, bool init = false, int index = 0) { - return v4l_try_fmt(fd, this); + if (init) { + memset(&in, 0, sizeof(in)); + in.index = index; + } else { + in.index++; + } + return cv4l_ioctl(VIDIOC_ENUMINPUT, &in); + } + + int enum_output(v4l2_output &out, bool init = false, int index = 0) + { + if (init) { + memset(&out, 0, sizeof(out)); + out.index = index; + } else { + out.index++; + } + return cv4l_ioctl(VIDIOC_ENUMOUTPUT, &out); + } + + int enum_audio(v4l2_audio &audio, bool init = false, int index = 0) + { + if (init) { + memset(&audio, 0, sizeof(audio)); + audio.index = index; + } else { + audio.index++; + } + return cv4l_ioctl(VIDIOC_ENUMAUDIO, &audio); + } + + int enum_audout(v4l2_audioout &audout, bool init = false, int index = 0) + { + if (init) { + memset(&audout, 0, sizeof(audout)); + audout.index = index; + } else { + audout.index++; + } + return cv4l_ioctl(VIDIOC_ENUMAUDOUT, &audout); + } + + bool ioctl_exists(int ret) + { + return ret == 0 || errno != ENOTTY; + } + + bool has_crop() + { + v4l2_crop crop; + v4l2_cropcap cropcap; + + crop.type = g_selection_type(); + cropcap.type = crop.type; + return ioctl_exists(cv4l_ioctl(VIDIOC_G_CROP, &crop)) && + ioctl_exists(cv4l_ioctl(VIDIOC_S_CROP, &crop)) && + ioctl_exists(cv4l_ioctl(VIDIOC_CROPCAP, &cropcap)); + } + + bool has_compose() + { + v4l2_selection sel; + + memset(&sel, 0, sizeof(sel)); + sel.type = g_selection_type(); + sel.target = V4L2_SEL_TGT_COMPOSE; + return ioctl_exists(cv4l_ioctl(VIDIOC_G_SELECTION, &sel)) && + ioctl_exists(cv4l_ioctl(VIDIOC_S_SELECTION, &sel)); + } + + bool input_has_crop() + { + v4l2_crop crop; + v4l2_cropcap cropcap; + + crop.type = g_selection_type(); + cropcap.type = crop.type; + return cv4l_ioctl(VIDIOC_G_CROP, &crop) == 0 && + cv4l_ioctl(VIDIOC_S_CROP, &crop) == 0 && + cv4l_ioctl(VIDIOC_CROPCAP, &cropcap) == 0 && + cropcap.bounds.width && cropcap.bounds.height; } - int s_fmt() + + bool input_has_compose() + { + v4l2_selection sel; + + memset(&sel, 0, sizeof(sel)); + sel.type = g_selection_type(); + sel.target = V4L2_SEL_TGT_COMPOSE; + return cv4l_ioctl(VIDIOC_G_SELECTION, &sel) == 0 && + cv4l_ioctl(VIDIOC_S_SELECTION, &sel) == 0; + } + + int subscribe_event(v4l2_event_subscription &sub) + { + return cv4l_ioctl(VIDIOC_SUBSCRIBE_EVENT, &sub); + } + + int dqevent(v4l2_event &ev) + { + return cv4l_ioctl(VIDIOC_DQEVENT, &ev); + } + + int g_input(int &input) + { + return cv4l_ioctl(VIDIOC_G_INPUT, &input); + } + + int s_input(int input) + { + return cv4l_ioctl(VIDIOC_S_INPUT, &input); + } + + int g_output(int &output) + { + return cv4l_ioctl(VIDIOC_G_OUTPUT, &output); + } + + int s_output(int output) + { + return cv4l_ioctl(VIDIOC_S_OUTPUT, &output); + } + + int g_audio(v4l2_audio &audio) + { + memset(&audio, 0, sizeof(audio)); + return cv4l_ioctl(VIDIOC_G_AUDIO, &audio); + } + + int s_audio(int input) + { + v4l2_audio audio; + + memset(&audio, 0, sizeof(audio)); + audio.index = input; + return cv4l_ioctl(VIDIOC_S_AUDIO, &audio); + } + + int g_audout(v4l2_audioout &audout) + { + memset(&audout, 0, sizeof(audout)); + return cv4l_ioctl(VIDIOC_G_AUDOUT, &audout); + } + + int s_audout(int output) + { + v4l2_audioout audout; + + memset(&audout, 0, sizeof(audout)); + audout.index = output; + return cv4l_ioctl(VIDIOC_S_AUDOUT, &audout); + } + + int g_std(v4l2_std_id &std) + { + return cv4l_ioctl(VIDIOC_G_STD, &std); + } + + int s_std(v4l2_std_id std) + { + return cv4l_ioctl(VIDIOC_S_STD, &std); + } + + int query_std(v4l2_std_id &std) + { + return cv4l_ioctl(VIDIOC_QUERYSTD, &std); + } + + int g_dv_timings(v4l2_dv_timings &timings) { - return v4l_s_fmt(fd, this); + return cv4l_ioctl(VIDIOC_G_DV_TIMINGS, &timings); } - void s_width(__u32 width) + + int s_dv_timings(v4l2_dv_timings &timings) { - v4l_format_s_width(this, width); + return cv4l_ioctl(VIDIOC_S_DV_TIMINGS, &timings); } - __u32 g_width() + + int query_dv_timings(v4l2_dv_timings &timings) { - return v4l_format_g_width(this); + return cv4l_ioctl(VIDIOC_QUERY_DV_TIMINGS, &timings); } - void s_height(__u32 height) + + int g_frequency(v4l2_frequency &freq, unsigned index = 0) { - v4l_format_s_height(this, height); + memset(&freq, 0, sizeof(freq)); + freq.tuner = index; + freq.type = V4L2_TUNER_ANALOG_TV; + return cv4l_ioctl(VIDIOC_G_FREQUENCY, &freq); } - __u32 g_height() + + int s_frequency(v4l2_frequency &freq) { - return v4l_format_g_height(this); + return cv4l_ioctl(VIDIOC_S_FREQUENCY, &freq); } - void s_pixelformat(__u32 pixelformat) + + int streamon(__u32 type = 0) { - v4l_format_s_pixelformat(this, pixelformat); + if (type == 0) + type = g_type(); + return cv4l_ioctl(VIDIOC_STREAMON, &type); } - __u32 g_pixelformat() + + int streamoff(__u32 type = 0) { - return v4l_format_g_pixelformat(this); + if (type == 0) + type = g_type(); + return cv4l_ioctl(VIDIOC_STREAMOFF, &type); } - void s_field(unsigned field) + + int querybuf(v4l_buffer &buf, unsigned index) { - v4l_format_s_field(this, field); + return v4l_buffer_querybuf(this, &buf, index); } - unsigned g_field() + + int dqbuf(v4l_buffer &buf) { - return v4l_format_g_field(this); + return v4l_buffer_dqbuf(this, &buf); } - unsigned g_first_field(v4l2_std_id std) + + int qbuf(v4l_buffer &buf) { - return v4l_format_g_first_field(this, std); + return v4l_buffer_qbuf(this, &buf); } - unsigned g_flds_per_frm() + + int prepare_buf(v4l_buffer &buf) { - return v4l_format_g_flds_per_frm(this); + return v4l_buffer_prepare_buf(this, &buf); } - void s_colorspace(unsigned colorspace) + + int enum_std(v4l2_standard &std, bool init = false, int index = 0) { - v4l_format_s_colorspace(this, colorspace); + if (init) { + memset(&std, 0, sizeof(std)); + std.index = index; + } else { + std.index++; + } + return cv4l_ioctl(VIDIOC_ENUMSTD, &std); } - unsigned g_colorspace() + + int enum_dv_timings(v4l2_enum_dv_timings &timings, bool init = false, int index = 0) { - return v4l_format_g_colorspace(this); + if (init) { + memset(&timings, 0, sizeof(timings)); + timings.index = index; + } else { + timings.index++; + } + return cv4l_ioctl(VIDIOC_ENUM_DV_TIMINGS, &timings); } - void s_num_planes(__u8 num_planes) + + int enum_fmt(v4l2_fmtdesc &fmt, bool init = false, int index = 0, unsigned type = 0) { - v4l_format_s_num_planes(this, num_planes); + if (init) { + memset(&fmt, 0, sizeof(fmt)); + fmt.index = index; + } else { + fmt.index++; + } + fmt.type = type ? type : g_type(); + return cv4l_ioctl(VIDIOC_ENUM_FMT, &fmt); } - __u8 g_num_planes() + + int enum_framesizes(v4l2_frmsizeenum &frm, __u32 init_pixfmt = 0, int index = 0) { - return v4l_format_g_num_planes(this); + if (init_pixfmt) { + memset(&frm, 0, sizeof(frm)); + frm.pixel_format = init_pixfmt; + frm.index = index; + } else { + frm.index++; + } + return cv4l_ioctl(VIDIOC_ENUM_FRAMESIZES, &frm); + } + + int enum_frameintervals(v4l2_frmivalenum &frm, __u32 init_pixfmt = 0, __u32 w = 0, __u32 h = 0, int index = 0) + { + if (init_pixfmt) { + memset(&frm, 0, sizeof(frm)); + frm.pixel_format = init_pixfmt; + frm.width = w; + frm.height = h; + frm.index = index; + } else { + frm.index++; + } + return cv4l_ioctl(VIDIOC_ENUM_FRAMEINTERVALS, &frm); } - void s_bytesperline(unsigned plane, __u32 bytesperline) + + int set_interval(v4l2_fract interval, unsigned type = 0) { - v4l_format_s_bytesperline(this, plane, bytesperline); + v4l2_streamparm parm; + + parm.type = type ? type : g_type(); + if (cv4l_ioctl(VIDIOC_G_PARM, &parm) || + !(parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) + return -1; + + parm.parm.capture.timeperframe = interval; + + return cv4l_ioctl(VIDIOC_S_PARM, &parm); } - __u32 g_bytesperline(unsigned plane) + + int get_interval(v4l2_fract &interval, unsigned type = 0) { - return v4l_format_g_bytesperline(this, plane); + v4l2_streamparm parm; + + parm.type = type ? type : g_type(); + if (cv4l_ioctl(VIDIOC_G_PARM, &parm) == 0 && + (parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) { + interval = parm.parm.capture.timeperframe; + return 0; + } + + return -1; } - void s_sizeimage(unsigned plane, __u32 sizeimage) + + v4l2_fract g_pixel_aspect(unsigned &width, unsigned &height, unsigned type = 0) + { + v4l2_cropcap ratio; + v4l2_dv_timings timings; + v4l2_std_id std; + static const v4l2_fract square = { 1, 1 }; + static const v4l2_fract hz50 = { 11, 12 }; + static const v4l2_fract hz60 = { 11, 10 }; + + ratio.type = type ? type : g_selection_type(); + if (cv4l_ioctl(VIDIOC_CROPCAP, &ratio) == 0) { + width = ratio.defrect.width; + height = ratio.defrect.height; + if (ratio.pixelaspect.numerator && ratio.pixelaspect.denominator) + return ratio.pixelaspect; + } + + width = 720; + height = 480; + if (!g_std(std)) { + if (std & V4L2_STD_525_60) + return hz60; + if (std & V4L2_STD_625_50) { + height = 576; + return hz50; + } + } + + if (!g_dv_timings(timings)) { + width = timings.bt.width; + height = timings.bt.height; + if (width == 720 && height == 480) + return hz60; + if (width == 720 && height == 576) { + height = 576; + return hz50; + } + return square; + } + width = 0; + height = 0; + return square; + } +}; + +class cv4l_fmt : public v4l2_format { +public: + cv4l_fmt(unsigned _type = 0) { - v4l_format_s_sizeimage(this, plane, sizeimage); + v4l_format_init(this, _type); } - __u32 g_sizeimage(unsigned plane) + cv4l_fmt(const v4l2_format &_fmt) { - return v4l_format_g_sizeimage(this, plane); + *this = _fmt; } -protected: - v4l_fd *fd; + __u32 g_type() { return type; } + void s_type(unsigned type) { v4l_format_init(this, type); } + __u32 g_width() { return v4l_format_g_width(this); } + void s_width(__u32 width) { v4l_format_s_width(this, width); } + __u32 g_height() { return v4l_format_g_height(this); } + void s_height(__u32 height) { v4l_format_s_height(this, height); } + __u32 g_pixelformat() { return v4l_format_g_pixelformat(this); } + void s_pixelformat(__u32 pixelformat) { v4l_format_s_pixelformat(this, pixelformat); } + unsigned g_colorspace() { return v4l_format_g_colorspace(this); } + void s_colorspace(unsigned colorspace) { v4l_format_s_colorspace(this, colorspace); } + __u8 g_num_planes() { return v4l_format_g_num_planes(this); } + void s_num_planes(__u8 num_planes) { v4l_format_s_num_planes(this, num_planes); } + __u32 g_bytesperline(unsigned plane = 0) { return v4l_format_g_bytesperline(this, plane); } + void s_bytesperline(__u32 bytesperline, unsigned plane = 0) { v4l_format_s_bytesperline(this, bytesperline, plane); } + __u32 g_sizeimage(unsigned plane = 0) { return v4l_format_g_sizeimage(this, plane); } + void s_sizeimage(__u32 sizeimage, unsigned plane = 0) { v4l_format_s_sizeimage(this, sizeimage, plane); } + unsigned g_field() { return v4l_format_g_field(this); } + void s_field(unsigned field) { v4l_format_s_field(this, field); } + unsigned g_first_field(v4l2_std_id std) { return v4l_format_g_first_field(this, std); } + unsigned g_flds_per_frm() { return v4l_format_g_flds_per_frm(this); } }; class cv4l_buffer; @@ -141,99 +514,86 @@ class cv4l_buffer; class cv4l_queue : v4l_queue { friend class cv4l_buffer; public: - cv4l_queue(v4l_fd *_fd, unsigned type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - unsigned memory = V4L2_MEMORY_MMAP) + cv4l_queue(unsigned type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + unsigned memory = V4L2_MEMORY_MMAP) { - fd = _fd; v4l_queue_init(this, type, memory); } - virtual ~cv4l_queue() - { - if (fd->fd != -1) - v4l_queue_free(fd, this); - } - void init(unsigned type, unsigned memory) { - if (fd->fd != -1) - v4l_queue_free(fd, this); v4l_queue_init(this, type, memory); } unsigned g_type() const { return v4l_queue_g_type(this); } unsigned g_memory() const { return v4l_queue_g_memory(this); } - bool is_planar() const { return v4l_queue_is_planar(this); } - bool is_output() const { return v4l_queue_is_output(this); } - bool is_capture() const { return v4l_queue_is_capture(this); } - bool is_video() const { return v4l_queue_is_video(this); } - bool is_vbi() const { return v4l_queue_is_vbi(this); } - bool is_sliced_vbi() const { return v4l_queue_is_sliced_vbi(this); } - bool is_sdr() const { return v4l_queue_is_sdr(this); } unsigned g_buffers() const { return v4l_queue_g_buffers(this); } unsigned g_num_planes() const { return v4l_queue_g_num_planes(this); } unsigned g_length(unsigned plane) const { return v4l_queue_g_length(this, plane); } unsigned g_mem_offset(unsigned index, unsigned plane) const { return v4l_queue_g_mem_offset(this, index, plane); } - void s_mmapping(unsigned index, unsigned plane, void *m) { v4l_queue_s_mmapping(this, index, plane, m); } void *g_mmapping(unsigned index, unsigned plane) const { return v4l_queue_g_mmapping(this, index, plane); } - void s_userptr(unsigned index, unsigned plane, void *m) { v4l_queue_s_userptr(this, index, plane, m); } + void s_mmapping(unsigned index, unsigned plane, void *m) { v4l_queue_s_mmapping(this, index, plane, m); } void *g_userptr(unsigned index, unsigned plane) const { return v4l_queue_g_userptr(this, index, plane); } - void s_fd(unsigned index, unsigned plane, int fd) { v4l_queue_s_fd(this, index, plane, fd); } + void s_userptr(unsigned index, unsigned plane, void *m) { v4l_queue_s_userptr(this, index, plane, m); } + void *g_dataptr(unsigned index, unsigned plane) const { return v4l_queue_g_dataptr(this, index, plane); } int g_fd(unsigned index, unsigned plane) const { return v4l_queue_g_fd(this, index, plane); } + void s_fd(unsigned index, unsigned plane, int fd) { v4l_queue_s_fd(this, index, plane, fd); } - int reqbufs(unsigned count = 0) + int reqbufs(cv4l_fd *fd, unsigned count = 0) { - return v4l_queue_reqbufs(fd, this, count); + return v4l_queue_reqbufs(fd->g_v4l_fd(), this, count); } - bool has_create_bufs() const + bool has_create_bufs(cv4l_fd *fd) const { - return v4l_queue_has_create_bufs(fd, this); + return v4l_queue_has_create_bufs(fd->g_v4l_fd(), this); } - int create_bufs(unsigned count, const v4l2_format *fmt = NULL) + int create_bufs(cv4l_fd *fd, unsigned count, const v4l2_format *fmt = NULL) { - return v4l_queue_create_bufs(fd, this, count, fmt); + return v4l_queue_create_bufs(fd->g_v4l_fd(), this, count, fmt); } - int streamon() + int mmap_bufs(cv4l_fd *fd, unsigned from = 0) { - return v4l_queue_streamon(fd, this); + return v4l_queue_mmap_bufs(fd->g_v4l_fd(), this, from); } - int streamoff() + int munmap_bufs(cv4l_fd *fd) { - return v4l_queue_streamoff(fd, this); + return v4l_queue_munmap_bufs(fd->g_v4l_fd(), this); } - int mmap_bufs(unsigned from = 0) + int alloc_bufs(cv4l_fd *fd, unsigned from = 0) { - return v4l_queue_mmap_bufs(fd, this, from); + return v4l_queue_alloc_bufs(fd->g_v4l_fd(), this, from); } - int munmap_bufs() + int free_bufs() { - return v4l_queue_munmap_bufs(fd, this); + return v4l_queue_free_bufs(this); } - int alloc_bufs(unsigned from = 0) + int obtain_bufs(cv4l_fd *fd, unsigned from = 0) { - return v4l_queue_alloc_bufs(fd, this, from); + return v4l_queue_obtain_bufs(fd->g_v4l_fd(), this, from); } - int free_bufs() + int release_bufs(cv4l_fd *fd) { - return v4l_queue_free_bufs(this); + return v4l_queue_release_bufs(fd->g_v4l_fd(), this); } - bool has_expbuf() + bool has_expbuf(cv4l_fd *fd) { - return v4l_queue_has_expbuf(fd); + return v4l_queue_has_expbuf(fd->g_v4l_fd()); } - int export_bufs() + int export_bufs(cv4l_fd *fd) { - return v4l_queue_export_bufs(fd, this); + return v4l_queue_export_bufs(fd->g_v4l_fd(), this); } void close_exported_fds() { v4l_queue_close_exported_fds(this); } - void buffer_init(struct v4l_buffer *buf, unsigned index) const + void free(cv4l_fd *fd) { - v4l_queue_buffer_init(this, buf, index); + v4l_queue_free(fd->g_v4l_fd(), this); } - -protected: - v4l_fd *fd; + void buffer_init(v4l_buffer &buf, unsigned index) const + { + v4l_queue_buffer_init(this, &buf, index); + } + int queue_all(cv4l_fd *fd); }; class cv4l_buffer : public v4l_buffer { @@ -251,20 +611,22 @@ public: init(b); } virtual ~cv4l_buffer() {} + void init(unsigned type = 0, unsigned memory = 0, unsigned index = 0) { v4l_buffer_init(this, type, memory, index); } void init(const cv4l_queue &q, unsigned index = 0) { - q.buffer_init(this, index); + q.buffer_init(*this, index); } void init(const cv4l_buffer &b) { *this = b; - if (is_planar()) + if (v4l_type_is_planar(g_type())) buf.m.planes = planes; } + __u32 g_index() const { return v4l_buffer_g_index(this); } void s_index(unsigned index) { v4l_buffer_s_index(this, index); } unsigned g_type() const { return v4l_buffer_g_type(this); } @@ -274,6 +636,20 @@ public: void or_flags(__u32 flags) { v4l_buffer_or_flags(this, flags); } unsigned g_field() const { return v4l_buffer_g_field(this); } void s_field(unsigned field) { v4l_buffer_s_field(this, field); } + + unsigned g_num_planes() const { return v4l_buffer_g_num_planes(this); } + __u32 g_mem_offset(unsigned plane = 0) const { return v4l_buffer_g_mem_offset(this, plane); } + void *g_userptr(unsigned plane = 0) const { return v4l_buffer_g_userptr(this, plane); } + void s_userptr(void *userptr, unsigned plane = 0) { v4l_buffer_s_userptr(this, plane, userptr); } + int g_fd(unsigned plane = 0) const { return v4l_buffer_g_fd(this, plane); } + void s_fd(int fd, unsigned plane = 0) { v4l_buffer_s_fd(this, plane, fd); } + __u32 g_bytesused(unsigned plane = 0) const { return v4l_buffer_g_bytesused(this, plane); } + void s_bytesused(__u32 bytesused, unsigned plane = 0) { v4l_buffer_s_bytesused(this, plane, bytesused); } + __u32 g_data_offset(unsigned plane = 0) const { return v4l_buffer_g_data_offset(this, plane); } + void s_data_offset(__u32 data_offset, unsigned plane = 0) { v4l_buffer_s_data_offset(this, plane, data_offset); } + __u32 g_length(unsigned plane = 0) const { return v4l_buffer_g_length(this, plane); } + void s_length(unsigned length, unsigned plane = 0) { return v4l_buffer_s_length(this, plane, length); } + __u32 g_sequence() const { return v4l_buffer_g_sequence(this); } __u32 g_timestamp_type() const { return v4l_buffer_g_timestamp_type(this); } __u32 g_timestamp_src() const { return v4l_buffer_g_timestamp_src(this); } @@ -285,90 +661,19 @@ public: void s_timestamp_clock() { v4l_buffer_s_timestamp_clock(this); } const v4l2_timecode &g_timecode() const { return *v4l_buffer_g_timecode(this); } void s_timecode(const v4l2_timecode &tc) { v4l_buffer_s_timecode(this, &tc); } - __u32 g_mem_offset(unsigned plane = 0) const - { - return v4l_buffer_g_mem_offset(this, plane); - } - void *g_userptr(unsigned plane = 0) const - { - return v4l_buffer_g_userptr(this, plane); - } - int g_fd(unsigned plane = 0) const - { - return v4l_buffer_g_fd(this, plane); - } - __u32 g_bytesused(unsigned plane = 0) const - { - return v4l_buffer_g_bytesused(this, plane); - } - __u32 g_length(unsigned plane = 0) const - { - return v4l_buffer_g_length(this, plane); - } - __u32 g_data_offset(unsigned plane = 0) const - { - return v4l_buffer_g_data_offset(this, plane); - } - void s_userptr(void *userptr, unsigned plane = 0) - { - v4l_buffer_s_userptr(this, plane, userptr); - } - void s_fd(int fd, unsigned plane = 0) - { - v4l_buffer_s_fd(this, plane, fd); - } - void s_bytesused(__u32 bytesused, unsigned plane = 0) - { - v4l_buffer_s_bytesused(this, plane, bytesused); - } - void s_data_offset(__u32 data_offset, unsigned plane = 0) - { - v4l_buffer_s_data_offset(this, plane, data_offset); - } - bool is_planar() const { return v4l_buffer_is_planar(this); } - bool is_output() const { return v4l_buffer_is_output(this); } - bool is_capture() const { return v4l_buffer_is_capture(this); } - bool is_video() const { return v4l_buffer_is_video(this); } - bool is_vbi() const { return v4l_buffer_is_vbi(this); } - bool is_sliced_vbi() const { return v4l_buffer_is_sliced_vbi(this); } - bool is_sdr() const { return v4l_buffer_is_sdr(this); } - unsigned g_num_planes() const - { - return v4l_buffer_g_num_planes(this); - } - - int querybuf(v4l_fd *fd, unsigned index) - { - return v4l_buffer_querybuf(fd, this, index); - } - int querybuf(const cv4l_queue &q, unsigned index) - { - return querybuf(q.fd, index); - } - int dqbuf(v4l_fd *fd) - { - return v4l_buffer_dqbuf(fd, this); - } - int dqbuf(const cv4l_queue &q) - { - return dqbuf(q.fd); - } - int qbuf(v4l_fd *fd) - { - return v4l_buffer_qbuf(fd, this); - } - int qbuf(const cv4l_queue &q) - { - return qbuf(q.fd); - } - int prepare_buf(v4l_fd *fd) - { - return v4l_buffer_prepare_buf(fd, this); - } - int prepare_buf(const cv4l_queue &q) - { - return prepare_buf(q.fd); - } }; +inline int cv4l_queue::queue_all(cv4l_fd *fd) +{ + cv4l_buffer buf; + + for (unsigned i = 0; i < g_buffers(); i++) { + buf.init(*this, i); + int ret = fd->qbuf(buf); + if (ret) + return ret; + } + return 0; +} + #endif diff --git a/utils/v4l2-compliance/v4l-helpers.h b/utils/v4l2-compliance/v4l-helpers.h index 5567528..8362144 100644 --- a/utils/v4l2-compliance/v4l-helpers.h +++ b/utils/v4l2-compliance/v4l-helpers.h @@ -2,54 +2,216 @@ #define _V4L_HELPERS_H_ #include +#include +#include +#include +#include +#include +#include #include +#include #include #include +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + struct v4l_fd { int fd; + struct v4l2_capability cap; + char devname[128]; + __u32 type; __u32 caps; bool trace; - int (*ioctl)(int fd, unsigned long cmd, ...); + bool direct; + + int (*open)(struct v4l_fd *f, const char *file, int oflag, ...); + int (*close)(struct v4l_fd *f); + int (*ioctl)(struct v4l_fd *f, unsigned long cmd, ...); + ssize_t (*read)(struct v4l_fd *f, void *buffer, size_t n); + ssize_t (*write)(struct v4l_fd *f, const void *buffer, size_t n); void *(*mmap)(void *addr, size_t length, int prot, int flags, - int fd, int64_t offset); - int (*munmap)(void *addr, size_t length); + struct v4l_fd *f, off_t offset); + int (*munmap)(struct v4l_fd *f, void *addr, size_t length); }; -static inline int v4l_named_ioctl(struct v4l_fd *f, const char *cmd_name, - unsigned long cmd, void *arg) +#ifdef __LIBV4L2_H + +static inline int v4l_wrap_open(struct v4l_fd *f, const char *file, int oflag, ...) +{ + return f->direct ? open(file, oflag) : v4l2_open(file, oflag); +} + +static inline int v4l_wrap_close(struct v4l_fd *f) +{ + return f->direct ? close(f->fd) : v4l2_close(f->fd); +} + +static inline ssize_t v4l_wrap_read(struct v4l_fd *f, void *buffer, size_t n) +{ + return f->direct ? read(f->fd, buffer, n) : v4l2_read(f->fd, buffer, n); +} + +static inline ssize_t v4l_wrap_write(struct v4l_fd *f, const void *buffer, size_t n) +{ + return f->direct ? write(f->fd, buffer, n) : v4l2_write(f->fd, buffer, n); +} + +static inline int v4l_wrap_ioctl(struct v4l_fd *f, unsigned long cmd, ...) +{ + void *arg; + va_list ap; + + va_start(ap, cmd); + arg = va_arg(ap, void *); + va_end(ap); + return f->direct ? ioctl(f->fd, cmd, arg) : v4l2_ioctl(f->fd, cmd, arg); +} + +static inline void *v4l_wrap_mmap(void *start, size_t length, int prot, int flags, + struct v4l_fd *f, off_t offset) +{ + return f->direct ? mmap(start, length, prot, flags, f->fd, offset) : + v4l2_mmap(start, length, prot, flags, f->fd, offset); +} + +static inline int v4l_wrap_munmap(struct v4l_fd *f, void *start, size_t length) +{ + return f->direct ? munmap(start, length) : v4l2_munmap(start, length); +} + +static inline bool v4l_fd_g_direct(const struct v4l_fd *f) +{ + return f->direct; +} + +static inline void v4l_fd_s_direct(struct v4l_fd *f, bool direct) +{ + f->direct = direct; +} + +#else + +static inline int v4l_wrap_open(struct v4l_fd *f, const char *file, int oflag, ...) +{ + return open(file, oflag); +} + +static inline int v4l_wrap_close(struct v4l_fd *f) +{ + return close(f->fd); +} + +static inline ssize_t v4l_wrap_read(struct v4l_fd *f, void *buffer, size_t n) +{ + return read(f->fd, buffer, n); +} + +static inline ssize_t v4l_wrap_write(struct v4l_fd *f, const void *buffer, size_t n) +{ + return write(f->fd, buffer, n); +} + +static inline int v4l_wrap_ioctl(struct v4l_fd *f, unsigned long cmd, ...) +{ + void *arg; + va_list ap; + + va_start(ap, cmd); + arg = va_arg(ap, void *); + va_end(ap); + return ioctl(f->fd, cmd, arg); +} + +static inline void *v4l_wrap_mmap(void *start, size_t length, int prot, int flags, + struct v4l_fd *f, off_t offset) +{ + return mmap(start, length, prot, flags, f->fd, offset); +} + +static inline int v4l_wrap_munmap(struct v4l_fd *f, void *start, size_t length) +{ + return munmap(start, length); +} + +static inline bool v4l_fd_g_direct(const struct v4l_fd *f) +{ + return true; +} + +static inline void v4l_fd_s_direct(struct v4l_fd *f, bool direct) +{ +} + +#endif + +static inline void v4l_fd_init(struct v4l_fd *f) +{ + memset(f, 0, sizeof(*f)); + f->fd = -1; + f->open = v4l_wrap_open; + f->close = v4l_wrap_close; + f->ioctl = v4l_wrap_ioctl; + f->read = v4l_wrap_read; + f->write = v4l_wrap_write; + f->mmap = v4l_wrap_mmap; + f->munmap = v4l_wrap_munmap; +} + +static inline bool v4l_fd_g_trace(const struct v4l_fd *f) +{ + return f->trace; +} + +static inline void v4l_fd_s_trace(struct v4l_fd *f, bool trace) +{ + f->trace = trace; +} + +static inline int v4l_named_ioctl(struct v4l_fd *f, + const char *cmd_name, unsigned long cmd, void *arg) { int retval; int e; - errno = 0; - retval = f->ioctl(f->fd, cmd, arg); - e = errno; + retval = f->ioctl(f, cmd, arg); + e = retval == 0 ? 0 : errno; if (f->trace) - fprintf(stderr, "\t\t%s returned %d (%s)\n", cmd_name, retval, strerror(e)); - return retval ? e : 0; + fprintf(stderr, "\t\t%s returned %d (%s)\n", + cmd_name, retval, strerror(e)); + return retval == -1 ? e : (retval ? -1 : 0); } #define v4l_ioctl(f, cmd, arg) v4l_named_ioctl(f, #cmd, cmd, arg) -/* - * mmap has a different prototype compared to v4l2_mmap. Because of - * this we have to make a wrapper for it. - */ -static inline void *v4l_fd_mmap(void *addr, size_t length, int prot, int flags, - int fd, int64_t offset) +static inline void *v4l_mmap(struct v4l_fd *f, size_t length, off_t offset) { - return mmap(addr, length, prot, flags, fd, offset); + return f->mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, f, offset); } -static inline void *v4l_mmap(struct v4l_fd *f, size_t length, off_t offset) +static inline int v4l_munmap(struct v4l_fd *f, void *start, size_t length) { - return f->mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, f->fd, offset); + return f->munmap(f, start, length); } -static inline int v4l_munmap(struct v4l_fd *f, void *start, size_t length) +static inline ssize_t v4l_read(struct v4l_fd *f, void *buffer, size_t n) +{ + return f->read(f, buffer, n); +} + +static inline ssize_t v4l_write(struct v4l_fd *f, const void *buffer, size_t n) { - return f->munmap(start, length) ? errno : 0; + return f->write(f, buffer, n); +} + +static inline int v4l_close(struct v4l_fd *f) +{ + int res = f->close(f); + + f->caps = f->type = 0; + f->fd = -1; + return res; } static inline int v4l_querycap(struct v4l_fd *f, struct v4l2_capability *cap) @@ -63,162 +225,145 @@ static inline __u32 v4l_capability_g_caps(const struct v4l2_capability *cap) cap->device_caps : cap->capabilities; } -static inline __u32 v4l_g_caps(struct v4l_fd *f) +static inline __u32 v4l_g_type(const struct v4l_fd *f) +{ + return f->type; +} + +static inline void v4l_s_type(struct v4l_fd *f, __u32 type) +{ + f->type = type; +} + +static inline __u32 v4l_g_selection_type(const struct v4l_fd *f) +{ + if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return V4L2_BUF_TYPE_VIDEO_OUTPUT; + return f->type; +} + +static inline __u32 v4l_g_caps(const struct v4l_fd *f) { return f->caps; } -static inline bool v4l_has_vid_cap(struct v4l_fd *f) +static inline bool v4l_has_vid_cap(const struct v4l_fd *f) { return v4l_g_caps(f) & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE); } -static inline bool v4l_has_vid_out(struct v4l_fd *f) +static inline bool v4l_has_vid_out(const struct v4l_fd *f) { return v4l_g_caps(f) & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE); } -static inline bool v4l_has_vid_m2m(struct v4l_fd *f) +static inline bool v4l_has_vid_m2m(const struct v4l_fd *f) { return v4l_g_caps(f) & (V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE); } -static inline bool v4l_has_vid_mplane(struct v4l_fd *f) +static inline bool v4l_has_vid_mplane(const struct v4l_fd *f) { return v4l_g_caps(f) & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE); } -static inline bool v4l_has_overlay_cap(struct v4l_fd *f) +static inline bool v4l_has_overlay_cap(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_VIDEO_OVERLAY; } -static inline bool v4l_has_overlay_out(struct v4l_fd *f) +static inline bool v4l_has_overlay_out(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_VIDEO_OUTPUT_OVERLAY; } -static inline bool v4l_has_raw_vbi_cap(struct v4l_fd *f) +static inline bool v4l_has_raw_vbi_cap(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_VBI_CAPTURE; } -static inline bool v4l_has_sliced_vbi_cap(struct v4l_fd *f) +static inline bool v4l_has_sliced_vbi_cap(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_SLICED_VBI_CAPTURE; } -static inline bool v4l_has_vbi_cap(struct v4l_fd *f) +static inline bool v4l_has_vbi_cap(const struct v4l_fd *f) { return v4l_has_raw_vbi_cap(f) || v4l_has_sliced_vbi_cap(f); } -static inline bool v4l_has_raw_vbi_out(struct v4l_fd *f) +static inline bool v4l_has_raw_vbi_out(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_VBI_OUTPUT; } -static inline bool v4l_has_sliced_vbi_out(struct v4l_fd *f) +static inline bool v4l_has_sliced_vbi_out(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_SLICED_VBI_OUTPUT; } -static inline bool v4l_has_vbi_out(struct v4l_fd *f) +static inline bool v4l_has_vbi_out(const struct v4l_fd *f) { return v4l_has_raw_vbi_out(f) || v4l_has_sliced_vbi_out(f); } -static inline bool v4l_has_vbi(struct v4l_fd *f) +static inline bool v4l_has_vbi(const struct v4l_fd *f) { return v4l_has_vbi_cap(f) || v4l_has_vbi_out(f); } -static inline bool v4l_has_radio_rx(struct v4l_fd *f) +static inline bool v4l_has_radio_rx(const struct v4l_fd *f) { return (v4l_g_caps(f) & V4L2_CAP_RADIO) && (v4l_g_caps(f) & V4L2_CAP_TUNER); } -static inline bool v4l_has_radio_tx(struct v4l_fd *f) +static inline bool v4l_has_radio_tx(const struct v4l_fd *f) { return (v4l_g_caps(f) & V4L2_CAP_RADIO) && (v4l_g_caps(f) & V4L2_CAP_MODULATOR); } -static inline bool v4l_has_rds_cap(struct v4l_fd *f) +static inline bool v4l_has_rds_cap(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_RDS_CAPTURE; } -static inline bool v4l_has_rds_out(struct v4l_fd *f) +static inline bool v4l_has_rds_out(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_RDS_OUTPUT; } -static inline bool v4l_has_sdr_cap(struct v4l_fd *f) +static inline bool v4l_has_sdr_cap(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_SDR_CAPTURE; } -static inline bool v4l_has_hwseek(struct v4l_fd *f) +static inline bool v4l_has_hwseek(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_HW_FREQ_SEEK; } -static inline bool v4l_has_rw(struct v4l_fd *f) +static inline bool v4l_has_rw(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_READWRITE; } -static inline bool v4l_has_streaming(struct v4l_fd *f) +static inline bool v4l_has_streaming(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_STREAMING; } -static inline void v4l_fd_init(struct v4l_fd *f, int fd) +static inline bool v4l_has_ext_pix_format(const struct v4l_fd *f) { - struct v4l2_capability cap; - - f->fd = fd; - f->ioctl = ioctl; - f->mmap = v4l_fd_mmap; - f->munmap = munmap; - f->caps = v4l_querycap(f, &cap) ? 0 : v4l_capability_g_caps(&cap); + return v4l_g_caps(f) & V4L2_CAP_EXT_PIX_FORMAT; } -#define v4l_fd_libv4l2_init(f, fd) \ - do { \ - struct v4l2_capability cap; \ - \ - (f)->fd = fd; \ - (f)->ioctl = v4l2_ioctl; \ - (f)->mmap = v4l2_mmap; \ - (f)->munmap = v4l2_munmap; \ - (f)->caps = v4l_querycap(f, &cap) ? 0 : \ - v4l_capability_g_caps(&cap); \ - } while (0) - -static inline __u32 v4l_buf_type_g_vid_cap(struct v4l_fd *f) -{ - if (v4l_g_caps(f) & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_M2M)) - return V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (v4l_g_caps(f) & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) - return V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - return 0; -} - -static inline __u32 v4l_buf_type_g_vid_out(struct v4l_fd *f) -{ - if (f->caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_M2M)) - return V4L2_BUF_TYPE_VIDEO_OUTPUT; - if (f->caps & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) - return V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - return 0; -} - -static inline __u32 v4l_g_buf_type(struct v4l_fd *f) +static inline __u32 v4l_determine_type(const struct v4l_fd *f) { if (v4l_has_vid_mplane(f)) return v4l_has_vid_cap(f) ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : @@ -240,83 +385,38 @@ static inline __u32 v4l_g_buf_type(struct v4l_fd *f) return 0; } - -static inline bool v4l_buf_type_is_planar(unsigned type) -{ - return V4L2_TYPE_IS_MULTIPLANAR(type); -} - -static inline bool v4l_buf_type_is_output(unsigned type) +static inline int v4l_open(struct v4l_fd *f, const char *devname, bool non_blocking) { - return V4L2_TYPE_IS_OUTPUT(type); -} - -static inline bool v4l_buf_type_is_capture(unsigned type) -{ - return !v4l_buf_type_is_output(type); -} + f->fd = f->open(f, devname, O_RDWR | (non_blocking ? O_NONBLOCK : 0)); -static inline bool v4l_buf_type_is_video(unsigned type) -{ - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - return true; - default: - return false; + if (f->fd < 0) + return f->fd; + if (f->devname != devname) { + strncpy(f->devname, devname, sizeof(f->devname)); + f->devname[sizeof(f->devname) - 1] = '\0'; } + if (v4l_querycap(f, &f->cap)) { + v4l_close(f); + return -1; + } + f->caps = v4l_capability_g_caps(&f->cap); + f->type = v4l_determine_type(f); + return f->fd; } -static inline bool v4l_buf_type_is_raw_vbi(unsigned type) -{ - return type == V4L2_BUF_TYPE_VBI_CAPTURE || - type == V4L2_BUF_TYPE_VBI_OUTPUT; -} - -static inline bool v4l_buf_type_is_sliced_vbi(unsigned type) -{ - return type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE || - type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT; -} - -static inline bool v4l_buf_type_is_vbi(unsigned type) -{ - return v4l_buf_type_is_raw_vbi(type) || v4l_buf_type_is_sliced_vbi(type); -} - -static inline bool v4l_buf_type_is_overlay(unsigned type) -{ - return type == V4L2_BUF_TYPE_VIDEO_OVERLAY || - type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY; -} - -static inline bool v4l_buf_type_is_sdr(unsigned type) -{ - return type == V4L2_BUF_TYPE_SDR_CAPTURE; -} - -static inline int v4l_g_fmt(struct v4l_fd *f, struct v4l2_format *fmt, unsigned type) -{ - fmt->type = type; - return v4l_ioctl(f, VIDIOC_G_FMT, fmt); -} - -static inline int v4l_try_fmt(struct v4l_fd *f, struct v4l2_format *fmt) +static inline int v4l_reopen(struct v4l_fd *f, bool non_blocking) { - return v4l_ioctl(f, VIDIOC_TRY_FMT, fmt); -} - -static inline int v4l_s_fmt(struct v4l_fd *f, struct v4l2_format *fmt) -{ - return v4l_ioctl(f, VIDIOC_S_FMT, fmt); + f->close(f); + return v4l_open(f, f->devname, non_blocking); } static inline void v4l_format_init(struct v4l2_format *fmt, unsigned type) { memset(fmt, 0, sizeof(*fmt)); fmt->type = type; + if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || + fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; } static inline void v4l_format_s_width(struct v4l2_format *fmt, __u32 width) @@ -539,17 +639,24 @@ v4l_format_g_num_planes(const struct v4l2_format *fmt) } static inline void v4l_format_s_bytesperline(struct v4l2_format *fmt, - unsigned plane, __u32 bytesperline) + __u32 bytesperline, unsigned plane) { switch (fmt->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: - fmt->fmt.pix.bytesperline = bytesperline; + if (plane == 0) + fmt->fmt.pix.bytesperline = bytesperline; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: fmt->fmt.pix_mp.plane_fmt[plane].bytesperline = bytesperline; break; + case V4L2_BUF_TYPE_VBI_CAPTURE: + case V4L2_BUF_TYPE_VBI_OUTPUT: + /* This assumes V4L2_PIX_FMT_GREY which is always the case */ + if (plane == 0) + fmt->fmt.vbi.samples_per_line = bytesperline; + break; } } @@ -559,22 +666,27 @@ v4l_format_g_bytesperline(const struct v4l2_format *fmt, unsigned plane) switch (fmt->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: - return fmt->fmt.pix.bytesperline; + return plane ? 0 : fmt->fmt.pix.bytesperline; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: return fmt->fmt.pix_mp.plane_fmt[plane].bytesperline; + case V4L2_BUF_TYPE_VBI_CAPTURE: + case V4L2_BUF_TYPE_VBI_OUTPUT: + /* This assumes V4L2_PIX_FMT_GREY which is always the case */ + return plane ? 0 : fmt->fmt.vbi.samples_per_line; default: return 0; } } static inline void v4l_format_s_sizeimage(struct v4l2_format *fmt, - unsigned plane, __u32 sizeimage) + __u32 sizeimage, unsigned plane) { switch (fmt->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: - fmt->fmt.pix.sizeimage = sizeimage; + if (plane == 0) + fmt->fmt.pix.sizeimage = sizeimage; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: @@ -589,15 +701,39 @@ v4l_format_g_sizeimage(const struct v4l2_format *fmt, unsigned plane) switch (fmt->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: - return fmt->fmt.pix.sizeimage; + return plane ? 0 : fmt->fmt.pix.sizeimage; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: return fmt->fmt.pix_mp.plane_fmt[plane].sizeimage; + case V4L2_BUF_TYPE_VBI_CAPTURE: + case V4L2_BUF_TYPE_VBI_OUTPUT: + /* This assumes V4L2_PIX_FMT_GREY which is always the case */ + return plane ? 0 : fmt->fmt.vbi.samples_per_line * + (fmt->fmt.vbi.count[0] + fmt->fmt.vbi.count[1]); + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + return plane ? 0 : fmt->fmt.sliced.io_size; default: return 0; } } +static inline int v4l_g_fmt(struct v4l_fd *f, struct v4l2_format *fmt, unsigned type) +{ + v4l_format_init(fmt, type ? type : f->type); + return v4l_ioctl(f, VIDIOC_G_FMT, fmt); +} + +static inline int v4l_try_fmt(struct v4l_fd *f, struct v4l2_format *fmt) +{ + return v4l_ioctl(f, VIDIOC_TRY_FMT, fmt); +} + +static inline int v4l_s_fmt(struct v4l_fd *f, struct v4l2_format *fmt) +{ + return v4l_ioctl(f, VIDIOC_S_FMT, fmt); +} + struct v4l_buffer { struct v4l2_plane planes[VIDEO_MAX_PLANES]; struct v4l2_buffer buf; @@ -616,44 +752,65 @@ static inline void v4l_buffer_init(struct v4l_buffer *buf, } } -static inline bool v4l_buffer_is_planar(const struct v4l_buffer *buf) +static inline bool v4l_type_is_planar(unsigned type) { - return v4l_buf_type_is_planar(buf->buf.type); + return V4L2_TYPE_IS_MULTIPLANAR(type); } -static inline bool v4l_buffer_is_output(const struct v4l_buffer *buf) +static inline bool v4l_type_is_output(unsigned type) { - return v4l_buf_type_is_output(buf->buf.type); + return V4L2_TYPE_IS_OUTPUT(type); } -static inline bool v4l_buffer_is_capture(const struct v4l_buffer *buf) +static inline bool v4l_type_is_capture(unsigned type) { - return v4l_buf_type_is_capture(buf->buf.type); + return !v4l_type_is_output(type); } -static inline bool v4l_buffer_is_video(const struct v4l_buffer *buf) +static inline bool v4l_type_is_video(unsigned type) { - return v4l_buf_type_is_video(buf->buf.type); + switch (type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + return true; + default: + return false; + } } -static inline bool v4l_buffer_is_vbi(const struct v4l_buffer *buf) +static inline bool v4l_type_is_raw_vbi(unsigned type) { - return v4l_buf_type_is_vbi(buf->buf.type); + return type == V4L2_BUF_TYPE_VBI_CAPTURE || + type == V4L2_BUF_TYPE_VBI_OUTPUT; } -static inline bool v4l_buffer_is_sliced_vbi(const struct v4l_buffer *buf) +static inline bool v4l_type_is_sliced_vbi(unsigned type) { - return v4l_buf_type_is_sliced_vbi(buf->buf.type); + return type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE || + type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT; } -static inline bool v4l_buffer_is_sdr(const struct v4l_buffer *buf) +static inline bool v4l_type_is_vbi(unsigned type) { - return v4l_buf_type_is_sdr(buf->buf.type); + return v4l_type_is_raw_vbi(type) || v4l_type_is_sliced_vbi(type); +} + +static inline bool v4l_type_is_overlay(unsigned type) +{ + return type == V4L2_BUF_TYPE_VIDEO_OVERLAY || + type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY; +} + +static inline bool v4l_type_is_sdr(unsigned type) +{ + return type == V4L2_BUF_TYPE_SDR_CAPTURE; } static inline unsigned v4l_buffer_g_num_planes(const struct v4l_buffer *buf) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) return buf->buf.length; return 1; } @@ -765,74 +922,82 @@ static inline void v4l_buffer_s_timestamp_src(struct v4l_buffer *buf, __u32 src) static inline unsigned v4l_buffer_g_length(const struct v4l_buffer *buf, unsigned plane) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) return buf->planes[plane].length; - return buf->buf.length; + return plane ? 0 : buf->buf.length; +} + +static inline void v4l_buffer_s_length(struct v4l_buffer *buf, unsigned plane, unsigned length) +{ + if (v4l_type_is_planar(buf->buf.type)) + buf->planes[plane].length = length; + else if (plane == 0) + buf->buf.length = length; } static inline unsigned v4l_buffer_g_bytesused(const struct v4l_buffer *buf, unsigned plane) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) return buf->planes[plane].bytesused; - return buf->buf.bytesused; + return plane ? 0 : buf->buf.bytesused; } static inline void v4l_buffer_s_bytesused(struct v4l_buffer *buf, unsigned plane, __u32 bytesused) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) buf->planes[plane].bytesused = bytesused; - else + else if (plane == 0) buf->buf.bytesused = bytesused; } static inline unsigned v4l_buffer_g_data_offset(const struct v4l_buffer *buf, unsigned plane) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) return buf->planes[plane].data_offset; return 0; } static inline void v4l_buffer_s_data_offset(struct v4l_buffer *buf, unsigned plane, __u32 data_offset) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) buf->planes[plane].data_offset = data_offset; } static inline __u32 v4l_buffer_g_mem_offset(const struct v4l_buffer *buf, unsigned plane) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) return buf->planes[plane].m.mem_offset; - return buf->buf.m.offset; + return plane ? 0 : buf->buf.m.offset; } static inline void v4l_buffer_s_userptr(struct v4l_buffer *buf, unsigned plane, void *userptr) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) buf->planes[plane].m.userptr = (unsigned long)userptr; - else + else if (plane == 0) buf->buf.m.userptr = (unsigned long)userptr; } static inline void *v4l_buffer_g_userptr(const struct v4l_buffer *buf, unsigned plane) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) return (void *)buf->planes[plane].m.userptr; - return (void *)buf->buf.m.userptr; + return plane ? NULL : (void *)buf->buf.m.userptr; } static inline void v4l_buffer_s_fd(struct v4l_buffer *buf, unsigned plane, int fd) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) buf->planes[plane].m.fd = fd; - else + else if (plane == 0) buf->buf.m.fd = fd; } static inline int v4l_buffer_g_fd(const struct v4l_buffer *buf, unsigned plane) { - if (v4l_buffer_is_planar(buf)) + if (v4l_type_is_planar(buf->buf.type)) return buf->planes[plane].m.fd; - return buf->buf.m.fd; + return plane ? -1 : buf->buf.m.fd; } static inline int v4l_buffer_prepare_buf(struct v4l_fd *f, struct v4l_buffer *buf) @@ -882,60 +1047,10 @@ static inline void v4l_queue_init(struct v4l_queue *q, q->fds[i][p] = -1; } -static inline unsigned v4l_queue_g_type(const struct v4l_queue *q) -{ - return q->type; -} - -static inline unsigned v4l_queue_g_memory(const struct v4l_queue *q) -{ - return q->memory; -} - -static inline bool v4l_queue_is_planar(const struct v4l_queue *q) -{ - return v4l_buf_type_is_planar(q->type); -} - -static inline bool v4l_queue_is_output(const struct v4l_queue *q) -{ - return v4l_buf_type_is_output(q->type); -} - -static inline bool v4l_queue_is_capture(const struct v4l_queue *q) -{ - return v4l_buf_type_is_capture(q->type); -} - -static inline bool v4l_queue_is_video(const struct v4l_queue *q) -{ - return v4l_buf_type_is_video(q->type); -} - -static inline bool v4l_queue_is_vbi(const struct v4l_queue *q) -{ - return v4l_buf_type_is_vbi(q->type); -} - -static inline bool v4l_queue_is_sliced_vbi(const struct v4l_queue *q) -{ - return v4l_buf_type_is_sliced_vbi(q->type); -} - -static inline bool v4l_queue_is_sdr(const struct v4l_queue *q) -{ - return v4l_buf_type_is_sdr(q->type); -} - -static inline unsigned v4l_queue_g_buffers(const struct v4l_queue *q) -{ - return q->buffers; -} - -static inline unsigned v4l_queue_g_num_planes(const struct v4l_queue *q) -{ - return q->num_planes; -} +static inline unsigned v4l_queue_g_type(const struct v4l_queue *q) { return q->type; } +static inline unsigned v4l_queue_g_memory(const struct v4l_queue *q) { return q->memory; } +static inline unsigned v4l_queue_g_buffers(const struct v4l_queue *q) { return q->buffers; } +static inline unsigned v4l_queue_g_num_planes(const struct v4l_queue *q) { return q->num_planes; } static inline __u32 v4l_queue_g_length(const struct v4l_queue *q, unsigned plane) { @@ -954,6 +1069,8 @@ static inline void v4l_queue_s_mmapping(struct v4l_queue *q, unsigned index, uns static inline void *v4l_queue_g_mmapping(const struct v4l_queue *q, unsigned index, unsigned plane) { + if (index >= v4l_queue_g_buffers(q) || plane >= v4l_queue_g_num_planes(q)) + return NULL; return q->mmappings[index][plane]; } @@ -964,6 +1081,8 @@ static inline void v4l_queue_s_userptr(struct v4l_queue *q, unsigned index, unsi static inline void *v4l_queue_g_userptr(const struct v4l_queue *q, unsigned index, unsigned plane) { + if (index >= v4l_queue_g_buffers(q) || plane >= v4l_queue_g_num_planes(q)) + return NULL; return (void *)q->userptrs[index][plane]; } @@ -977,6 +1096,13 @@ static inline int v4l_queue_g_fd(const struct v4l_queue *q, unsigned index, unsi return q->fds[index][plane]; } +static inline void *v4l_queue_g_dataptr(const struct v4l_queue *q, unsigned index, unsigned plane) +{ + if (q->memory == V4L2_MEMORY_USERPTR) + return v4l_queue_g_userptr(q, index, plane); + return v4l_queue_g_mmapping(q, index, plane); +} + static inline int v4l_queue_querybufs(struct v4l_fd *f, struct v4l_queue *q, unsigned from) { unsigned b, p; @@ -1056,16 +1182,6 @@ static inline int v4l_queue_create_bufs(struct v4l_fd *f, return v4l_queue_querybufs(f, q, q->buffers - createbufs.count); } -static inline int v4l_queue_streamon(struct v4l_fd *f, struct v4l_queue *q) -{ - return v4l_ioctl(f, VIDIOC_STREAMON, &q->type); -} - -static inline int v4l_queue_streamoff(struct v4l_fd *f, struct v4l_queue *q) -{ - return v4l_ioctl(f, VIDIOC_STREAMOFF, &q->type); -} - static inline int v4l_queue_mmap_bufs(struct v4l_fd *f, struct v4l_queue *q, unsigned from) { @@ -1146,13 +1262,28 @@ static inline int v4l_queue_free_bufs(struct v4l_queue *q) return 0; for (b = 0; b < v4l_queue_g_buffers(q); b++) { for (p = 0; p < v4l_queue_g_num_planes(q); p++) { - free(v4l_queue_g_mmapping(q, b, p)); - v4l_queue_s_mmapping(q, b, p, NULL); + free(v4l_queue_g_userptr(q, b, p)); + v4l_queue_s_userptr(q, b, p, NULL); } } return 0; } +static inline int v4l_queue_obtain_bufs(struct v4l_fd *f, + struct v4l_queue *q, unsigned from) +{ + if (q->memory == V4L2_MEMORY_USERPTR) + return v4l_queue_alloc_bufs(f, q, from); + return v4l_queue_mmap_bufs(f, q, from); +} + +static inline int v4l_queue_release_bufs(struct v4l_fd *f, struct v4l_queue *q) +{ + if (q->memory == V4L2_MEMORY_USERPTR) + return v4l_queue_free_bufs(q); + return v4l_queue_munmap_bufs(f, q); +} + static inline bool v4l_queue_has_expbuf(struct v4l_fd *f) { @@ -1205,9 +1336,8 @@ static inline void v4l_queue_close_exported_fds(struct v4l_queue *q) static inline void v4l_queue_free(struct v4l_fd *f, struct v4l_queue *q) { - v4l_queue_streamoff(f, q); - v4l_queue_free_bufs(q); - v4l_queue_munmap_bufs(f, q); + v4l_ioctl(f, VIDIOC_STREAMOFF, &q->type); + v4l_queue_release_bufs(f, q); v4l_queue_close_exported_fds(q); v4l_queue_reqbufs(f, q, 0); } @@ -1217,14 +1347,16 @@ static inline void v4l_queue_buffer_init(const struct v4l_queue *q, struct v4l_b unsigned p; v4l_buffer_init(buf, v4l_queue_g_type(q), v4l_queue_g_memory(q), index); - if (v4l_queue_is_planar(q)) { + if (v4l_type_is_planar(q->type)) { buf->buf.length = v4l_queue_g_num_planes(q); buf->buf.m.planes = buf->planes; } switch (q->memory) { case V4L2_MEMORY_USERPTR: - for (p = 0; p < v4l_queue_g_num_planes(q); p++) + for (p = 0; p < v4l_queue_g_num_planes(q); p++) { v4l_buffer_s_userptr(buf, p, v4l_queue_g_userptr(q, index, p)); + v4l_buffer_s_length(buf, p, v4l_queue_g_length(q, p)); + } break; case V4L2_MEMORY_DMABUF: for (p = 0; p < v4l_queue_g_num_planes(q); p++) @@ -1235,4 +1367,8 @@ static inline void v4l_queue_buffer_init(const struct v4l_queue *q, struct v4l_b } } +#ifdef __cplusplus +} +#endif /* __cplusplus */ + #endif diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index b8f828b..0f859a6 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -69,7 +68,6 @@ static int tests_total, tests_ok; // Globals bool show_info; bool show_warnings = true; -bool wrapper; int kernel_version; unsigned warnings; @@ -129,38 +127,6 @@ static void usage(void) exit(0); } -static void v4l_fd_test_init(struct v4l_fd *f, int fd) -{ - struct v4l2_capability cap; - - f->fd = fd; - f->ioctl = test_ioctl; - f->mmap = test_mmap; - f->munmap = test_munmap; - f->trace = options[OptTrace]; - f->caps = v4l_querycap(f, &cap) ? 0 : v4l_capability_g_caps(&cap); -} - -int doioctl_name(struct node *node, unsigned long int request, void *parm, - const char *name) -{ - int retval; - int e; - - errno = 0; - retval = test_ioctl(node->vfd.fd, request, parm); - e = errno; - if (options[OptTrace]) - printf("\t\t%s returned %d (%s)\n", name, retval, strerror(e)); - if (retval == 0) - return 0; - if (retval != -1) { - fail("%s returned %d instead of 0 or -1\n", name, retval); - return -1; - } - return e; -} - std::string cap2s(unsigned cap) { std::string s; @@ -352,7 +318,7 @@ static int testCap(struct node *node) // set by the core, so this really should always be there // for a modern driver for both caps and dcaps fail_on_test(!(caps & V4L2_CAP_EXT_PIX_FORMAT)); - fail_on_test(!(dcaps & V4L2_CAP_EXT_PIX_FORMAT)); + //fail_on_test(!(dcaps & V4L2_CAP_EXT_PIX_FORMAT)); fail_on_test(node->is_video && !(dcaps & video_caps)); fail_on_test(node->is_radio && !(dcaps & radio_caps)); // V4L2_CAP_AUDIO is invalid for radio and sdr @@ -446,7 +412,7 @@ static void streamingSetup(struct node *node) struct v4l2_frequency f = { 0 }; unsigned freq_caps; - if (node->caps & V4L2_CAP_MODULATOR) { + if (node->g_caps() & V4L2_CAP_MODULATOR) { struct v4l2_modulator m = { 0 }; doioctl(node, VIDIOC_G_MODULATOR, &m); @@ -499,16 +465,16 @@ static void streamingSetup(struct node *node) int main(int argc, char **argv) { int i; - struct node node = { -1 }; - struct node video_node = { -1 }; - struct node video_node2 = { -1 }; - struct node vbi_node = { -1 }; - struct node vbi_node2 = { -1 }; - struct node radio_node = { -1 }; - struct node radio_node2 = { -1 }; - struct node sdr_node = { -1 }; - struct node sdr_node2 = { -1 }; - struct node expbuf_node = { -1 }; + struct node node; + struct node video_node; + struct node video_node2; + struct node vbi_node; + struct node vbi_node2; + struct node radio_node; + struct node radio_node2; + struct node sdr_node; + struct node sdr_node2; + struct node expbuf_node; /* command args */ int ch; @@ -632,7 +598,7 @@ int main(int argc, char **argv) usage(); return 1; } - wrapper = options[OptUseWrapper]; + bool direct = !options[OptUseWrapper]; struct utsname uts; int v1, v2, v3; @@ -647,105 +613,99 @@ int main(int argc, char **argv) video_device = "/dev/video0"; if (video_device) { - fd = test_open(video_device, O_RDWR); + video_node.s_trace(options[OptTrace]); + video_node.s_direct(direct); + fd = video_node.open(video_device, false); if (fd < 0) { fprintf(stderr, "Failed to open %s: %s\n", video_device, strerror(errno)); exit(1); } - v4l_fd_test_init(&video_node.vfd, fd); } if (vbi_device) { - fd = test_open(vbi_device, O_RDWR); + vbi_node.s_trace(options[OptTrace]); + vbi_node.s_direct(direct); + fd = vbi_node.open(vbi_device, false); if (fd < 0) { fprintf(stderr, "Failed to open %s: %s\n", vbi_device, strerror(errno)); exit(1); } - v4l_fd_test_init(&vbi_node.vfd, fd); } if (radio_device) { - fd = test_open(radio_device, O_RDWR); + radio_node.s_trace(options[OptTrace]); + radio_node.s_direct(direct); + fd = radio_node.open(radio_device, false); if (fd < 0) { fprintf(stderr, "Failed to open %s: %s\n", radio_device, strerror(errno)); exit(1); } - v4l_fd_test_init(&radio_node.vfd, fd); } if (sdr_device) { - fd = test_open(sdr_device, O_RDWR); + sdr_node.s_trace(options[OptTrace]); + sdr_node.s_direct(direct); + fd = sdr_node.open(sdr_device, false); if (fd < 0) { fprintf(stderr, "Failed to open %s: %s\n", sdr_device, strerror(errno)); exit(1); } - v4l_fd_test_init(&sdr_node.vfd, fd); } if (expbuf_device) { - fd = open(expbuf_device, O_RDWR); + expbuf_node.s_trace(options[OptTrace]); + expbuf_node.s_direct(true); + fd = expbuf_node.open(expbuf_device, false); if (fd < 0) { fprintf(stderr, "Failed to open %s: %s\n", expbuf_device, strerror(errno)); exit(1); } - v4l_fd_init(&expbuf_node.vfd, fd); } - if (video_node.vfd.fd >= 0) { - node.vfd = video_node.vfd; + if (video_node.g_fd() >= 0) { + node = video_node; device = video_device; node.is_video = true; - } else if (vbi_node.vfd.fd >= 0) { - node.vfd = vbi_node.vfd; + } else if (vbi_node.g_fd() >= 0) { + node = vbi_node; device = vbi_device; node.is_vbi = true; - } else if (radio_node.vfd.fd >= 0) { - node.vfd = radio_node.vfd; + } else if (radio_node.g_fd() >= 0) { + node = radio_node; device = radio_device; node.is_radio = true; - } else if (sdr_node.vfd.fd >= 0) { - node.vfd = sdr_node.vfd; + } else if (sdr_node.g_fd() >= 0) { + node = sdr_node; device = sdr_device; node.is_sdr = true; } node.device = device; doioctl(&node, VIDIOC_QUERYCAP, &vcap); - if (vcap.capabilities & V4L2_CAP_DEVICE_CAPS) - node.caps = vcap.device_caps; - else - node.caps = vcap.capabilities; - if (node.caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | + if (node.g_caps() & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_SLICED_VBI_CAPTURE)) node.has_inputs = true; - if (node.caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VBI_OUTPUT | + if (node.g_caps() & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_SLICED_VBI_OUTPUT)) node.has_outputs = true; - if (node.caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | + if (node.g_caps() & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_RDS_CAPTURE | V4L2_CAP_SDR_CAPTURE)) node.can_capture = true; - if (node.caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VBI_OUTPUT | + if (node.g_caps() & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_RDS_OUTPUT)) node.can_output = true; - if (node.caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | + if (node.g_caps() & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) node.is_planar = true; - if (expbuf_device) { - doioctl(&expbuf_node, VIDIOC_QUERYCAP, &vcap); - if (vcap.capabilities & V4L2_CAP_DEVICE_CAPS) - expbuf_node.caps = vcap.device_caps; - else - expbuf_node.caps = vcap.capabilities; - } /* Information Opts */ @@ -768,7 +728,7 @@ int main(int argc, char **argv) } printf("\nCompliance test for device %s (%susing libv4l2):\n\n", - device, wrapper ? "" : "not "); + device, direct ? "not " : ""); /* Required ioctls */ @@ -782,8 +742,8 @@ int main(int argc, char **argv) if (video_device) { video_node2 = node; printf("\ttest second video open: %s\n", - ok((video_node2.vfd.fd = test_open(video_device, O_RDWR)) < 0)); - if (video_node2.vfd.fd >= 0) { + ok(video_node2.open(video_device, false) >= 0 ? 0 : errno)); + if (video_node2.g_fd() >= 0) { printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&video_node2))); printf("\ttest VIDIOC_G/S_PRIORITY: %s\n", ok(testPrio(&node, &video_node2))); @@ -793,8 +753,8 @@ int main(int argc, char **argv) if (vbi_device) { vbi_node2 = node; printf("\ttest second vbi open: %s\n", - ok((vbi_node2.vfd.fd = test_open(vbi_device, O_RDWR)) < 0)); - if (vbi_node2.vfd.fd >= 0) { + ok(vbi_node2.open(vbi_device, false) >= 0 ? 0 : errno)); + if (vbi_node2.g_fd() >= 0) { printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&vbi_node2))); printf("\ttest VIDIOC_G/S_PRIORITY: %s\n", ok(testPrio(&node, &vbi_node2))); @@ -804,8 +764,8 @@ int main(int argc, char **argv) if (radio_device) { radio_node2 = node; printf("\ttest second radio open: %s\n", - ok((radio_node2.vfd.fd = test_open(radio_device, O_RDWR)) < 0)); - if (radio_node2.vfd.fd >= 0) { + ok(radio_node2.open(radio_device, false) >= 0 ? 0 : errno)); + if (radio_node2.g_fd() >= 0) { printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&radio_node2))); printf("\ttest VIDIOC_G/S_PRIORITY: %s\n", ok(testPrio(&node, &radio_node2))); @@ -815,8 +775,8 @@ int main(int argc, char **argv) if (sdr_device) { sdr_node2 = node; printf("\ttest second sdr open: %s\n", - ok((sdr_node2.vfd.fd = test_open(sdr_device, O_RDWR)) < 0)); - if (sdr_node2.vfd.fd >= 0) { + ok(sdr_node2.open(sdr_device, false) >= 0 ? 0 : errno)); + if (sdr_node2.g_fd() >= 0) { printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&sdr_node2))); printf("\ttest VIDIOC_G/S_PRIORITY: %s\n", ok(testPrio(&node, &sdr_node2))); @@ -940,17 +900,17 @@ int main(int argc, char **argv) printf("\ttest read/write: %s\n", ok(testReadWrite(&node))); // Reopen after each streaming test to reset the streaming state // in case of any errors in the preceeding test. - reopen(&node); + node.reopen(); printf("\ttest MMAP: %s\n", ok(testMmap(&node, frame_count))); - reopen(&node); + node.reopen(); printf("\ttest USERPTR: %s\n", ok(testUserPtr(&node, frame_count))); - reopen(&node); + node.reopen(); if (options[OptSetExpBufDevice] || !(node.valid_memorytype & (1 << V4L2_MEMORY_DMABUF))) printf("\ttest DMABUF: %s\n", ok(testDmaBuf(&expbuf_node, &node, frame_count))); else if (!options[OptSetExpBufDevice]) printf("\ttest DMABUF: Cannot test, specify --expbuf-device\n"); - reopen(&node); + node.reopen(); } printf("\n"); @@ -962,11 +922,11 @@ int main(int argc, char **argv) /* Final test report */ - test_close(node.vfd.fd); + node.close(); if (node.node2) - test_close(node.node2->vfd.fd); + node.node2->close(); if (expbuf_device) - close(expbuf_node.vfd.fd); + expbuf_node.close(); printf("Total: %d, Succeeded: %d, Failed: %d, Warnings: %d\n", tests_total, tests_ok, tests_total - tests_ok, warnings); exit(app_result); diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index ade9d4b..be3f127 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -30,14 +30,6 @@ #ifndef NO_LIBV4L2 #include -#else -#define v4l2_open(file, oflag, ...) (-1) -#define v4l2_close(fd) (-1) -#define v4l2_read(fd, buffer, n) (-1) -#define v4l2_write(fd, buffer, n) (-1) -#define v4l2_ioctl(fd, request, ...) (-1) -#define v4l2_mmap(start, length, prot, flags, fd, offset) (MAP_FAILED) -#define v4l2_munmap(_start, length) (-1) #endif #include @@ -48,7 +40,6 @@ extern bool show_info; extern bool show_warnings; -extern bool wrapper; extern int kernel_version; extern unsigned warnings; @@ -59,10 +50,9 @@ struct test_queryctrl: v4l2_queryctrl { typedef std::list qctrl_list; typedef std::set<__u32> pixfmt_set; -struct node; +struct base_node; -struct node { - struct v4l_fd vfd; +struct base_node { bool is_video; bool is_radio; bool is_vbi; @@ -72,7 +62,6 @@ struct node { bool can_capture; bool can_output; const char *device; - unsigned caps; struct node *node2; /* second open filehandle */ bool has_outputs; bool has_inputs; @@ -85,14 +74,19 @@ struct node { unsigned cur_io_caps; unsigned std_controls; unsigned priv_controls; - qctrl_list controls; __u32 fbuf_caps; - pixfmt_set buftype_pixfmts[V4L2_BUF_TYPE_SDR_CAPTURE + 1]; __u32 valid_buftypes; __u32 valid_buftype; __u32 valid_memorytype; }; +struct node : public base_node, public cv4l_fd { + node() : base_node() {} + + qctrl_list controls; + pixfmt_set buftype_pixfmts[V4L2_BUF_TYPE_SDR_CAPTURE + 1]; +}; + #define info(fmt, args...) \ do { \ if (show_info) \ @@ -118,59 +112,6 @@ struct node { return fail("%s\n", #test); \ } while (0) -static inline int test_open(const char *file, int oflag) -{ - return wrapper ? v4l2_open(file, oflag) : open(file, oflag); -} - -static inline int test_close(int fd) -{ - return wrapper ? v4l2_close(fd) : close(fd); -} - -static inline void reopen(struct node *node) -{ - test_close(node->vfd.fd); - if ((node->vfd.fd = test_open(node->device, O_RDWR)) < 0) { - fprintf(stderr, "Failed to open %s: %s\n", node->device, - strerror(errno)); - exit(1); - } -} - -static inline ssize_t test_read(int fd, void *buffer, size_t n) -{ - return wrapper ? v4l2_read(fd, buffer, n) : read(fd, buffer, n); -} - -static inline ssize_t test_write(int fd, const void *buffer, size_t n) -{ - return wrapper ? v4l2_write(fd, buffer, n) : write(fd, buffer, n); -} - -static inline int test_ioctl(int fd, unsigned long cmd, ...) -{ - void *arg; - va_list ap; - - va_start(ap, cmd); - arg = va_arg(ap, void *); - va_end(ap); - return wrapper ? v4l2_ioctl(fd, cmd, arg) : ioctl(fd, cmd, arg); -} - -static inline void *test_mmap(void *start, size_t length, int prot, int flags, - int fd, int64_t offset) -{ - return wrapper ? v4l2_mmap(start, length, prot, flags, fd, offset) : - mmap(start, length, prot, flags, fd, offset); -} - -static inline int test_munmap(void *start, size_t length) -{ - return wrapper ? v4l2_munmap(start, length) : munmap(start, length); -} - static inline int check_fract(const struct v4l2_fract *f) { if (f->numerator && f->denominator) @@ -183,9 +124,7 @@ static inline double fract2f(const struct v4l2_fract *f) return (double)f->numerator / (double)f->denominator; } -int doioctl_name(struct node *node, unsigned long int request, void *parm, - const char *name); -#define doioctl(n, r, p) doioctl_name(n, r, p, #r) +#define doioctl(n, r, p) v4l_named_ioctl((n)->g_v4l_fd(), #r, r, p) std::string cap2s(unsigned cap); std::string buftype2s(int type); diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp index 1ccd66d..32923da 100644 --- a/utils/v4l2-compliance/v4l2-test-buffers.cpp +++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp @@ -106,20 +106,8 @@ static std::string field2s(unsigned val) } } -class queue : public cv4l_queue { -public: - queue(node *node, unsigned type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - unsigned memory = V4L2_MEMORY_MMAP) : - cv4l_queue(&node->vfd, type, memory) {} -}; - class buffer : public cv4l_buffer { public: - using cv4l_buffer::querybuf; - using cv4l_buffer::prepare_buf; - using cv4l_buffer::qbuf; - using cv4l_buffer::dqbuf; - buffer(unsigned type = 0, unsigned memory = 0, unsigned index = 0) : cv4l_buffer(type, memory, index) {} buffer(const cv4l_queue &q, unsigned index = 0) : @@ -128,39 +116,28 @@ public: int querybuf(node *node, unsigned index) { - return querybuf(&node->vfd, index); + return node->querybuf(*this, index); } int prepare_buf(node *node) { - return prepare_buf(&node->vfd); + return node->prepare_buf(*this); } int dqbuf(node *node) { - return dqbuf(&node->vfd); + return node->dqbuf(*this); } int qbuf(node *node, bool fill_bytesused = true) { int err; - if (is_output()) - fill_output_buf(fill_bytesused); - err = qbuf(&node->vfd); - if (err == 0 && is_output()) - buffer_info[g_timestamp()] = buf; - return err; - } - int qbuf(const queue &q, bool fill_bytesused = true) - { - int err; - - if (is_output()) + if (v4l_type_is_output(g_type())) fill_output_buf(fill_bytesused); - err = cv4l_buffer::qbuf(q); - if (err == 0 && is_output()) + err = node->qbuf(*this); + if (err == 0 && v4l_type_is_output(g_type())) buffer_info[g_timestamp()] = buf; return err; } - int check(const queue &q, enum QueryBufMode mode) + int check(const cv4l_queue &q, enum QueryBufMode mode) { int ret = check(q.g_type(), q.g_memory(), g_index(), mode, last_seq); @@ -168,7 +145,7 @@ public: ret = check_planes(q, mode); return ret; } - int check(const queue &q, enum QueryBufMode mode, __u32 index) + int check(const cv4l_queue &q, enum QueryBufMode mode, __u32 index) { int ret = check(q.g_type(), q.g_memory(), index, mode, last_seq); @@ -176,7 +153,7 @@ public: ret = check_planes(q, mode); return ret; } - int check(const queue &q, buf_seq &seq) + int check(const cv4l_queue &q, buf_seq &seq) { int ret = check(q.g_type(), q.g_memory(), g_index(), Dequeued, seq); @@ -196,7 +173,7 @@ public: private: int check(unsigned type, unsigned memory, unsigned index, enum QueryBufMode mode, struct buf_seq &seq); - int check_planes(const queue &q, enum QueryBufMode mode); + int check_planes(const cv4l_queue &q, enum QueryBufMode mode); void fill_output_buf(bool fill_bytesused = true) { timespec ts; @@ -229,7 +206,7 @@ private: } }; -int buffer::check_planes(const queue &q, enum QueryBufMode mode) +int buffer::check_planes(const cv4l_queue &q, enum QueryBufMode mode) { if (mode == Dequeued || mode == Prepared) { for (unsigned p = 0; p < g_num_planes(); p++) { @@ -261,7 +238,7 @@ int buffer::check(unsigned type, unsigned memory, unsigned index, timestamp != V4L2_BUF_FLAG_TIMESTAMP_COPY); fail_on_test(timestamp_src != V4L2_BUF_FLAG_TSTAMP_SRC_SOE && timestamp_src != V4L2_BUF_FLAG_TSTAMP_SRC_EOF); - fail_on_test(!ts_copy && is_output() && + fail_on_test(!ts_copy && v4l_type_is_output(g_type()) && timestamp_src == V4L2_BUF_FLAG_TSTAMP_SRC_SOE); if (g_flags() & V4L2_BUF_FLAG_KEYFRAME) frame_types++; @@ -282,7 +259,7 @@ int buffer::check(unsigned type, unsigned memory, unsigned index, buf_states++; fail_on_test(buf_states > 1); fail_on_test(buf.length == 0); - if (is_planar()) { + if (v4l_type_is_planar(g_type())) { fail_on_test(buf.length > VIDEO_MAX_PLANES); for (unsigned p = 0; p < buf.length; p++) { struct v4l2_plane *vp = buf.m.planes + p; @@ -292,7 +269,7 @@ int buffer::check(unsigned type, unsigned memory, unsigned index, } } - if (is_capture() && !ts_copy && + if (v4l_type_is_capture(g_type()) && !ts_copy && (g_flags() & V4L2_BUF_FLAG_TIMECODE)) warn("V4L2_BUF_FLAG_TIMECODE was used!\n"); @@ -304,7 +281,7 @@ int buffer::check(unsigned type, unsigned memory, unsigned index, } fail_on_test(!g_timestamp().tv_sec && !g_timestamp().tv_usec); fail_on_test(!(g_flags() & (V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR))); - if (is_video()) { + if (v4l_type_is_video(g_type())) { fail_on_test(g_field() == V4L2_FIELD_ALTERNATE); fail_on_test(g_field() == V4L2_FIELD_ANY); if (cur_fmt.g_field() == V4L2_FIELD_ALTERNATE) { @@ -327,12 +304,12 @@ int buffer::check(unsigned type, unsigned memory, unsigned index, seq.last_field = g_field(); } else { fail_on_test(g_sequence()); - if (mode == Queued && ts_copy && is_output()) { + if (mode == Queued && ts_copy && v4l_type_is_output(g_type())) { fail_on_test(!g_timestamp().tv_sec && !g_timestamp().tv_usec); } else { fail_on_test(g_timestamp().tv_sec || g_timestamp().tv_usec); } - if (!is_output() || mode == Unqueued) + if (!v4l_type_is_output(g_type()) || mode == Unqueued) fail_on_test(frame_types); if (mode == Unqueued) fail_on_test(g_flags() & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_PREPARED | @@ -355,7 +332,7 @@ static int testQueryBuf(struct node *node, unsigned type, unsigned count) for (i = 0; i < count; i++) { fail_on_test(buf.querybuf(node, i)); - if (buf.is_planar()) + if (v4l_type_is_planar(buf.g_type())) fail_on_test(buf.buf.m.planes != buf.planes); fail_on_test(buf.check(Unqueued, i)); } @@ -366,34 +343,35 @@ static int testQueryBuf(struct node *node, unsigned type, unsigned count) static int testSetupVbi(struct node *node, int type) { - if (!v4l_buf_type_is_vbi(type)) + if (!v4l_type_is_vbi(type)) return 0; if (!(node->cur_io_caps & V4L2_IN_CAP_STD)) return -1; - cv4l_fmt vbi_fmt(&node->vfd, type); + node->s_type(type); + cv4l_fmt vbi_fmt; - if (!vbi_fmt.g_fmt()) - vbi_fmt.s_fmt(); + if (!node->g_fmt(vbi_fmt)) + node->s_fmt(vbi_fmt); return 0; } int testReqBufs(struct node *node) { - bool can_stream = node->caps & V4L2_CAP_STREAMING; - bool can_rw = node->caps & V4L2_CAP_READWRITE; + bool can_stream = node->g_caps() & V4L2_CAP_STREAMING; + bool can_rw = node->g_caps() & V4L2_CAP_READWRITE; bool mmap_valid; bool userptr_valid; bool dmabuf_valid; int ret; unsigned i, m; - reopen(node); + node->reopen(); - queue q(node, 0, 0); + cv4l_queue q(0, 0); - ret = q.reqbufs(0); + ret = q.reqbufs(node, 0); if (ret == ENOTTY) { fail_on_test(can_stream); return ret; @@ -401,7 +379,7 @@ int testReqBufs(struct node *node) fail_on_test(ret != EINVAL); fail_on_test(node->node2 == NULL); for (i = 1; i <= V4L2_BUF_TYPE_SDR_CAPTURE; i++) { - bool is_overlay = v4l_buf_type_is_overlay(i); + bool is_overlay = v4l_type_is_overlay(i); if (!(node->valid_buftypes & (1 << i))) continue; @@ -414,19 +392,19 @@ int testReqBufs(struct node *node) node->valid_buftype = i; q.init(0, 0); - fail_on_test(q.reqbufs(i) != EINVAL); + fail_on_test(q.reqbufs(node, i) != EINVAL); q.init(i, V4L2_MEMORY_MMAP); - ret = q.reqbufs(0); + ret = q.reqbufs(node, 0); fail_on_test(ret && ret != EINVAL); mmap_valid = !ret; q.init(i, V4L2_MEMORY_USERPTR); - ret = q.reqbufs(0); + ret = q.reqbufs(node, 0); fail_on_test(ret && ret != EINVAL); userptr_valid = !ret; q.init(i, V4L2_MEMORY_DMABUF); - ret = q.reqbufs(0); + ret = q.reqbufs(node, 0); fail_on_test(ret && ret != EINVAL); dmabuf_valid = !ret; fail_on_test((can_stream && !is_overlay) && !mmap_valid && !userptr_valid && !dmabuf_valid); @@ -436,33 +414,33 @@ int testReqBufs(struct node *node) if (mmap_valid) { q.init(i, V4L2_MEMORY_MMAP); - fail_on_test(q.reqbufs(1)); + fail_on_test(q.reqbufs(node, 1)); fail_on_test(q.g_buffers() == 0); fail_on_test(q.g_memory() != V4L2_MEMORY_MMAP); fail_on_test(q.g_type() != i); - fail_on_test(q.reqbufs(1)); + fail_on_test(q.reqbufs(node, 1)); fail_on_test(testQueryBuf(node, i, q.g_buffers())); node->valid_memorytype |= 1 << V4L2_MEMORY_MMAP; } if (userptr_valid) { q.init(i, V4L2_MEMORY_USERPTR); - fail_on_test(q.reqbufs(1)); + fail_on_test(q.reqbufs(node, 1)); fail_on_test(q.g_buffers() == 0); fail_on_test(q.g_memory() != V4L2_MEMORY_USERPTR); fail_on_test(q.g_type() != i); - fail_on_test(q.reqbufs(1)); + fail_on_test(q.reqbufs(node, 1)); fail_on_test(testQueryBuf(node, i, q.g_buffers())); node->valid_memorytype |= 1 << V4L2_MEMORY_USERPTR; } if (dmabuf_valid) { q.init(i, V4L2_MEMORY_DMABUF); - fail_on_test(q.reqbufs(1)); + fail_on_test(q.reqbufs(node, 1)); fail_on_test(q.g_buffers() == 0); fail_on_test(q.g_memory() != V4L2_MEMORY_DMABUF); fail_on_test(q.g_type() != i); - fail_on_test(q.reqbufs(1)); + fail_on_test(q.reqbufs(node, 1)); fail_on_test(testQueryBuf(node, i, q.g_buffers())); node->valid_memorytype |= 1 << V4L2_MEMORY_DMABUF; } @@ -471,30 +449,30 @@ int testReqBufs(struct node *node) char buf = 0; if (node->can_capture) - ret = test_read(node->vfd.fd, &buf, 1); + ret = node->read(&buf, 1); else - ret = test_write(node->vfd.fd, &buf, 1); + ret = node->write(&buf, 1); if (ret != -1) return fail("Expected -1, got %d\n", ret); if (errno != EBUSY) return fail("Expected EBUSY, got %d\n", errno); } - fail_on_test(q.reqbufs(0)); + fail_on_test(q.reqbufs(node, 0)); for (m = V4L2_MEMORY_MMAP; m <= V4L2_MEMORY_DMABUF; m++) { if (!(node->valid_memorytype & (1 << m))) continue; - queue q2(node->node2, i, m); - fail_on_test(q.reqbufs(1)); + cv4l_queue q2(i, m); + fail_on_test(q.reqbufs(node, 1)); if (!node->is_m2m) { - fail_on_test(q2.reqbufs(1) != EBUSY); - fail_on_test(q2.reqbufs() != EBUSY); - fail_on_test(q.reqbufs()); - fail_on_test(q2.reqbufs(1)); - fail_on_test(q2.reqbufs()); + fail_on_test(q2.reqbufs(node->node2, 1) != EBUSY); + fail_on_test(q2.reqbufs(node->node2) != EBUSY); + fail_on_test(q.reqbufs(node)); + fail_on_test(q2.reqbufs(node->node2, 1)); + fail_on_test(q2.reqbufs(node->node2)); } - fail_on_test(q.reqbufs()); - ret = q.create_bufs(1); + fail_on_test(q.reqbufs(node)); + ret = q.create_bufs(node, 1); if (ret == ENOTTY) { warn("VIDIOC_CREATE_BUFS not supported\n"); break; @@ -503,12 +481,12 @@ int testReqBufs(struct node *node) fail_on_test(q.g_buffers() == 0); fail_on_test(q.g_type() != i); fail_on_test(testQueryBuf(node, i, q.g_buffers())); - fail_on_test(q.create_bufs(1)); + fail_on_test(q.create_bufs(node, 1)); fail_on_test(testQueryBuf(node, i, q.g_buffers())); if (!node->is_m2m) - fail_on_test(q2.create_bufs(1) != EBUSY); + fail_on_test(q2.create_bufs(node->node2, 1) != EBUSY); } - fail_on_test(q.reqbufs()); + fail_on_test(q.reqbufs(node)); } return 0; } @@ -519,53 +497,53 @@ int testExpBuf(struct node *node) int type; if (!(node->valid_memorytype & (1 << V4L2_MEMORY_MMAP))) { - queue q(node); + cv4l_queue q; - fail_on_test(q.has_expbuf()); + fail_on_test(q.has_expbuf(node)); return ENOTTY; } for (type = 0; type <= V4L2_BUF_TYPE_SDR_CAPTURE; type++) { if (!(node->valid_buftypes & (1 << type))) continue; - if (v4l_buf_type_is_overlay(type)) + if (v4l_type_is_overlay(type)) continue; if (testSetupVbi(node, type)) continue; - queue q(node, type, V4L2_MEMORY_MMAP); + cv4l_queue q(type, V4L2_MEMORY_MMAP); - fail_on_test(q.reqbufs(1)); - if (q.has_expbuf()) { - fail_on_test(q.export_bufs()); + fail_on_test(q.reqbufs(node, 1)); + if (q.has_expbuf(node)) { + fail_on_test(q.export_bufs(node)); have_expbuf = true; } else { - fail_on_test(!q.export_bufs()); + fail_on_test(!q.export_bufs(node)); } q.close_exported_fds(); - fail_on_test(q.reqbufs()); + fail_on_test(q.reqbufs(node)); } return have_expbuf ? 0 : ENOTTY; } int testReadWrite(struct node *node) { - bool can_rw = node->caps & V4L2_CAP_READWRITE; - int fd_flags = fcntl(node->vfd.fd, F_GETFL); + bool can_rw = node->g_caps() & V4L2_CAP_READWRITE; + int fd_flags = fcntl(node->g_fd(), F_GETFL); char buf = 0; int ret; - if (v4l_has_vbi(&node->vfd) && + if (v4l_has_vbi(node->g_v4l_fd()) && !(node->cur_io_caps & V4L2_IN_CAP_STD)) { return 0; } - fcntl(node->vfd.fd, F_SETFL, fd_flags | O_NONBLOCK); + fcntl(node->g_fd(), F_SETFL, fd_flags | O_NONBLOCK); if (node->can_capture) - ret = read(node->vfd.fd, &buf, 1); + ret = node->read(&buf, 1); else - ret = write(node->vfd.fd, &buf, 1); + ret = node->write(&buf, 1); // Note: RDS can only return multiples of 3, so we accept // both 0 and 1 as return code. // EBUSY can be returned when attempting to read/write to a @@ -577,22 +555,22 @@ int testReadWrite(struct node *node) if (!can_rw) return ENOTTY; - reopen(node); - fcntl(node->vfd.fd, F_SETFL, fd_flags | O_NONBLOCK); + node->reopen(); + fcntl(node->g_fd(), F_SETFL, fd_flags | O_NONBLOCK); /* check that the close cleared the busy flag */ if (node->can_capture) - ret = read(node->vfd.fd, &buf, 1); + ret = node->read(&buf, 1); else - ret = write(node->vfd.fd, &buf, 1); + ret = node->write(&buf, 1); fail_on_test((ret < 0 && errno != EAGAIN && errno != EBUSY) || ret > 1); return 0; } -static int captureBufs(struct node *node, const queue &q, - const queue &m2m_q, unsigned frame_count, bool use_poll) +static int captureBufs(struct node *node, const cv4l_queue &q, + const cv4l_queue &m2m_q, unsigned frame_count, bool use_poll) { - int fd_flags = fcntl(node->vfd.fd, F_GETFL); + int fd_flags = fcntl(node->g_fd(), F_GETFL); buffer buf(q); unsigned count = frame_count; int ret; @@ -604,7 +582,7 @@ static int captureBufs(struct node *node, const queue &q, } if (use_poll) - fcntl(node->vfd.fd, F_SETFL, fd_flags | O_NONBLOCK); + fcntl(node->g_fd(), F_SETFL, fd_flags | O_NONBLOCK); for (;;) { buf.init(q); @@ -613,18 +591,18 @@ static int captureBufs(struct node *node, const queue &q, fd_set fds; FD_ZERO(&fds); - FD_SET(node->vfd.fd, &fds); + FD_SET(node->g_fd(), &fds); if (node->is_m2m) - ret = select(node->vfd.fd + 1, &fds, &fds, NULL, &tv); - else if (q.is_output()) - ret = select(node->vfd.fd + 1, NULL, &fds, NULL, &tv); + ret = select(node->g_fd() + 1, &fds, &fds, NULL, &tv); + else if (v4l_type_is_output(q.g_type())) + ret = select(node->g_fd() + 1, NULL, &fds, NULL, &tv); else - ret = select(node->vfd.fd + 1, &fds, NULL, NULL, &tv); + ret = select(node->g_fd() + 1, &fds, NULL, NULL, &tv); fail_on_test(ret <= 0); - fail_on_test(!FD_ISSET(node->vfd.fd, &fds)); + fail_on_test(!FD_ISSET(node->g_fd(), &fds)); } - ret = buf.dqbuf(q); + ret = buf.dqbuf(node); if (ret != EAGAIN) { fail_on_test(ret); if (show_info) @@ -636,11 +614,11 @@ static int captureBufs(struct node *node, const queue &q, printf("\r\t%s: Frame #%03d%s", buftype2s(q.g_type()).c_str(), frame_count - count, use_poll ? " (polling)" : ""); - if (node->vfd.trace) + if (node->g_trace()) printf("\n"); fflush(stdout); } - if (buf.is_capture() && node->is_m2m && buf.ts_is_copy()) { + if (v4l_type_is_capture(buf.g_type()) && node->is_m2m && buf.ts_is_copy()) { fail_on_test(buffer_info.find(buf.g_timestamp()) == buffer_info.end()); struct v4l2_buffer &orig_buf = buffer_info[buf.g_timestamp()]; fail_on_test(buf.g_field() != orig_buf.field); @@ -650,7 +628,7 @@ static int captureBufs(struct node *node, const queue &q, fail_on_test(memcmp(&buf.g_timecode(), &orig_buf.timecode, sizeof(orig_buf.timecode))); } - fail_on_test(buf.qbuf(q)); + fail_on_test(buf.qbuf(node)); if (--count == 0) break; } @@ -658,7 +636,7 @@ static int captureBufs(struct node *node, const queue &q, continue; buf.init(m2m_q); - ret = buf.dqbuf(m2m_q); + ret = buf.dqbuf(node); if (ret == EAGAIN) continue; if (show_info) @@ -667,7 +645,7 @@ static int captureBufs(struct node *node, const queue &q, buf.g_timestamp().tv_sec, buf.g_timestamp().tv_usec); fail_on_test(ret); fail_on_test(buf.check(m2m_q, last_m2m_seq)); - if (buf.is_capture() && buf.ts_is_copy()) { + if (v4l_type_is_capture(buf.g_type()) && buf.ts_is_copy()) { fail_on_test(buffer_info.find(buf.g_timestamp()) == buffer_info.end()); struct v4l2_buffer &orig_buf = buffer_info[buf.g_timestamp()]; fail_on_test(buf.g_field() != orig_buf.field); @@ -677,10 +655,10 @@ static int captureBufs(struct node *node, const queue &q, fail_on_test(memcmp(&buf.g_timecode(), &orig_buf.timecode, sizeof(orig_buf.timecode))); } - fail_on_test(buf.qbuf(m2m_q)); + fail_on_test(buf.qbuf(node)); } if (use_poll) - fcntl(node->vfd.fd, F_SETFL, fd_flags); + fcntl(node->g_fd(), F_SETFL, fd_flags); if (!show_info) { printf("\r\t \r"); fflush(stdout); @@ -690,33 +668,33 @@ static int captureBufs(struct node *node, const queue &q, static unsigned invert_buf_type(unsigned type) { - if (v4l_buf_type_is_planar(type)) - return v4l_buf_type_is_output(type) ? + if (v4l_type_is_planar(type)) + return v4l_type_is_output(type) ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - return v4l_buf_type_is_output(type) ? + return v4l_type_is_output(type) ? V4L2_BUF_TYPE_VIDEO_CAPTURE : V4L2_BUF_TYPE_VIDEO_OUTPUT; } -static int setupM2M(struct node *node, queue &q) +static int setupM2M(struct node *node, cv4l_queue &q) { last_m2m_seq.init(); - fail_on_test(q.reqbufs(1)); + fail_on_test(q.reqbufs(node, 1)); for (unsigned i = 0; i < q.g_buffers(); i++) { buffer buf(q); - fail_on_test(buf.querybuf(q, i)); - fail_on_test(buf.qbuf(q)); + fail_on_test(buf.querybuf(node, i)); + fail_on_test(buf.qbuf(node)); } - if (q.is_video()) { - cv4l_fmt fmt(&node->vfd, q.g_type()); + if (v4l_type_is_video(q.g_type())) { + cv4l_fmt fmt(q.g_type()); - fmt.g_fmt(); + node->g_fmt(fmt); last_m2m_seq.last_field = fmt.g_field(); } - fail_on_test(q.streamon()); + fail_on_test(node->streamon(q.g_type())); return 0; } @@ -735,7 +713,7 @@ static int bufferOutputErrorTest(struct node *node, const buffer &orig_buf) have_prepare = ret != ENOTTY; fail_on_test(buf.qbuf(node, false) != EINVAL); - if (buf.is_planar()) { + if (v4l_type_is_planar(buf.g_type())) { for (unsigned p = 0; p < buf.g_num_planes(); p++) { buf.s_bytesused(buf.g_length(p) / 2, p); buf.s_data_offset(buf.g_bytesused(p), p); @@ -766,56 +744,56 @@ static int bufferOutputErrorTest(struct node *node, const buffer &orig_buf) return 0; } -static int setupMmap(struct node *node, queue &q) +static int setupMmap(struct node *node, cv4l_queue &q) { for (unsigned i = 0; i < q.g_buffers(); i++) { buffer buf(q); int ret; - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Unqueued, i)); for (unsigned p = 0; p < buf.g_num_planes(); p++) { // Try a random offset - fail_on_test(test_mmap(NULL, buf.g_length(p), PROT_READ | PROT_WRITE, - MAP_SHARED, node->vfd.fd, buf.g_mem_offset(p) + 0xdeadbeef) != MAP_FAILED); + fail_on_test(node->mmap(buf.g_length(p), + buf.g_mem_offset(p) + 0xdeadbeef) != MAP_FAILED); } - fail_on_test(!buf.dqbuf(q)); - if (buf.is_output() && i == 0) { + fail_on_test(!buf.dqbuf(node)); + if (v4l_type_is_output(buf.g_type()) && i == 0) { fail_on_test(bufferOutputErrorTest(node, buf)); - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Queued, i)); } else { - ret = buf.prepare_buf(q); + ret = buf.prepare_buf(node); fail_on_test(ret && ret != ENOTTY); if (ret == 0) { - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Prepared, i)); - fail_on_test(!buf.prepare_buf(q)); + fail_on_test(!buf.prepare_buf(node)); } - fail_on_test(buf.qbuf(q)); - fail_on_test(!buf.qbuf(q)); - fail_on_test(!buf.prepare_buf(q)); + fail_on_test(buf.qbuf(node)); + fail_on_test(!buf.qbuf(node)); + fail_on_test(!buf.prepare_buf(node)); // Test with invalid buffer index buf.s_index(buf.g_index() + VIDEO_MAX_FRAME); - fail_on_test(!buf.prepare_buf(q)); - fail_on_test(!buf.qbuf(q)); - fail_on_test(!buf.querybuf(q, buf.g_index())); + fail_on_test(!buf.prepare_buf(node)); + fail_on_test(!buf.qbuf(node)); + fail_on_test(!buf.querybuf(node, buf.g_index())); buf.s_index(buf.g_index() - VIDEO_MAX_FRAME); fail_on_test(buf.g_index() != i); } - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Queued, i)); - fail_on_test(!buf.dqbuf(q)); + fail_on_test(!buf.dqbuf(node)); } - fail_on_test(q.mmap_bufs()); + fail_on_test(q.mmap_bufs(node)); return 0; } int testMmap(struct node *node, unsigned frame_count) { - bool can_stream = node->caps & V4L2_CAP_STREAMING; + bool can_stream = node->g_caps() & V4L2_CAP_STREAMING; bool have_createbufs = true; int type; int ret; @@ -827,55 +805,55 @@ int testMmap(struct node *node, unsigned frame_count) for (type = 0; type <= V4L2_BUF_TYPE_SDR_CAPTURE; type++) { if (!(node->valid_buftypes & (1 << type))) continue; - if (v4l_buf_type_is_overlay(type)) + if (v4l_type_is_overlay(type)) continue; - queue q(node, type, V4L2_MEMORY_MMAP); - queue m2m_q(node, invert_buf_type(type)); + cv4l_queue q(type, V4L2_MEMORY_MMAP); + cv4l_queue m2m_q(invert_buf_type(type)); if (testSetupVbi(node, type)) continue; - ret = q.reqbufs(0); + ret = q.reqbufs(node, 0); if (ret) { fail_on_test(can_stream); return ret; } fail_on_test(!can_stream); - fail_on_test(q.streamon() != EINVAL); - fail_on_test(q.streamoff()); + fail_on_test(node->streamon(q.g_type()) != EINVAL); + fail_on_test(node->streamoff(q.g_type())); q.init(type, V4L2_MEMORY_MMAP); - fail_on_test(q.reqbufs(1)); - fail_on_test(q.streamoff()); + fail_on_test(q.reqbufs(node, 1)); + fail_on_test(node->streamoff(q.g_type())); last_seq.init(); // Test queuing buffers... for (unsigned i = 0; i < q.g_buffers(); i++) { buffer buf(q); - fail_on_test(buf.querybuf(q, i)); - fail_on_test(buf.qbuf(q)); + fail_on_test(buf.querybuf(node, i)); + fail_on_test(buf.qbuf(node)); } // calling STREAMOFF... - fail_on_test(q.streamoff()); + fail_on_test(node->streamoff(q.g_type())); // and now we should be able to queue those buffers again since // STREAMOFF should return them back to the dequeued state. for (unsigned i = 0; i < q.g_buffers(); i++) { buffer buf(q); - fail_on_test(buf.querybuf(q, i)); - fail_on_test(buf.qbuf(q)); + fail_on_test(buf.querybuf(node, i)); + fail_on_test(buf.qbuf(node)); } // Now request buffers again, freeing the old buffers. // Good check for whether all the internal vb2 calls are in // balance. - fail_on_test(q.reqbufs(q.g_buffers())); - cur_fmt.init(&node->vfd, q.g_type()); - cur_fmt.g_fmt(); + fail_on_test(q.reqbufs(node, q.g_buffers())); + cur_fmt.s_type(q.g_type()); + node->g_fmt(cur_fmt); - ret = q.create_bufs(0); + ret = q.create_bufs(node, 0); fail_on_test(ret != ENOTTY && ret != 0); if (ret == ENOTTY) have_createbufs = false; @@ -886,47 +864,48 @@ int testMmap(struct node *node, unsigned frame_count) last_seq.last_field = cur_fmt.g_field(); fmt.s_height(fmt.g_height() / 2); for (unsigned p = 0; p < fmt.g_num_planes(); p++) - fmt.s_sizeimage(p, fmt.g_sizeimage(p) / 2); - ret = q.create_bufs(1, &fmt); + fmt.s_sizeimage(fmt.g_sizeimage(p) / 2, p); + ret = q.create_bufs(node, 1, &fmt); fail_on_test(ret != EINVAL); fail_on_test(testQueryBuf(node, cur_fmt.type, q.g_buffers())); fmt = cur_fmt; for (unsigned p = 0; p < fmt.g_num_planes(); p++) - fmt.s_sizeimage(p, fmt.g_sizeimage(p) * 2); + fmt.s_sizeimage(fmt.g_sizeimage(p) * 2, p); } - fail_on_test(q.create_bufs(1, &fmt)); + fail_on_test(q.create_bufs(node, 1, &fmt)); } fail_on_test(setupMmap(node, q)); - fail_on_test(q.streamon()); - fail_on_test(q.streamon()); + fail_on_test(node->streamon(q.g_type())); + fail_on_test(node->streamon(q.g_type())); if (node->is_m2m) fail_on_test(setupM2M(node, m2m_q)); else fail_on_test(captureBufs(node, q, m2m_q, frame_count, false)); fail_on_test(captureBufs(node, q, m2m_q, frame_count, true)); - fail_on_test(q.streamoff()); - fail_on_test(q.streamoff()); + fail_on_test(node->streamoff(q.g_type())); + fail_on_test(node->streamoff(q.g_type())); + q.munmap_bufs(node); + fail_on_test(q.reqbufs(node, 0)); } return 0; } -static int setupUserPtr(struct node *node, queue &q) +static int setupUserPtr(struct node *node, cv4l_queue &q) { - fail_on_test(q.alloc_bufs()); + fail_on_test(q.alloc_bufs(node)); for (unsigned i = 0; i < q.g_buffers(); i++) { buffer buf(q); int ret; - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Unqueued, i)); for (unsigned p = 0; p < buf.g_num_planes(); p++) { // This should not work! - fail_on_test(test_mmap(NULL, buf.g_length(p), PROT_READ | PROT_WRITE, - MAP_SHARED, node->vfd.fd, 0) != MAP_FAILED); + fail_on_test(node->mmap(buf.g_length(p), 0) != MAP_FAILED); } ret = ENOTTY; @@ -934,39 +913,39 @@ static int setupUserPtr(struct node *node, queue &q) if ((i & 1) == 0) { for (unsigned p = 0; p < buf.g_num_planes(); p++) buf.s_userptr(0UL, p); - ret = buf.prepare_buf(q); + ret = buf.prepare_buf(node); fail_on_test(!ret); for (unsigned p = 0; p < buf.g_num_planes(); p++) buf.s_userptr((char *)q.g_userptr(i, p) + 0xdeadbeef, p); - ret = buf.prepare_buf(q); + ret = buf.prepare_buf(node); fail_on_test(!ret); for (unsigned p = 0; p < buf.g_num_planes(); p++) buf.s_userptr(q.g_userptr(i, p), p); - ret = buf.prepare_buf(q); + ret = buf.prepare_buf(node); fail_on_test(ret && ret != ENOTTY); if (ret == 0) { - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Prepared, i)); } } if (ret == ENOTTY) { for (unsigned p = 0; p < buf.g_num_planes(); p++) buf.s_userptr(0UL, p); - ret = buf.qbuf(q); + ret = buf.qbuf(node); fail_on_test(!ret); for (unsigned p = 0; p < buf.g_num_planes(); p++) buf.s_userptr((char *)q.g_userptr(i, p) + 0xdeadbeef, p); - ret = buf.qbuf(q); + ret = buf.qbuf(node); fail_on_test(!ret); for (unsigned p = 0; p < buf.g_num_planes(); p++) buf.s_userptr(q.g_userptr(i, p), p); } - fail_on_test(buf.qbuf(q)); - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.qbuf(node)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Queued, i)); } return 0; @@ -974,7 +953,7 @@ static int setupUserPtr(struct node *node, queue &q) int testUserPtr(struct node *node, unsigned frame_count) { - bool can_stream = node->caps & V4L2_CAP_STREAMING; + bool can_stream = node->g_caps() & V4L2_CAP_STREAMING; int type; int ret; @@ -985,16 +964,16 @@ int testUserPtr(struct node *node, unsigned frame_count) for (type = 0; type <= V4L2_BUF_TYPE_SDR_CAPTURE; type++) { if (!(node->valid_buftypes & (1 << type))) continue; - if (v4l_buf_type_is_overlay(type)) + if (v4l_type_is_overlay(type)) continue; - queue q(node, type, V4L2_MEMORY_USERPTR); - queue m2m_q(node, invert_buf_type(type)); + cv4l_queue q(type, V4L2_MEMORY_USERPTR); + cv4l_queue m2m_q(invert_buf_type(type)); if (testSetupVbi(node, type)) continue; - ret = q.reqbufs(0); + ret = q.reqbufs(node, 0); if (ret) { fail_on_test(ret != EINVAL); return ENOTTY; @@ -1002,76 +981,75 @@ int testUserPtr(struct node *node, unsigned frame_count) fail_on_test(!can_stream); q.init(type, V4L2_MEMORY_USERPTR); - fail_on_test(q.reqbufs(1)); - fail_on_test(q.streamoff()); + fail_on_test(q.reqbufs(node, 1)); + fail_on_test(node->streamoff(q.g_type())); last_seq.init(); if (node->is_video) last_seq.last_field = cur_fmt.g_field(); fail_on_test(setupUserPtr(node, q)); - fail_on_test(q.streamon()); - fail_on_test(q.streamon()); + fail_on_test(node->streamon(q.g_type())); + fail_on_test(node->streamon(q.g_type())); if (node->is_m2m) fail_on_test(setupM2M(node, m2m_q)); else fail_on_test(captureBufs(node, q, m2m_q, frame_count, false)); fail_on_test(captureBufs(node, q, m2m_q, frame_count, true)); - fail_on_test(q.streamoff()); - fail_on_test(q.streamoff()); + fail_on_test(node->streamoff(q.g_type())); + fail_on_test(node->streamoff(q.g_type())); } return 0; } static int setupDmaBuf(struct node *expbuf_node, struct node *node, - queue &q, queue &exp_q) + cv4l_queue &q, cv4l_queue &exp_q) { - fail_on_test(exp_q.reqbufs(q.g_buffers())); + fail_on_test(exp_q.reqbufs(expbuf_node, q.g_buffers())); fail_on_test(exp_q.g_buffers() < q.g_buffers()); - fail_on_test(exp_q.export_bufs()); + fail_on_test(exp_q.export_bufs(expbuf_node)); for (unsigned i = 0; i < q.g_buffers(); i++) { buffer buf(q); int ret; - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Unqueued, i)); fail_on_test(exp_q.g_num_planes() < buf.g_num_planes()); for (unsigned p = 0; p < buf.g_num_planes(); p++) { fail_on_test(exp_q.g_length(p) < buf.g_length(p)); // This should not work! - fail_on_test(test_mmap(NULL, buf.g_length(p), PROT_READ | PROT_WRITE, - MAP_SHARED, node->vfd.fd, 0) != MAP_FAILED); + fail_on_test(node->mmap(buf.g_length(p), 0) != MAP_FAILED); q.s_fd(i, p, exp_q.g_fd(i, p)); } for (unsigned p = 0; p < buf.g_num_planes(); p++) buf.s_fd(0xdeadbeef + q.g_fd(i, p), p); - ret = buf.prepare_buf(q); + ret = buf.prepare_buf(node); fail_on_test(!ret); if (ret != ENOTTY) { buf.init(q, i); - ret = buf.prepare_buf(q); + ret = buf.prepare_buf(node); fail_on_test(ret); - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Prepared, i)); } else { - fail_on_test(!buf.qbuf(q)); + fail_on_test(!buf.qbuf(node)); buf.init(q, i); } - fail_on_test(buf.qbuf(q)); - fail_on_test(buf.querybuf(q, i)); + fail_on_test(buf.qbuf(node)); + fail_on_test(buf.querybuf(node, i)); fail_on_test(buf.check(q, Queued, i)); } - fail_on_test(q.mmap_bufs()); + fail_on_test(q.mmap_bufs(node)); return 0; } int testDmaBuf(struct node *expbuf_node, struct node *node, unsigned frame_count) { - bool can_stream = node->caps & V4L2_CAP_STREAMING; + bool can_stream = node->g_caps() & V4L2_CAP_STREAMING; int expbuf_type, type; int ret; @@ -1082,52 +1060,52 @@ int testDmaBuf(struct node *expbuf_node, struct node *node, unsigned frame_count for (type = 0; type <= V4L2_BUF_TYPE_SDR_CAPTURE; type++) { if (!(node->valid_buftypes & (1 << type))) continue; - if (v4l_buf_type_is_sdr(type)) + if (v4l_type_is_sdr(type)) continue; - if (v4l_buf_type_is_overlay(type)) + if (v4l_type_is_overlay(type)) continue; - if (expbuf_node->caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) + if (expbuf_node->g_caps() & V4L2_CAP_VIDEO_CAPTURE_MPLANE) expbuf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - else if (expbuf_node->caps & V4L2_CAP_VIDEO_CAPTURE) + else if (expbuf_node->g_caps() & V4L2_CAP_VIDEO_CAPTURE) expbuf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - else if (expbuf_node->caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) + else if (expbuf_node->g_caps() & V4L2_CAP_VIDEO_OUTPUT_MPLANE) expbuf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; else expbuf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - queue q(node, type, V4L2_MEMORY_DMABUF); - queue m2m_q(node, invert_buf_type(type)); - queue exp_q(expbuf_node, expbuf_type, V4L2_MEMORY_MMAP); + cv4l_queue q(type, V4L2_MEMORY_DMABUF); + cv4l_queue m2m_q(invert_buf_type(type)); + cv4l_queue exp_q(expbuf_type, V4L2_MEMORY_MMAP); if (testSetupVbi(node, type)) continue; - ret = q.reqbufs(0); + ret = q.reqbufs(node, 0); if (ret) { fail_on_test(ret != EINVAL); return ENOTTY; } fail_on_test(!can_stream); - fail_on_test(q.reqbufs(1)); - fail_on_test(q.streamoff()); + fail_on_test(q.reqbufs(node, 1)); + fail_on_test(node->streamoff(q.g_type())); last_seq.init(); if (node->is_video) last_seq.last_field = cur_fmt.g_field(); fail_on_test(setupDmaBuf(expbuf_node, node, q, exp_q)); - fail_on_test(q.streamon()); - fail_on_test(q.streamon()); + fail_on_test(node->streamon(q.g_type())); + fail_on_test(node->streamon(q.g_type())); if (node->is_m2m) fail_on_test(setupM2M(node, m2m_q)); else fail_on_test(captureBufs(node, q, m2m_q, frame_count, false)); fail_on_test(captureBufs(node, q, m2m_q, frame_count, true)); - fail_on_test(q.streamoff()); - fail_on_test(q.streamoff()); + fail_on_test(node->streamoff(q.g_type())); + fail_on_test(node->streamoff(q.g_type())); } return 0; } diff --git a/utils/v4l2-compliance/v4l2-test-controls.cpp b/utils/v4l2-compliance/v4l2-test-controls.cpp index 70bf97e..c45181a 100644 --- a/utils/v4l2-compliance/v4l2-test-controls.cpp +++ b/utils/v4l2-compliance/v4l2-test-controls.cpp @@ -721,8 +721,8 @@ int testControlEvents(struct node *node) return fail("subscribe event for control '%s' failed\n", iter->name); //if (iter->type == V4L2_CTRL_TYPE_CTRL_CLASS) FD_ZERO(&set); - FD_SET(node->vfd.fd, &set); - ret = select(node->vfd.fd + 1, NULL, NULL, &set, &timeout); + FD_SET(node->g_fd(), &set); + ret = select(node->g_fd() + 1, NULL, NULL, &set, &timeout); if (ret == 0) { if (iter->type != V4L2_CTRL_TYPE_CTRL_CLASS) return fail("failed to find event for control '%s'\n", iter->name); diff --git a/utils/v4l2-compliance/v4l2-test-formats.cpp b/utils/v4l2-compliance/v4l2-test-formats.cpp index dc7f665..6746c0d 100644 --- a/utils/v4l2-compliance/v4l2-test-formats.cpp +++ b/utils/v4l2-compliance/v4l2-test-formats.cpp @@ -165,7 +165,7 @@ static int testEnumFrameSizes(struct node *node, __u32 pixfmt) frmsize.discrete.width + 1, frmsize.discrete.height, 0); if (ret && ret != ENOTTY) return ret; - if (ret == 0 && !(node->caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE))) + if (ret == 0 && !(node->g_caps() & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE))) return fail("found discrete framesizes when no video capture is supported\n"); break; case V4L2_FRMSIZE_TYPE_CONTINUOUS: @@ -243,7 +243,7 @@ static int testEnumFormatsType(struct node *node, unsigned type) return fail("fmtdesc.description not set\n"); if (!fmtdesc.pixelformat) return fail("fmtdesc.pixelformat not set\n"); - if (!wrapper && (fmtdesc.flags & V4L2_FMT_FLAG_EMULATED)) + if (node->g_direct() && (fmtdesc.flags & V4L2_FMT_FLAG_EMULATED)) return fail("drivers must never set the emulated flag\n"); if (fmtdesc.flags & ~(V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_EMULATED)) return fail("unknown flag %08x returned\n", fmtdesc.flags); @@ -282,10 +282,10 @@ int testEnumFormats(struct node *node) case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: case V4L2_BUF_TYPE_SDR_CAPTURE: - if (ret && (node->caps & buftype2cap[type])) + if (ret && (node->g_caps() & buftype2cap[type])) return fail("%s cap set, but no %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); - if (!ret && !(node->caps & buftype2cap[type])) + if (!ret && !(node->g_caps() & buftype2cap[type])) return fail("%s cap not set, but %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); break; @@ -330,15 +330,15 @@ int testFBuf(struct node *node) memset(&fbuf, 0xff, sizeof(fbuf)); fbuf.fmt.priv = 0; ret = doioctl(node, VIDIOC_G_FBUF, &fbuf); - fail_on_test(ret == 0 && !(node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY))); - fail_on_test(ret == ENOTTY && (node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY))); + fail_on_test(ret == 0 && !(node->g_caps() & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY))); + fail_on_test(ret == ENOTTY && (node->g_caps() & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY))); if (ret == ENOTTY) return ret; if (ret && ret != EINVAL) return fail("expected EINVAL, but got %d when getting framebuffer format\n", ret); node->fbuf_caps = caps = fbuf.capability; flags = fbuf.flags; - if (node->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) + if (node->g_caps() & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) fail_on_test(!fbuf.base); if (flags & V4L2_FBUF_FLAG_CHROMAKEY) fail_on_test(!(caps & V4L2_FBUF_CAP_CHROMAKEY)); @@ -551,10 +551,10 @@ int testGetFormats(struct node *node) case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: case V4L2_BUF_TYPE_SDR_CAPTURE: - if (ret && (node->caps & buftype2cap[type])) + if (ret && (node->g_caps() & buftype2cap[type])) return fail("%s cap set, but no %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); - if (!ret && !(node->caps & buftype2cap[type])) + if (!ret && !(node->g_caps() & buftype2cap[type])) return fail("%s cap not set, but %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); break; @@ -773,7 +773,7 @@ static int testGlobalFormat(struct node *node, int type) // test is pointless. // This test will also never succeed if we are using the libv4l2 // wrapper. - if (wrapper || (pixfmt1 == pixfmt2 && w1 == w2 && h1 == h2)) + if (!node->g_direct() || (pixfmt1 == pixfmt2 && w1 == w2 && h1 == h2)) return 0; if (type == V4L2_BUF_TYPE_SDR_CAPTURE) { @@ -993,13 +993,13 @@ static int testSlicedVBICapType(struct node *node, unsigned type) ret = doioctl(node, VIDIOC_G_SLICED_VBI_CAP, &cap); if (ret == ENOTTY || ret == EINVAL) { if (node->cur_io_caps & V4L2_IN_CAP_STD) - fail_on_test(sliced_type && (node->caps & buftype2cap[type])); + fail_on_test(sliced_type && (node->g_caps() & buftype2cap[type])); return ret == ENOTTY ? ret : 0; } fail_on_test(ret); fail_on_test(check_0(cap.reserved, sizeof(cap.reserved))); fail_on_test(cap.type != type); - fail_on_test(!sliced_type || !(node->caps & buftype2cap[type])); + fail_on_test(!sliced_type || !(node->g_caps() & buftype2cap[type])); for (int f = 0; f < 2; f++) for (int i = 0; i < 24; i++) @@ -1035,9 +1035,9 @@ static int testParmStruct(struct node *node, struct v4l2_streamparm &parm) if (ret) return fail("reserved not zeroed\n"); fail_on_test(cap->readbuffers > VIDEO_MAX_FRAME); - if (!(node->caps & V4L2_CAP_READWRITE)) + if (!(node->g_caps() & V4L2_CAP_READWRITE)) fail_on_test(cap->readbuffers); - else if (node->caps & V4L2_CAP_STREAMING) + else if (node->g_caps() & V4L2_CAP_STREAMING) fail_on_test(!cap->readbuffers); fail_on_test(cap->capability & ~V4L2_CAP_TIMEPERFRAME); fail_on_test(cap->capturemode & ~V4L2_MODE_HIGHQUALITY); @@ -1053,9 +1053,9 @@ static int testParmStruct(struct node *node, struct v4l2_streamparm &parm) if (ret) return fail("reserved not zeroed\n"); fail_on_test(out->writebuffers > VIDEO_MAX_FRAME); - if (!(node->caps & V4L2_CAP_READWRITE)) + if (!(node->g_caps() & V4L2_CAP_READWRITE)) fail_on_test(out->writebuffers); - else if (node->caps & V4L2_CAP_STREAMING) + else if (node->g_caps() & V4L2_CAP_STREAMING) fail_on_test(!out->writebuffers); fail_on_test(out->capability & ~V4L2_CAP_TIMEPERFRAME); fail_on_test(out->outputmode); @@ -1117,7 +1117,7 @@ int testParm(struct node *node) type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && type != V4L2_BUF_TYPE_VIDEO_OUTPUT) return fail("G/S_PARM is only allowed for video capture/output\n"); - if (!(node->caps & buftype2cap[type])) + if (!(node->g_caps() & buftype2cap[type])) return fail("%s cap not set, but G/S_PARM worked\n", buftype2s(type).c_str()); } diff --git a/utils/v4l2-compliance/v4l2-test-input-output.cpp b/utils/v4l2-compliance/v4l2-test-input-output.cpp index dcece7b..0d61289 100644 --- a/utils/v4l2-compliance/v4l2-test-input-output.cpp +++ b/utils/v4l2-compliance/v4l2-test-input-output.cpp @@ -110,8 +110,8 @@ static int checkTuner(struct node *node, const struct v4l2_tuner &tuner, if (node->is_sdr) fail_on_test(!(V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_1HZ)); fail_on_test(!(tuner.capability & V4L2_TUNER_CAP_FREQ_BANDS)); - fail_on_test(!(node->caps & V4L2_CAP_HW_FREQ_SEEK) && hwseek_caps); - fail_on_test((node->caps & V4L2_CAP_HW_FREQ_SEEK) && + fail_on_test(!(node->g_caps() & V4L2_CAP_HW_FREQ_SEEK) && hwseek_caps); + fail_on_test((node->g_caps() & V4L2_CAP_HW_FREQ_SEEK) && !(tuner.capability & (V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP))); if (tuner.rangelow > tuner.rangehigh) return fail("rangelow > rangehigh\n"); @@ -136,10 +136,10 @@ static int checkTuner(struct node *node, const struct v4l2_tuner &tuner, return fail("V4L2_TUNER_CAP_RDS is set, but not V4L2_TUNER_CAP_RDS_* or vice versa\n"); fail_on_test(node->is_sdr && have_rds); if ((tuner.capability & V4L2_TUNER_CAP_RDS_BLOCK_IO) && - !(node->caps & V4L2_CAP_READWRITE)) + !(node->g_caps() & V4L2_CAP_READWRITE)) return fail("V4L2_TUNER_CAP_RDS_BLOCK_IO is set, but not V4L2_CAP_READWRITE\n"); if (node->is_radio && !(tuner.capability & V4L2_TUNER_CAP_RDS_BLOCK_IO) && - (node->caps & V4L2_CAP_READWRITE)) + (node->g_caps() & V4L2_CAP_READWRITE)) return fail("V4L2_TUNER_CAP_RDS_BLOCK_IO is not set, but V4L2_CAP_READWRITE is\n"); if (std == V4L2_STD_NTSC_M && (tuner.rxsubchans & V4L2_TUNER_SUB_LANG1)) return fail("LANG1 subchan, but NTSC-M standard\n"); @@ -208,13 +208,13 @@ int testTuner(struct node *node) tuner.index = t; if (doioctl(node, VIDIOC_S_TUNER, &tuner) != EINVAL) return fail("could set invalid tuner %d\n", t); - if (node->tuners && !(node->caps & V4L2_CAP_TUNER)) + if (node->tuners && !(node->g_caps() & V4L2_CAP_TUNER)) return fail("tuners found, but no tuner capability set\n"); - if (!node->tuners && (node->caps & V4L2_CAP_TUNER)) + if (!node->tuners && (node->g_caps() & V4L2_CAP_TUNER)) return fail("no tuners found, but tuner capability set\n"); - if (has_rds && !(node->caps & V4L2_CAP_RDS_CAPTURE)) + if (has_rds && !(node->g_caps() & V4L2_CAP_RDS_CAPTURE)) return fail("RDS tuner capability, but no RDS capture capability?\n"); - if (!has_rds && (node->caps & V4L2_CAP_RDS_CAPTURE)) + if (!has_rds && (node->g_caps() & V4L2_CAP_RDS_CAPTURE)) return fail("No RDS tuner capability, but RDS capture capability?\n"); return 0; } @@ -244,10 +244,10 @@ int testTunerFreq(struct node *node) if (freq.type != V4L2_TUNER_RADIO && freq.type != V4L2_TUNER_ANALOG_TV && freq.type != V4L2_TUNER_ADC && freq.type != V4L2_TUNER_RF) return fail("returned invalid tuner type %d\n", freq.type); - if (freq.type == V4L2_TUNER_RADIO && !(node->caps & V4L2_CAP_RADIO)) + if (freq.type == V4L2_TUNER_RADIO && !(node->g_caps() & V4L2_CAP_RADIO)) return fail("radio tuner found but no radio capability set\n"); if ((freq.type == V4L2_TUNER_ADC || freq.type == V4L2_TUNER_RF) && - !(node->caps & V4L2_CAP_SDR_CAPTURE)) + !(node->g_caps() & V4L2_CAP_SDR_CAPTURE)) return fail("sdr tuner found but no sdr capture capability set\n"); if (freq.type != tuner.type) return fail("frequency tuner type and tuner type mismatch\n"); @@ -292,7 +292,7 @@ int testTunerFreq(struct node *node) } /* If this is a modulator device, then skip the remaining tests */ - if (node->caps & V4L2_CAP_MODULATOR) + if (node->g_caps() & V4L2_CAP_MODULATOR) return 0; freq.tuner = t; @@ -327,11 +327,11 @@ int testTunerHwSeek(struct node *node) seek.tuner = t; seek.type = V4L2_TUNER_RADIO; ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek); - if (!(node->caps & V4L2_CAP_HW_FREQ_SEEK) && ret != ENOTTY) + if (!(node->g_caps() & V4L2_CAP_HW_FREQ_SEEK) && ret != ENOTTY) return fail("hw seek supported but capability not set\n"); if (!node->is_radio && ret != ENOTTY) return fail("hw seek supported on a non-radio node?!\n"); - if (!node->is_radio || !(node->caps & V4L2_CAP_HW_FREQ_SEEK)) + if (!node->is_radio || !(node->g_caps() & V4L2_CAP_HW_FREQ_SEEK)) return ENOTTY; seek.type = V4L2_TUNER_ANALOG_TV; ret = doioctl(node, VIDIOC_S_HW_FREQ_SEEK, &seek); @@ -490,7 +490,7 @@ int testEnumInputAudio(struct node *node) node->audio_inputs++; i++; } - if (node->audio_inputs && !(node->caps & V4L2_CAP_AUDIO)) + if (node->audio_inputs && !(node->g_caps() & V4L2_CAP_AUDIO)) return fail("audio inputs reported, but no CAP_AUDIO set\n"); return 0; } @@ -592,10 +592,10 @@ static int checkModulator(struct node *node, const struct v4l2_modulator &mod, u if (have_rds ^ have_rds_method) return fail("V4L2_TUNER_CAP_RDS is set, but not V4L2_TUNER_CAP_RDS_* or vice versa\n"); if ((mod.capability & V4L2_TUNER_CAP_RDS_BLOCK_IO) && - !(node->caps & V4L2_CAP_READWRITE)) + !(node->g_caps() & V4L2_CAP_READWRITE)) return fail("V4L2_TUNER_CAP_RDS_BLOCK_IO is set, but not V4L2_CAP_READWRITE\n"); if (!(mod.capability & V4L2_TUNER_CAP_RDS_BLOCK_IO) && - (node->caps & V4L2_CAP_READWRITE)) + (node->g_caps() & V4L2_CAP_READWRITE)) return fail("V4L2_TUNER_CAP_RDS_BLOCK_IO is not set, but V4L2_CAP_READWRITE is\n"); return checkEnumFreqBands(node, mod.index, V4L2_TUNER_RADIO, mod.capability, mod.rangelow, mod.rangehigh); @@ -632,13 +632,13 @@ int testModulator(struct node *node) mod.index = m; if (doioctl(node, VIDIOC_S_MODULATOR, &mod) != EINVAL) return fail("could set invalid modulator %d\n", m); - if (node->modulators && !(node->caps & V4L2_CAP_MODULATOR)) + if (node->modulators && !(node->g_caps() & V4L2_CAP_MODULATOR)) return fail("modulators found, but no modulator capability set\n"); - if (!node->modulators && (node->caps & V4L2_CAP_MODULATOR)) + if (!node->modulators && (node->g_caps() & V4L2_CAP_MODULATOR)) return fail("no modulators found, but modulator capability set\n"); - if (has_rds && !(node->caps & V4L2_CAP_RDS_OUTPUT)) + if (has_rds && !(node->g_caps() & V4L2_CAP_RDS_OUTPUT)) return fail("RDS modulator capability, but no RDS output capability?\n"); - if (!has_rds && (node->caps & V4L2_CAP_RDS_OUTPUT)) + if (!has_rds && (node->g_caps() & V4L2_CAP_RDS_OUTPUT)) return fail("No RDS modulator capability, but RDS output capability?\n"); return 0; } @@ -699,7 +699,7 @@ int testModulatorFreq(struct node *node) } /* If this is a tuner device, then skip the remaining tests */ - if (node->caps & V4L2_CAP_TUNER) + if (node->g_caps() & V4L2_CAP_TUNER) return 0; freq.tuner = m; @@ -833,7 +833,7 @@ int testEnumOutputAudio(struct node *node) o++; } - if (node->audio_outputs && !(node->caps & V4L2_CAP_AUDIO)) + if (node->audio_outputs && !(node->g_caps() & V4L2_CAP_AUDIO)) return fail("audio outputs reported, but no CAP_AUDIO set\n"); return 0; } @@ -893,7 +893,7 @@ int testOutputAudio(struct node *node) return fail("invalid audioset for output %d\n", o); } - if (node->audio_outputs == 0 && node->audio_inputs == 0 && (node->caps & V4L2_CAP_AUDIO)) + if (node->audio_outputs == 0 && node->audio_inputs == 0 && (node->g_caps() & V4L2_CAP_AUDIO)) return fail("no audio inputs or outputs reported, but CAP_AUDIO set\n"); return node->audio_outputs ? 0 : ENOTTY; } diff --git a/utils/v4l2-compliance/v4l2-test-io-config.cpp b/utils/v4l2-compliance/v4l2-test-io-config.cpp index 150477c..c75ea55 100644 --- a/utils/v4l2-compliance/v4l2-test-io-config.cpp +++ b/utils/v4l2-compliance/v4l2-test-io-config.cpp @@ -155,7 +155,7 @@ static int checkTimings(struct node *node, bool has_timings, bool is_input) struct v4l2_enum_dv_timings enumtimings; struct v4l2_dv_timings timings; struct v4l2_format fmt; - bool is_mplane = node->caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | + bool is_mplane = node->g_caps() & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE); unsigned type;