From: Hans Verkuil Date: Sun, 20 Jul 2014 12:38:42 +0000 (+0200) Subject: qv4l2: integrate with the cv4l-helpers.h header X-Git-Tag: v4l-utils-1.3.90~75 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c646931f47a366305f87d25750ed585b441d1cbf;p=platform%2Fupstream%2Fv4l-utils.git qv4l2: integrate with the cv4l-helpers.h header Replace the old v4l2-api.cpp/.h files by the cv4l-helpers.h. It's a major change, but without any functional changes involved, just refactoring. Signed-off-by: Hans Verkuil --- diff --git a/utils/qv4l2/Makefile.am b/utils/qv4l2/Makefile.am index 57d76d3..1e3d081 100644 --- a/utils/qv4l2/Makefile.am +++ b/utils/qv4l2/Makefile.am @@ -1,18 +1,19 @@ bin_PROGRAMS = qv4l2 man_MANS = qv4l2.1 -qv4l2_SOURCES = qv4l2.cpp general-tab.cpp ctrl-tab.cpp vbi-tab.cpp v4l2-api.cpp capture-win.cpp \ +qv4l2_SOURCES = qv4l2.cpp general-tab.cpp ctrl-tab.cpp vbi-tab.cpp capture-win.cpp \ capture-win-qt.cpp capture-win-qt.h capture-win-gl.cpp capture-win-gl.h alsa_stream.c alsa_stream.h \ - raw2sliced.cpp qv4l2.h capture-win.h general-tab.h vbi-tab.h v4l2-api.h raw2sliced.h + raw2sliced.cpp qv4l2.h capture-win.h general-tab.h vbi-tab.h raw2sliced.h nodist_qv4l2_SOURCES = moc_qv4l2.cpp moc_general-tab.cpp moc_capture-win.cpp moc_vbi-tab.cpp qrc_qv4l2.cpp qv4l2_LDADD = ../../lib/libv4l2/libv4l2.la ../../lib/libv4lconvert/libv4lconvert.la ../libv4l2util/libv4l2util.la \ ../libmedia_dev/libmedia_dev.la +qv4l2_CPPFLAGS = -I../v4l2-compliance if WITH_QTGL -qv4l2_CPPFLAGS = $(QTGL_CFLAGS) +qv4l2_CPPFLAGS += $(QTGL_CFLAGS) qv4l2_LDFLAGS = $(QTGL_LIBS) else -qv4l2_CPPFLAGS = $(QT_CFLAGS) +qv4l2_CPPFLAGS += $(QT_CFLAGS) qv4l2_LDFLAGS = $(QT_LIBS) endif diff --git a/utils/qv4l2/ctrl-tab.cpp b/utils/qv4l2/ctrl-tab.cpp index 29f1e27..ccc7b68 100644 --- a/utils/qv4l2/ctrl-tab.cpp +++ b/utils/qv4l2/ctrl-tab.cpp @@ -83,7 +83,7 @@ void ApplicationWindow::addTabs(int size[]) memset(&qctrl, 0, sizeof(qctrl)); qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; - while (queryctrl(qctrl)) { + while (!queryctrl(qctrl)) { if (is_valid_type(qctrl.type) && (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) == 0) { m_ctrlMap[qctrl.id] = qctrl; @@ -109,7 +109,7 @@ void ApplicationWindow::addTabs(int size[]) m_classMap[V4L2_CTRL_CLASS_USER].push_back(qctrl.id); } for (qctrl.id = V4L2_CID_PRIVATE_BASE; - queryctrl(qctrl); qctrl.id++) { + !queryctrl(qctrl); qctrl.id++) { if (!is_valid_type(qctrl.type)) continue; if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) @@ -389,7 +389,7 @@ void ApplicationWindow::addCtrl(QGridLayout *grid, const v4l2_queryctrl &qctrl) for (int i = qctrl.minimum; i <= qctrl.maximum; i++) { qmenu.id = qctrl.id; qmenu.index = i; - if (!querymenu(qmenu)) + if (querymenu(qmenu)) continue; if (qctrl.type == V4L2_CTRL_TYPE_MENU) combo->addItem((char *)qmenu.name); @@ -479,7 +479,7 @@ void ApplicationWindow::ctrlAction(int id) ctrls.count = idx; ctrls.ctrl_class = ctrl_class; ctrls.controls = c; - if (ioctl(VIDIOC_S_EXT_CTRLS, &ctrls)) { + if (cv4l_ioctl(VIDIOC_S_EXT_CTRLS, &ctrls)) { if (ctrls.error_idx >= ctrls.count) { error(errno); } @@ -565,7 +565,7 @@ int ApplicationWindow::getVal(unsigned id) for (i = qctrl.minimum; i <= qctrl.maximum; i++) { qmenu.id = qctrl.id; qmenu.index = i; - if (!querymenu(qmenu)) + if (querymenu(qmenu)) continue; if (idx-- == 0) break; @@ -594,7 +594,7 @@ void ApplicationWindow::updateCtrl(unsigned id) c.id = id; c.value = getVal(id); - if (ioctl(VIDIOC_S_CTRL, &c)) { + if (cv4l_ioctl(VIDIOC_S_CTRL, &c)) { errorCtrl(id, errno, c.value); } else if (m_ctrlMap[id].flags & V4L2_CTRL_FLAG_UPDATE) @@ -619,7 +619,7 @@ void ApplicationWindow::updateCtrl(unsigned id) ctrls.count = 1; ctrls.ctrl_class = ctrl_class; ctrls.controls = &c; - if (ioctl(VIDIOC_S_EXT_CTRLS, &ctrls)) { + if (cv4l_ioctl(VIDIOC_S_EXT_CTRLS, &ctrls)) { errorCtrl(id, errno, c.value); } else if (m_ctrlMap[id].flags & V4L2_CTRL_FLAG_UPDATE) @@ -685,7 +685,7 @@ void ApplicationWindow::refresh(unsigned ctrl_class) if (m_ctrlMap[id].flags & V4L2_CTRL_FLAG_WRITE_ONLY) continue; c.id = id; - if (ioctl(VIDIOC_G_CTRL, &c)) { + if (cv4l_ioctl(VIDIOC_G_CTRL, &c)) { errorCtrl(id, errno); } setVal(id, c.value); @@ -717,7 +717,7 @@ void ApplicationWindow::refresh(unsigned ctrl_class) ctrls.count = cnt; ctrls.ctrl_class = ctrl_class; ctrls.controls = c; - if (ioctl(VIDIOC_G_EXT_CTRLS, &ctrls)) { + if (cv4l_ioctl(VIDIOC_G_EXT_CTRLS, &ctrls)) { if (ctrls.error_idx >= ctrls.count) { error(errno); } @@ -875,7 +875,7 @@ void ApplicationWindow::setVal(unsigned id, int v) for (i = qctrl.minimum; i <= v; i++) { qmenu.id = id; qmenu.index = i; - if (!querymenu(qmenu)) + if (querymenu(qmenu)) continue; idx++; } diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp index c5e732b..05e63dd 100644 --- a/utils/qv4l2/general-tab.cpp +++ b/utils/qv4l2/general-tab.cpp @@ -44,9 +44,20 @@ enum audioDeviceAdd { AUDIO_ADD_READWRITE }; -GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) : +static QString pixfmt2s(unsigned id) +{ + QString pixfmt; + + pixfmt += (char)(id & 0xff); + pixfmt += (char)((id >> 8) & 0xff); + pixfmt += (char)((id >> 16) & 0xff); + pixfmt += (char)((id >> 24) & 0xff); + return pixfmt; +} + +GeneralTab::GeneralTab(const QString &device, cv4l_fd *_fd, int n, QWidget *parent) : QGridLayout(parent), - v4l2(fd), + cv4l_fd(_fd), m_row(0), m_col(0), m_cols(n), @@ -107,26 +118,26 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) { m_device.append(device); setSizeConstraint(QLayout::SetMinimumSize); + for (int i = 0; i < n; i++) { m_maxw[i] = 0; } + cv4l_ioctl(VIDIOC_QUERYCAP, &m_querycap); - if (querycap(m_querycap)) { - addTitle("General Information"); + addTitle("General Information"); - addLabel("Device"); - addLabel(device + (useWrapper() ? " (wrapped)" : "")); + addLabel("Device"); + addLabel(device + (g_direct() ? "" : " (wrapped)")); - addLabel("Driver"); - addLabel((char *)m_querycap.driver); + addLabel("Driver"); + addLabel((char *)m_querycap.driver); - addLabel("Card"); - addLabel((char *)m_querycap.card); + addLabel("Card"); + addLabel((char *)m_querycap.card); - addLabel("Bus"); - addLabel((char *)m_querycap.bus_info); - } + addLabel("Bus"); + addLabel((char *)m_querycap.bus_info); g_tuner(m_tuner); g_tuner(m_tuner_rf, 1); @@ -147,38 +158,28 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) (m_modulator.capability & (V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_1HZ))) m_isRadio = true; if (m_querycap.capabilities & V4L2_CAP_DEVICE_CAPS) { - m_isVbi = caps() & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE); - m_isSDR = caps() & V4L2_CAP_SDR_CAPTURE; + m_isVbi = g_caps() & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE); + m_isSDR = g_caps() & V4L2_CAP_SDR_CAPTURE; if (m_isSDR) m_isRadio = true; - if (caps() & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE)) + if (g_caps() & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE)) m_isOutput = true; } if (m_querycap.capabilities & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE)) m_isPlanar = true; - if (isSlicedVbi()) - m_buftype = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - else if (isVbi()) - m_buftype = V4L2_BUF_TYPE_VBI_CAPTURE; - else if (m_isOutput) - m_buftype = isPlanar() ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : - V4L2_BUF_TYPE_VIDEO_OUTPUT; - else - m_buftype = isPlanar() ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : - V4L2_BUF_TYPE_VIDEO_CAPTURE; m_stackedStandards = new QStackedWidget; m_stackedFrameSettings = new QStackedWidget; m_stackedFrequency = new QStackedWidget; - if (enum_input(vin, true) || m_tuner.capability) { + if (!enum_input(vin, true) || m_tuner.capability) { addTitle("Input Settings"); inputSection(needsStd, needsTimings, vin); } - if (m_tuner_rf.capability || m_modulator.capability || (!isRadio() && enum_output(vout, true))) { + if (m_tuner_rf.capability || m_modulator.capability || (!isRadio() && !enum_output(vout, true))) { addTitle("Output Settings"); outputSection(vout, fmt); } @@ -188,8 +189,8 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) m_audioOutDevice = new QComboBox(parent); } - if (!isVbi() && (createAudioDeviceList() || (!isRadio() && enum_audio(vaudio, true)) || - (!isSDR() && m_tuner.capability) || (!isRadio() && enum_audout(vaudout, true)))) { + if (!isVbi() && (createAudioDeviceList() || (!isRadio() && !enum_audio(vaudio, true)) || + (!isSDR() && m_tuner.capability) || (!isRadio() && !enum_audout(vaudout, true)))) { addTitle("Audio Settings"); audioSection(vaudio, vaudout); } @@ -209,12 +210,13 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) if (isVbi()) { addLabel("VBI Capture Method"); m_vbiMethods = new QComboBox(parent); - if (caps() & V4L2_CAP_VBI_CAPTURE) + if (g_caps() & V4L2_CAP_VBI_CAPTURE) m_vbiMethods->addItem("Raw"); - if (caps() & V4L2_CAP_SLICED_VBI_CAPTURE) + if (g_caps() & V4L2_CAP_SLICED_VBI_CAPTURE) m_vbiMethods->addItem("Sliced"); addWidget(m_vbiMethods); connect(m_vbiMethods, SIGNAL(activated(int)), SLOT(vbiMethodsChanged(int))); + vbiMethodsChanged(0); updateVideoInput(); goto capture_method; } @@ -223,28 +225,27 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) capture_method: addLabel("Capture Method"); m_capMethods = new QComboBox(parent); - if (caps() & V4L2_CAP_STREAMING) { - v4l2_requestbuffers reqbuf; + if (g_caps() & V4L2_CAP_STREAMING) { + cv4l_queue q; - // Yuck. The videobuf framework does not accept a count of 0. + // Yuck. The videobuf framework does not accept a reqbufs count of 0. // This is out-of-spec, but it means that the only way to test which - // method is supported is to give it a non-zero count. But non-videobuf - // drivers like uvc do not allow e.g. S_FMT calls after a REQBUFS call - // with non-zero counts unless there is a REQBUFS call with count == 0 - // in between. This is actual proper behavior, although somewhat - // unexpected. So the only way at the moment to do this that works - // everywhere is to call REQBUFS with a count of 1, and then again with - // a count of 0. - if (reqbufs_user(reqbuf, 1)) { + // method is supported is to give it a non-zero count. But after that + // we have to reopen the device to clear the fact that there were + // buffers allocated. This is the only really portable way as long + // as there are still drivers around that do not support reqbufs(0). + q.init(g_type(), V4L2_MEMORY_USERPTR); + if (q.reqbufs(this, 1) == 0) { m_capMethods->addItem("User pointer I/O", QVariant(methodUser)); - reqbufs_user(reqbuf, 0); + reopen(true); } - if (reqbufs_mmap(reqbuf, 1)) { + q.init(g_type(), V4L2_MEMORY_MMAP); + if (q.reqbufs(this, 1) == 0) { m_capMethods->addItem("Memory mapped I/O", QVariant(methodMmap)); - reqbufs_mmap(reqbuf, 0); + reopen(true); } } - if (caps() & V4L2_CAP_READWRITE) { + if (g_caps() & V4L2_CAP_READWRITE) { m_capMethods->addItem("read()", QVariant(methodRead)); } addWidget(m_capMethods); @@ -272,7 +273,7 @@ done: void GeneralTab::inputSection(bool needsStd, bool needsTimings, v4l2_input vin) { - if (!isRadio() && enum_input(vin, true)) { + if (!isRadio() && !enum_input(vin, true)) { addLabel("Input"); m_videoInput = new QComboBox(parentWidget()); do { @@ -287,7 +288,7 @@ void GeneralTab::inputSection(bool needsStd, bool needsTimings, v4l2_input vin) }; subscribe_event(sub); - } while (enum_input(vin)); + } while (!enum_input(vin)); addWidget(m_videoInput); connect(m_videoInput, SIGNAL(activated(int)), SLOT(inputChanged(int))); m_row++; @@ -306,7 +307,7 @@ void GeneralTab::inputSection(bool needsStd, bool needsTimings, v4l2_input vin) m_stdRow->addWidget(m_tvStandard, 0, 1, Qt::AlignLeft); connect(m_tvStandard, SIGNAL(activated(int)), SLOT(standardChanged(int))); refreshStandards(); - if (ioctl_exists(VIDIOC_QUERYSTD, &tmp)) { + if (ioctl_exists(cv4l_ioctl(VIDIOC_QUERYSTD, &tmp))) { m_qryStandard = new QToolButton(parentWidget()); m_qryStandard->setIcon(QIcon(":/enterbutt.png")); m_stdRow->addWidget(new QLabel("Query Standard", parentWidget()), 0, 2, Qt::AlignLeft); @@ -440,12 +441,12 @@ void GeneralTab::inputSection(bool needsStd, bool needsTimings, v4l2_input vin) void GeneralTab::outputSection(v4l2_output vout, v4l2_fmtdesc fmt) { - if (!isRadio() && enum_output(vout, true)) { + if (!isRadio() && !enum_output(vout, true)) { addLabel("Output"); m_videoOutput = new QComboBox(parentWidget()); do { m_videoOutput->addItem((char *)vout.name); - } while (enum_output(vout)); + } while (!enum_output(vout)); addWidget(m_videoOutput); connect(m_videoOutput, SIGNAL(activated(int)), SLOT(outputChanged(int))); updateVideoOutput(); @@ -455,11 +456,11 @@ void GeneralTab::outputSection(v4l2_output vout, v4l2_fmtdesc fmt) addLabel("Output Image Formats"); m_vidOutFormats = new QComboBox(parentWidget()); m_vidOutFormats->setMinimumContentsLength(20); - if (enum_fmt(fmt, m_buftype, true)) { + if (!enum_fmt(fmt, true)) { do { m_vidOutFormats->addItem(pixfmt2s(fmt.pixelformat) + " - " + (const char *)fmt.description); - } while (enum_fmt(fmt, m_buftype)); + } while (!enum_fmt(fmt)); } addWidget(m_vidOutFormats); connect(m_vidOutFormats, SIGNAL(activated(int)), SLOT(vidOutFormatChanged(int))); @@ -545,7 +546,7 @@ void GeneralTab::audioSection(v4l2_audio vaudio, v4l2_audioout vaudout) setAudioDeviceBufferSize(75); } else { v4l2_fract fract; - if (!v4l2::get_interval(m_buftype, fract)) { + if (cv4l_fd::get_interval(fract)) { // Default values are for 30 FPS fract.numerator = 33; fract.denominator = 1000; @@ -561,13 +562,13 @@ void GeneralTab::audioSection(v4l2_audio vaudio, v4l2_audioout vaudout) } } - if (!isRadio() && enum_audio(vaudio, true)) { + if (!isRadio() && !enum_audio(vaudio, true)) { addLabel("Input Audio"); m_audioInput = new QComboBox(parentWidget()); m_audioInput->setMinimumContentsLength(10); do { m_audioInput->addItem((char *)vaudio.name); - } while (enum_audio(vaudio)); + } while (!enum_audio(vaudio)); addWidget(m_audioInput); connect(m_audioInput, SIGNAL(activated(int)), SLOT(inputAudioChanged(int))); updateAudioInput(); @@ -604,13 +605,13 @@ void GeneralTab::audioSection(v4l2_audio vaudio, v4l2_audioout vaudout) connect(m_audioMode, SIGNAL(activated(int)), SLOT(audioModeChanged(int))); } - if (!isRadio() && enum_audout(vaudout, true)) { + if (!isRadio() && !enum_audout(vaudout, true)) { addLabel("Output Audio"); m_audioOutput = new QComboBox(parentWidget()); m_audioOutput->setMinimumContentsLength(10); do { m_audioOutput->addItem((char *)vaudout.name); - } while (enum_audout(vaudout)); + } while (!enum_audout(vaudout)); addWidget(m_audioOutput); connect(m_audioOutput, SIGNAL(activated(int)), SLOT(outputAudioChanged(int))); updateAudioOutput(); @@ -623,7 +624,7 @@ void GeneralTab::formatSection(v4l2_fmtdesc fmt) addLabel("Capture Image Formats"); m_vidCapFormats = new QComboBox(parentWidget()); m_vidCapFormats->setMinimumContentsLength(20); - if (enum_fmt(fmt, m_buftype, true)) { + if (!enum_fmt(fmt, true)) { do { QString s(pixfmt2s(fmt.pixelformat) + " ("); @@ -631,7 +632,7 @@ void GeneralTab::formatSection(v4l2_fmtdesc fmt) m_vidCapFormats->addItem(s + "Emulated)"); else m_vidCapFormats->addItem(s + (const char *)fmt.description + ")"); - } while (enum_fmt(fmt, m_buftype)); + } while (!enum_fmt(fmt)); } addWidget(m_vidCapFormats); connect(m_vidCapFormats, SIGNAL(activated(int)), SLOT(vidCapFormatChanged(int))); @@ -1125,7 +1126,7 @@ void GeneralTab::updateGUI(int input) { v4l2_input in; enum_input(in, true, input); - if (!g_input(input) || m_isRadio) { + if (g_input(input) || m_isRadio) { m_stackedFrameSettings->hide(); return; } @@ -1306,16 +1307,13 @@ void GeneralTab::vidCapFormatChanged(int idx) { v4l2_fmtdesc desc; - enum_fmt(desc, m_buftype, true, idx); + enum_fmt(desc, true, idx); - v4l2_format fmt; + cv4l_fmt fmt; - g_fmt(m_buftype, fmt); - if (isPlanar()) - fmt.fmt.pix_mp.pixelformat = desc.pixelformat; - else - fmt.fmt.pix.pixelformat = desc.pixelformat; - if (try_fmt(fmt)) + g_fmt(fmt); + fmt.s_pixelformat(desc.pixelformat); + if (try_fmt(fmt) == 0) s_fmt(fmt); updateVidCapFormat(); @@ -1351,15 +1349,12 @@ static const char *field2s(int val) void GeneralTab::vidFieldChanged(int idx) { - v4l2_format fmt; + cv4l_fmt fmt; - g_fmt(m_buftype, fmt); + g_fmt(fmt); for (__u32 f = V4L2_FIELD_NONE; f <= V4L2_FIELD_INTERLACED_BT; f++) { if (m_vidFields->currentText() == QString(field2s(f))) { - if (isPlanar()) - fmt.fmt.pix_mp.field = f; - else - fmt.fmt.pix.field = f; + fmt.s_field(f); s_fmt(fmt); break; } @@ -1369,16 +1364,13 @@ void GeneralTab::vidFieldChanged(int idx) void GeneralTab::frameWidthChanged() { - v4l2_format fmt; + cv4l_fmt fmt; int val = m_frameWidth->value(); if (m_frameWidth->isEnabled()) { - g_fmt(m_buftype, fmt); - if (isPlanar()) - fmt.fmt.pix_mp.width = val; - else - fmt.fmt.pix.width = val; - if (try_fmt(fmt)) + g_fmt(fmt); + fmt.s_width(val); + if (try_fmt(fmt) == 0) s_fmt(fmt); } @@ -1387,16 +1379,13 @@ void GeneralTab::frameWidthChanged() void GeneralTab::frameHeightChanged() { - v4l2_format fmt; + cv4l_fmt fmt; int val = m_frameHeight->value(); if (m_frameHeight->isEnabled()) { - g_fmt(m_buftype, fmt); - if (isPlanar()) - fmt.fmt.pix_mp.height = val; - else - fmt.fmt.pix.height = val; - if (try_fmt(fmt)) + g_fmt(fmt); + fmt.s_height(val); + if (try_fmt(fmt) == 0) s_fmt(fmt); } @@ -1405,20 +1394,15 @@ void GeneralTab::frameHeightChanged() void GeneralTab::frameSizeChanged(int idx) { - v4l2_frmsizeenum frmsize; + v4l2_frmsizeenum frmsize = { 0 }; - if (enum_framesizes(frmsize, m_pixelformat, idx)) { - v4l2_format fmt; + if (!enum_framesizes(frmsize, m_pixelformat, idx)) { + cv4l_fmt fmt; - g_fmt(m_buftype, fmt); - if (isPlanar()) { - fmt.fmt.pix_mp.width = frmsize.discrete.width; - fmt.fmt.pix_mp.height = frmsize.discrete.height; - } else { - fmt.fmt.pix.width = frmsize.discrete.width; - fmt.fmt.pix.height = frmsize.discrete.height; - } - if (try_fmt(fmt)) + g_fmt(fmt); + fmt.s_width(frmsize.discrete.width); + fmt.s_height(frmsize.discrete.height); + if (try_fmt(fmt) == 0) s_fmt(fmt); } updateVidFormat(); @@ -1426,11 +1410,11 @@ void GeneralTab::frameSizeChanged(int idx) void GeneralTab::frameIntervalChanged(int idx) { - v4l2_frmivalenum frmival; + v4l2_frmivalenum frmival = { 0 }; - if (enum_frameintervals(frmival, m_pixelformat, m_width, m_height, idx) + if (!enum_frameintervals(frmival, m_pixelformat, m_width, m_height, idx) && frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) { - if (set_interval(m_buftype, frmival.discrete)) + if (!set_interval(frmival.discrete)) m_interval = frmival.discrete; } } @@ -1439,21 +1423,21 @@ void GeneralTab::vidOutFormatChanged(int idx) { v4l2_fmtdesc desc; - enum_fmt(desc, m_buftype, true, idx); + enum_fmt(desc, true, idx); - v4l2_format fmt; + cv4l_fmt fmt; - g_fmt(m_buftype, fmt); - fmt.fmt.pix.pixelformat = desc.pixelformat; - if (try_fmt(fmt)) + g_fmt(fmt); + fmt.s_pixelformat(desc.pixelformat); + if (try_fmt(fmt) == 0) s_fmt(fmt); updateVidOutFormat(); } void GeneralTab::vbiMethodsChanged(int idx) { - m_buftype = isSlicedVbi() ? V4L2_BUF_TYPE_SLICED_VBI_CAPTURE : - V4L2_BUF_TYPE_VBI_CAPTURE; + s_type(isSlicedVbi() ? V4L2_BUF_TYPE_SLICED_VBI_CAPTURE : + V4L2_BUF_TYPE_VBI_CAPTURE); } void GeneralTab::cropChanged() @@ -1468,7 +1452,7 @@ void GeneralTab::cropChanged() crop.c.left = m_cropLeft->value(); crop.c.height = m_cropHeight->value(); crop.c.top = m_cropTop->value(); - ioctl("Set Crop Rectangle", VIDIOC_S_CROP, &crop); + cv4l_ioctl(VIDIOC_S_CROP, &crop); updateVidCapFormat(); } @@ -1485,7 +1469,7 @@ void GeneralTab::composeChanged() sel.r.left = m_composeLeft->value(); sel.r.height = m_composeHeight->value(); sel.r.top = m_composeTop->value(); - ioctl("Set Compose Rectangle", VIDIOC_S_SELECTION, &sel); + cv4l_ioctl(VIDIOC_S_SELECTION, &sel); updateVidCapFormat(); } @@ -1494,7 +1478,7 @@ void GeneralTab::updateVideoInput() int input; v4l2_input in; - if (!g_input(input)) + if (g_input(input)) return; enum_input(in, true, input); m_videoInput->setCurrentIndex(input); @@ -1553,7 +1537,7 @@ void GeneralTab::updateVideoOutput() int output; v4l2_output out; - if (!g_output(output)) + if (g_output(output)) return; enum_output(out, true, output); m_videoOutput->setCurrentIndex(output); @@ -1602,10 +1586,10 @@ void GeneralTab::refreshStandards() { v4l2_standard vs; m_tvStandard->clear(); - if (enum_std(vs, true)) { + if (!enum_std(vs, true)) { do { m_tvStandard->addItem((char *)vs.name); - } while (enum_std(vs)); + } while (!enum_std(vs)); } } @@ -1616,18 +1600,18 @@ void GeneralTab::updateStandard() QString what; g_std(std); - if (enum_std(vs, true)) { + if (!enum_std(vs, true)) { do { if (vs.id == std) break; - } while (enum_std(vs)); + } while (!enum_std(vs)); } if (vs.id != std) { - if (enum_std(vs, true)) { + if (!enum_std(vs, true)) { do { if (vs.id & std) break; - } while (enum_std(vs)); + } while (!enum_std(vs)); } } if ((vs.id & std) == 0) @@ -1665,7 +1649,7 @@ void GeneralTab::refreshTimings() { v4l2_enum_dv_timings timings; m_videoTimings->clear(); - if (enum_dv_timings(timings, true)) { + if (!enum_dv_timings(timings, true)) { do { v4l2_bt_timings &bt = timings.timings.bt; double tot_height = bt.height + @@ -1682,7 +1666,7 @@ void GeneralTab::refreshTimings() sprintf(buf, "%dx%dp%.2f", bt.width, bt.height, (double)bt.pixelclock / (tot_width * tot_height)); m_videoTimings->addItem(buf); - } while (enum_dv_timings(timings)); + } while (!enum_dv_timings(timings)); } } @@ -1693,11 +1677,11 @@ void GeneralTab::updateTimings() QString what; g_dv_timings(timings); - if (enum_dv_timings(p, true)) { + if (!enum_dv_timings(p, true)) { do { if (!memcmp(&timings, &p.timings, sizeof(timings))) break; - } while (enum_dv_timings(p)); + } while (!enum_dv_timings(p)); } if (memcmp(&timings, &p.timings, sizeof(timings))) return; @@ -1714,7 +1698,7 @@ void GeneralTab::qryTimingsClicked() { v4l2_dv_timings timings; - if (query_dv_timings(timings)) { + if (!query_dv_timings(timings)) { s_dv_timings(timings); updateTimings(); } @@ -1765,40 +1749,24 @@ void GeneralTab::updateFreqRf() void GeneralTab::updateVidCapFormat() { v4l2_fmtdesc desc; - v4l2_format fmt; + cv4l_fmt fmt; if (isVbi()) return; - g_fmt(m_buftype, fmt); - if (isPlanar()) { - m_pixelformat = fmt.fmt.pix_mp.pixelformat; - m_width = fmt.fmt.pix_mp.width; - m_height = fmt.fmt.pix_mp.height; - } else { - m_pixelformat = fmt.fmt.pix.pixelformat; - m_width = fmt.fmt.pix.width; - m_height = fmt.fmt.pix.height; - } + g_fmt(fmt); + m_pixelformat = fmt.g_pixelformat(); + m_width = fmt.g_width(); + m_height = fmt.g_height(); updateFrameSize(); updateFrameInterval(); - if (enum_fmt(desc, m_buftype, true)) { + if (!enum_fmt(desc, true)) { do { - if (isPlanar()) { - if (desc.pixelformat == fmt.fmt.pix_mp.pixelformat) - break; - } else { - if (desc.pixelformat == fmt.fmt.pix.pixelformat) - break; - } - } while (enum_fmt(desc, m_buftype)); - } - if (isPlanar()) { - if (desc.pixelformat != fmt.fmt.pix_mp.pixelformat) - return; - } else { - if (desc.pixelformat != fmt.fmt.pix.pixelformat) - return; + if (desc.pixelformat == m_pixelformat) + break; + } while (!enum_fmt(desc)); } + if (desc.pixelformat != m_pixelformat) + return; m_vidCapFormats->setCurrentIndex(desc.index); updateVidFields(); updateCrop(); @@ -1808,75 +1776,46 @@ void GeneralTab::updateVidCapFormat() void GeneralTab::updateVidOutFormat() { v4l2_fmtdesc desc; - v4l2_format fmt; + cv4l_fmt fmt; - g_fmt(m_buftype, fmt); - if (isPlanar()) { - m_pixelformat = fmt.fmt.pix_mp.pixelformat; - m_width = fmt.fmt.pix_mp.width; - m_height = fmt.fmt.pix_mp.height; - } else { - m_pixelformat = fmt.fmt.pix.pixelformat; - m_width = fmt.fmt.pix.width; - m_height = fmt.fmt.pix.height; - } + g_fmt(fmt); + m_pixelformat = fmt.g_pixelformat(); + m_width = fmt.g_width(); + m_height = fmt.g_height(); updateFrameSize(); updateFrameInterval(); - if (enum_fmt(desc, m_buftype, true)) { + if (!enum_fmt(desc, true)) { do { - if (isPlanar()) { - if (desc.pixelformat == fmt.fmt.pix_mp.pixelformat) - break; - } else { - if (desc.pixelformat == fmt.fmt.pix.pixelformat) - break; - } - } while (enum_fmt(desc, m_buftype)); - } - if (isPlanar()) { - if (desc.pixelformat != fmt.fmt.pix_mp.pixelformat) - return; - } else { - if (desc.pixelformat != fmt.fmt.pix.pixelformat) - return; + if (desc.pixelformat == m_pixelformat) + break; + } while (!enum_fmt(desc)); } + if (desc.pixelformat == m_pixelformat) + return; m_vidOutFormats->setCurrentIndex(desc.index); updateVidFields(); } void GeneralTab::updateVidFields() { - v4l2_format fmt; - v4l2_format tmp; + cv4l_fmt fmt; + cv4l_fmt tmp; bool first = true; - g_fmt(m_buftype, fmt); + g_fmt(fmt); for (__u32 f = V4L2_FIELD_NONE; f <= V4L2_FIELD_INTERLACED_BT; f++) { tmp = fmt; - if (isPlanar()) { - tmp.fmt.pix_mp.field = f; - if (!try_fmt(tmp) || tmp.fmt.pix_mp.field != f) - continue; - if (first) { - m_vidFields->clear(); - first = false; - } - m_vidFields->addItem(field2s(f)); - if (fmt.fmt.pix_mp.field == f) - m_vidFields->setCurrentIndex(m_vidFields->count() - 1); - } else { - tmp.fmt.pix.field = f; - if (!try_fmt(tmp) || tmp.fmt.pix.field != f) - continue; - if (first) { - m_vidFields->clear(); - first = false; - } - m_vidFields->addItem(field2s(f)); - if (fmt.fmt.pix.field == f) - m_vidFields->setCurrentIndex(m_vidFields->count() - 1); + tmp.s_field(f); + if (try_fmt(tmp) || tmp.g_field() != f) + continue; + if (first) { + m_vidFields->clear(); + first = false; } + m_vidFields->addItem(field2s(f)); + if (fmt.g_field() == f) + m_vidFields->setCurrentIndex(m_vidFields->count() - 1); } } @@ -1891,8 +1830,8 @@ void GeneralTab::updateCrop() v4l2_rect &c = crop.c; cropcap.type = crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (ioctl(VIDIOC_CROPCAP, &cropcap) || - ioctl(VIDIOC_G_CROP, &crop)) + if (cv4l_ioctl(VIDIOC_CROPCAP, &cropcap) || + cv4l_ioctl(VIDIOC_G_CROP, &crop)) return; m_cropWidth->blockSignals(true); @@ -1929,7 +1868,7 @@ void GeneralTab::updateCompose() sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; sel.target = V4L2_SEL_TGT_COMPOSE; - if (ioctl(VIDIOC_G_SELECTION, &sel)) + if (cv4l_ioctl(VIDIOC_G_SELECTION, &sel)) return; m_composeWidth->blockSignals(true); @@ -1964,7 +1903,7 @@ void GeneralTab::updateFrameSize() m_frameSize->clear(); - ok = enum_framesizes(frmsize, m_pixelformat); + ok = !enum_framesizes(frmsize, m_pixelformat); if (ok && frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) { do { m_frameSize->addItem(QString("%1x%2") @@ -1972,7 +1911,7 @@ void GeneralTab::updateFrameSize() if (frmsize.discrete.width == m_width && frmsize.discrete.height == m_height) m_frameSize->setCurrentIndex(frmsize.index); - } while (enum_framesizes(frmsize)); + } while (!enum_framesizes(frmsize)); m_discreteSizes = true; m_frameWidth->setEnabled(false); @@ -2053,7 +1992,7 @@ double GeneralTab::getPixelAspectRatio() v4l2_fract ratio = { 1, 1 }; unsigned w = 0, h = 0; - ratio = g_pixel_aspect(m_buftype, w, h); + ratio = g_pixel_aspect(w, h); switch (m_pixelAspectRatio->currentIndex()) { // override ratio if hardcoded, but keep w and h case 1: @@ -2084,21 +2023,15 @@ double GeneralTab::getPixelAspectRatio() .arg(ratio.numerator).arg(ratio.denominator)); m_pixelAspectRatio->setStatusTip(m_pixelAspectRatio->whatsThis()); - v4l2_format fmt; + cv4l_fmt fmt; unsigned cur_width, cur_height; unsigned cur_field; - g_fmt(m_buftype, fmt); + g_fmt(fmt); - if (isPlanar()) { - cur_width = fmt.fmt.pix_mp.width; - cur_height = fmt.fmt.pix_mp.height; - cur_field = fmt.fmt.pix_mp.field; - } else { - cur_width = fmt.fmt.pix.width; - cur_height = fmt.fmt.pix.height; - cur_field = fmt.fmt.pix.field; - } + cur_width = fmt.g_width(); + cur_height = fmt.g_height(); + cur_field = fmt.g_field(); if (w == 0) w = cur_width; if (cur_field == V4L2_FIELD_TOP || @@ -2124,18 +2057,18 @@ double GeneralTab::getPixelAspectRatio() void GeneralTab::updateFrameInterval() { - v4l2_frmivalenum frmival; - v4l2_fract curr; + v4l2_frmivalenum frmival = { 0 }; + v4l2_fract curr = { 1, 1 }; bool curr_ok, ok; m_frameInterval->clear(); - ok = enum_frameintervals(frmival, m_pixelformat, m_width, m_height); + ok = !enum_frameintervals(frmival, m_pixelformat, m_width, m_height); m_has_interval = ok && frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE; m_frameInterval->setEnabled(m_has_interval); if (m_has_interval) { m_interval = frmival.discrete; - curr_ok = v4l2::get_interval(m_buftype, curr); + curr_ok = !cv4l_fd::get_interval(curr); do { m_frameInterval->addItem(QString("%1 fps") .arg((double)frmival.discrete.denominator / frmival.discrete.numerator)); @@ -2145,7 +2078,7 @@ void GeneralTab::updateFrameInterval() m_frameInterval->setCurrentIndex(frmival.index); m_interval = frmival.discrete; } - } while (enum_frameintervals(frmival)); + } while (!enum_frameintervals(frmival)); } } diff --git a/utils/qv4l2/general-tab.h b/utils/qv4l2/general-tab.h index 79865da..6941f78 100644 --- a/utils/qv4l2/general-tab.h +++ b/utils/qv4l2/general-tab.h @@ -31,7 +31,6 @@ #include #include "qv4l2.h" -#include "v4l2-api.h" #include "capture-win.h" #ifdef HAVE_ALSA @@ -48,12 +47,12 @@ class QSpinBox; class QToolButton; class QSlider; -class GeneralTab: public QGridLayout, public v4l2 +class GeneralTab: public QGridLayout, cv4l_fd { Q_OBJECT public: - GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent = 0); + GeneralTab(const QString &device, cv4l_fd *fd, int n, QWidget *parent = 0); virtual ~GeneralTab() {} CapMethod capMethod(); @@ -72,15 +71,6 @@ public: bool isVbi() const { return m_isVbi; } bool isSlicedVbi() const; bool isPlanar() const { return m_isPlanar; } - __u32 bufType() const { return m_buftype; } - inline bool reqbufs_mmap(v4l2_requestbuffers &reqbuf, int count = 0) { - return v4l2::reqbufs_mmap(reqbuf, m_buftype, count); - } - inline bool reqbufs_user(v4l2_requestbuffers &reqbuf, int count = 0) { - return v4l2::reqbufs_user(reqbuf, m_buftype, count); - } - inline bool streamon() { return v4l2::streamon(m_buftype); } - inline bool streamoff() { return v4l2::streamoff(m_buftype); } void setHaveBuffers(bool haveBuffers); void sourceChange(const v4l2_event &ev); unsigned getDisplayColorspace() const; @@ -205,7 +195,6 @@ private: bool m_isPlanar; bool m_haveBuffers; bool m_discreteSizes; - __u32 m_buftype; __u32 m_audioModes[5]; QString m_device; struct v4l2_tuner m_tuner; diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp index cc12d3a..a0209ac 100644 --- a/utils/qv4l2/qv4l2.cpp +++ b/utils/qv4l2/qv4l2.cpp @@ -17,13 +17,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "qv4l2.h" -#include "general-tab.h" -#include "vbi-tab.h" -#include "capture-win.h" -#include "capture-win-qt.h" -#include "capture-win-gl.h" - #ifdef ENABLE_ASLA extern "C" { #include "alsa_stream.h" @@ -59,7 +52,15 @@ extern "C" { #include #include #include -#include + +#include "qv4l2.h" +#include "general-tab.h" +#include "vbi-tab.h" +#include "capture-win.h" +#include "capture-win-qt.h" +#include "capture-win-gl.h" + +#include ApplicationWindow::ApplicationWindow() : m_capture(NULL), @@ -78,8 +79,9 @@ ApplicationWindow::ApplicationWindow() : m_capImage = NULL; m_frameData = NULL; m_nbuffers = 0; - m_buffers = NULL; m_makeSnapshot = false; + for (unsigned b = 0; b < sizeof(m_clear); b++) + m_clear[b] = false; QAction *openAct = new QAction(QIcon(":/fileopen.png"), "&Open Device", this); openAct->setStatusTip("Open a v4l device, use libv4l2 wrapper if possible"); @@ -217,14 +219,15 @@ ApplicationWindow::~ApplicationWindow() closeDevice(); } - void ApplicationWindow::setDevice(const QString &device, bool rawOpen) { closeDevice(); m_sigMapper = new QSignalMapper(this); connect(m_sigMapper, SIGNAL(mapped(int)), this, SLOT(ctrlAction(int))); - if (!open(device, !rawOpen)) { + s_direct(rawOpen); + + if (open(device.toLatin1(), true) < 0) { #ifdef HAVE_ALSA m_showAllAudioAct->setEnabled(false); m_audioBufferAct->setEnabled(false); @@ -235,7 +238,7 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen) newCaptureWin(); QWidget *w = new QWidget(m_tabs); - m_genTab = new GeneralTab(device, *this, 4, w); + m_genTab = new GeneralTab(device, this, 4, w); int size[2]; size[0] = m_genTab->getWidth(); size[1] = m_genTab->getHeight(); @@ -259,7 +262,8 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen) connect(m_genTab, SIGNAL(clearBuffers()), this, SLOT(clearBuffers())); m_tabs->addTab(w, "General Settings"); addTabs(size); - if (caps() & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)) { + m_vbiTab = NULL; + if (has_vbi_cap()) { w = new QWidget(m_tabs); m_vbiTab = new VbiTab(w); m_tabs->addTab(w, "VBI"); @@ -270,13 +274,13 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen) statusBar()->clearMessage(); m_tabs->show(); m_tabs->setFocus(); - m_convertData = v4lconvert_create(fd()); - m_capStartAct->setEnabled(fd() >= 0); - m_saveRawAct->setEnabled(fd() >= 0); + m_convertData = v4lconvert_create(g_fd()); + m_capStartAct->setEnabled(g_fd() >= 0); + m_saveRawAct->setEnabled(g_fd() >= 0); #ifdef HAVE_QTGL m_useGLAct->setEnabled(CaptureWinGL::isSupported()); #endif - m_ctrlNotifier = new QSocketNotifier(fd(), QSocketNotifier::Exception, m_tabs); + m_ctrlNotifier = new QSocketNotifier(g_fd(), QSocketNotifier::Exception, m_tabs); connect(m_ctrlNotifier, SIGNAL(activated(int)), this, SLOT(ctrlEvent())); } @@ -336,7 +340,7 @@ void ApplicationWindow::ctrlEvent() { v4l2_event ev; - while (dqevent(ev)) { + while (dqevent(ev) == 0) { if (ev.type == V4L2_EVENT_SOURCE_CHANGE) { m_genTab->sourceChange(ev); continue; @@ -381,7 +385,7 @@ void ApplicationWindow::ctrlEvent() ctrls.count = 1; ctrls.ctrl_class = 0; ctrls.controls = &c; - if (!ioctl(VIDIOC_G_EXT_CTRLS, &ctrls)) + if (!cv4l_ioctl(VIDIOC_G_EXT_CTRLS, &ctrls)) setString(ev.id, c.string); free(c.string); } @@ -408,13 +412,73 @@ void ApplicationWindow::newCaptureWin() connect(m_capture, SIGNAL(close()), this, SLOT(closeCaptureWin())); } +bool ApplicationWindow::startCapture() +{ + startAudio(); + + if (m_genTab->isRadio()) + return true; + + m_queue.init(g_type(), m_capMethod); + +#ifdef HAVE_QTGL + m_useGLAct->setEnabled(false); +#endif + + switch (m_capMethod) { + case methodRead: + m_snapshotAct->setEnabled(true); + m_genTab->setHaveBuffers(true); + /* Nothing to do. */ + return true; + + case methodMmap: + case methodUser: + if (m_queue.reqbufs(this, 4)) { + error("Cannot capture"); + break; + } + + if (m_queue.g_buffers() < 2) { + error("Too few buffers"); + break; + } + + if (m_queue.obtain_bufs(this)) { + error("Get buffers"); + break; + } + + for (unsigned i = 0; i < m_queue.g_buffers(); i++) { + cv4l_buffer buf; + + m_queue.buffer_init(buf, i); + qbuf(buf); + } + + if (streamon()) { + perror("VIDIOC_STREAMON"); + break; + } + m_snapshotAct->setEnabled(true); + m_genTab->setHaveBuffers(true); + return true; + } + + m_queue.free(this); + reopen(true); + m_capStartAct->setChecked(false); +#ifdef HAVE_QTGL + m_useGLAct->setEnabled(CaptureWinGL::isSupported()); +#endif + return false; +} + void ApplicationWindow::capVbiFrame() { - __u32 buftype = m_genTab->bufType(); - v4l2_buffer buf; + cv4l_buffer buf(m_queue); __u8 *data = NULL; int s = 0; - bool again; switch (m_capMethod) { case methodRead: @@ -430,43 +494,28 @@ void ApplicationWindow::capVbiFrame() break; case methodMmap: - if (!dqbuf_mmap(buf, buftype, again)) { - error("dqbuf"); - m_capStartAct->setChecked(false); - return; - } - if (again) - return; - if (buf.flags & V4L2_BUF_FLAG_ERROR) { - qbuf(buf); - return; - } - data = (__u8 *)m_buffers[buf.index].start[0]; - s = buf.bytesused; - break; - case methodUser: - if (!dqbuf_user(buf, buftype, again)) { + if (dqbuf(buf)) { + if (errno == EAGAIN) + return; error("dqbuf"); m_capStartAct->setChecked(false); return; } - if (again) - return; - if (buf.flags & V4L2_BUF_FLAG_ERROR) { + if (buf.g_flags() & V4L2_BUF_FLAG_ERROR) { qbuf(buf); return; } - data = (__u8 *)buf.m.userptr; - s = buf.bytesused; + data = (__u8 *)m_queue.g_dataptr(buf.g_index(), 0); + s = buf.g_bytesused(); break; } - if (buftype == V4L2_BUF_TYPE_VBI_CAPTURE && s != m_vbiSize) { + if (g_type() == V4L2_BUF_TYPE_VBI_CAPTURE && s != m_vbiSize) { error("incorrect vbi size"); m_capStartAct->setChecked(false); return; } - if (showFrames() && buftype == V4L2_BUF_TYPE_VBI_CAPTURE) { + if (showFrames() && g_type() == V4L2_BUF_TYPE_VBI_CAPTURE) { for (unsigned y = 0; y < m_vbiHeight; y++) { __u8 *p = data + y * m_vbiWidth; __u8 *q = m_capImage->bits() + y * m_capImage->bytesPerLine(); @@ -483,7 +532,7 @@ void ApplicationWindow::capVbiFrame() struct v4l2_sliced_vbi_data sdata[m_vbiHandle.count[0] + m_vbiHandle.count[1]]; struct v4l2_sliced_vbi_data *p; - if (buftype == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { + if (g_type() == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { p = (struct v4l2_sliced_vbi_data *)data; } else { vbi_parse(&m_vbiHandle, data, &sfmt, sdata); @@ -510,7 +559,7 @@ void ApplicationWindow::capVbiFrame() m_tv = tv; } status = QString("Frame: %1 Fps: %2").arg(++m_frame).arg(m_fps); - if (showFrames() && buftype == V4L2_BUF_TYPE_VBI_CAPTURE) + if (showFrames() && g_type() == V4L2_BUF_TYPE_VBI_CAPTURE) m_capture->setFrame(m_capImage->width(), m_capImage->height(), m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), NULL, status); @@ -523,22 +572,19 @@ void ApplicationWindow::capVbiFrame() void ApplicationWindow::capFrame() { - __u32 buftype = m_genTab->bufType(); - v4l2_plane planes[VIDEO_MAX_PLANES]; - v4l2_buffer buf; + cv4l_buffer buf(m_queue); + unsigned char *plane[2]; + unsigned bytesused[2]; int s = 0; int err = 0; - bool again; #ifdef HAVE_ALSA struct timeval tv_alsa; #endif - unsigned char *displaybuf = NULL; - unsigned char *displaybuf2 = NULL; - + plane[0] = plane[1] = NULL; switch (m_capMethod) { case methodRead: - s = read(m_frameData, m_capSrcFormat.fmt.pix.sizeimage); + s = read(m_frameData, m_capSrcFormat.g_sizeimage(0)); #ifdef HAVE_ALSA alsa_thread_timestamp(&tv_alsa); #endif @@ -555,31 +601,26 @@ void ApplicationWindow::capFrame() if (m_saveRaw.openMode()) m_saveRaw.write((const char *)m_frameData, s); - if (!showFrames()) - break; - if (m_mustConvert) + plane[0] = m_frameData; + if (showFrames() && m_mustConvert) { err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat, m_frameData, s, m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage); - if (m_mustConvert && err != -1) - displaybuf = m_capImage->bits(); - if (!m_mustConvert) - displaybuf = m_frameData; + if (err != -1) + plane[0] = m_capImage->bits(); + } break; case methodMmap: - memset(planes, 0, sizeof(planes)); - buf.length = VIDEO_MAX_PLANES; - buf.m.planes = planes; - if (!dqbuf_mmap(buf, buftype, again)) { + case methodUser: + if (dqbuf(buf)) { + if (errno == EAGAIN) + return; error("dqbuf"); m_capStartAct->setChecked(false); return; } - - if (again) - return; - if (buf.flags & V4L2_BUF_FLAG_ERROR) { + if (buf.g_flags() & V4L2_BUF_FLAG_ERROR) { qbuf(buf); return; } @@ -588,72 +629,27 @@ void ApplicationWindow::capFrame() alsa_thread_timestamp(&tv_alsa); #endif - if (showFrames()) { - if (m_mustConvert) - err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat, - (unsigned char *)m_buffers[buf.index].start[0], buf.bytesused, - m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage); - if (m_mustConvert && err != -1) - displaybuf = m_capImage->bits(); - if (!m_mustConvert) { - displaybuf = (unsigned char *)m_buffers[buf.index].start[0]; - displaybuf2 = (unsigned char *)m_buffers[buf.index].start[1]; - if (V4L2_TYPE_IS_MULTIPLANAR(buf.type)) { - displaybuf += planes[0].data_offset; - displaybuf2 += planes[1].data_offset; - } - } + plane[0] = (__u8 *)m_queue.g_dataptr(buf.g_index(), 0); + plane[1] = (__u8 *)m_queue.g_dataptr(buf.g_index(), 1); + plane[0] += buf.g_data_offset(0); + bytesused[0] = buf.g_bytesused(0) - buf.g_data_offset(0); + if (plane[1]) { + plane[1] += buf.g_data_offset(1); + bytesused[1] = buf.g_bytesused(1) - buf.g_data_offset(1); } - if (m_makeSnapshot) - makeSnapshot((unsigned char *)m_buffers[buf.index].start[0], buf.bytesused); - if (m_saveRaw.openMode()) - m_saveRaw.write((const char *)m_buffers[buf.index].start[0], buf.bytesused); - - break; - - case methodUser: - memset(planes, 0, sizeof(planes)); - buf.length = VIDEO_MAX_PLANES; - buf.m.planes = planes; - if (!dqbuf_user(buf, buftype, again)) { - error("dqbuf1"); - m_capStartAct->setChecked(false); - return; - } - if (again) - return; - if (buf.flags & V4L2_BUF_FLAG_ERROR) { - qbuf(buf); - return; - } -#ifdef HAVE_ALSA - alsa_thread_timestamp(&tv_alsa); -#endif - if (buf.flags & V4L2_BUF_FLAG_ERROR) { - qbuf(buf); - return; - } - - if (showFrames()) { - if (m_mustConvert) - err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat, - (unsigned char *)buf.m.userptr, buf.bytesused, - m_capImage->bits(), m_capDestFormat.fmt.pix.sizeimage); - if (m_mustConvert && err != -1) - displaybuf = m_capImage->bits(); - if (!m_mustConvert) { - displaybuf = (unsigned char *)m_buffers[buf.index].start[0]; - displaybuf2 = (unsigned char *)m_buffers[buf.index].start[1]; - if (V4L2_TYPE_IS_MULTIPLANAR(buf.type)) { - displaybuf += planes[0].data_offset; - displaybuf2 += planes[1].data_offset; - } + if (showFrames() && m_mustConvert) { + err = v4lconvert_convert(m_convertData, &m_capSrcFormat, &m_capDestFormat, + plane[0], bytesused[0], m_capImage->bits(), + m_capDestFormat.fmt.pix.sizeimage); + if (err != -1) { + plane[0] = m_capImage->bits(); + bytesused[0] = m_capDestFormat.fmt.pix.sizeimage; } } if (m_makeSnapshot) - makeSnapshot((unsigned char *)buf.m.userptr, buf.bytesused); + makeSnapshot(plane[0], bytesused[0]); if (m_saveRaw.openMode()) - m_saveRaw.write((const char *)buf.m.userptr, buf.bytesused); + m_saveRaw.write((const char *)plane[0], bytesused[0]); break; } @@ -679,26 +675,26 @@ void ApplicationWindow::capFrame() #ifdef HAVE_ALSA if (alsa_thread_is_running()) { if (tv_alsa.tv_sec || tv_alsa.tv_usec) { - m_totalAudioLatency.tv_sec += buf.timestamp.tv_sec - tv_alsa.tv_sec; - m_totalAudioLatency.tv_usec += buf.timestamp.tv_usec - tv_alsa.tv_usec; + m_totalAudioLatency.tv_sec += buf.g_timestamp().tv_sec - tv_alsa.tv_sec; + m_totalAudioLatency.tv_usec += buf.g_timestamp().tv_usec - tv_alsa.tv_usec; } status.append(QString(" Average A-V: %3 ms") .arg((m_totalAudioLatency.tv_sec * 1000 + m_totalAudioLatency.tv_usec / 1000) / m_frame)); } #endif - if (displaybuf == NULL && showFrames()) + if (plane[0] == NULL && showFrames()) status.append(" Error: Unsupported format."); if (showFrames()) m_capture->setFrame(m_capImage->width(), m_capImage->height(), - m_capDestFormat.fmt.pix.pixelformat, displaybuf, displaybuf2, status); + m_capDestFormat.g_pixelformat(), plane[0], plane[1], status); if (m_capMethod == methodMmap || m_capMethod == methodUser) { - if (m_buffers[buf.index].clear) { - memset(m_buffers[buf.index].start[0], 0, m_buffers[buf.index].length[0]); - if (V4L2_TYPE_IS_MULTIPLANAR(buf.type)) - memset(m_buffers[buf.index].start[1], 0, m_buffers[buf.index].length[1]); - m_buffers[buf.index].clear = false; + if (m_clear[buf.g_index()]) { + memset(m_queue.g_dataptr(buf.g_index(), 0), 0, buf.g_length()); + if (V4L2_TYPE_IS_MULTIPLANAR(buf.g_type())) + memset(m_queue.g_dataptr(buf.g_index(), 1), 0, buf.g_length(1)); + m_clear[buf.g_index()] = false; } qbuf(buf); @@ -711,180 +707,6 @@ void ApplicationWindow::capFrame() refresh(); } -bool ApplicationWindow::startCapture(unsigned buffer_size) -{ - startAudio(); - - if (m_genTab->isRadio()) - return true; - - __u32 buftype = m_genTab->bufType(); - v4l2_requestbuffers req; - unsigned int i; - - memset(&req, 0, sizeof(req)); - - m_useGLAct->setEnabled(false); - - switch (m_capMethod) { - case methodRead: - m_snapshotAct->setEnabled(true); - m_genTab->setHaveBuffers(true); - /* Nothing to do. */ - return true; - - case methodMmap: - if (!reqbufs_mmap(req, buftype, 3)) { - error("Cannot capture"); - break; - } - - if (req.count < 2) { - error("Too few buffers"); - reqbufs_mmap(req, buftype); - break; - } - - m_buffers = (buffer *)calloc(req.count, sizeof(*m_buffers)); - - if (!m_buffers) { - error("Out of memory"); - reqbufs_mmap(req, buftype); - break; - } - - for (m_nbuffers = 0; m_nbuffers < req.count; ++m_nbuffers) { - v4l2_plane planes[VIDEO_MAX_PLANES]; - v4l2_buffer buf; - - memset(&buf, 0, sizeof(buf)); - - buf.type = buftype; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = m_nbuffers; - buf.length = VIDEO_MAX_PLANES; - buf.m.planes = planes; - - if (-1 == ioctl(VIDIOC_QUERYBUF, &buf)) { - perror("VIDIOC_QUERYBUF"); - goto error; - } - - if (V4L2_TYPE_IS_MULTIPLANAR(buftype)) { - m_buffers[m_nbuffers].planes = buf.length; - for (unsigned p = 0; p < buf.length; p++) { - m_buffers[m_nbuffers].length[p] = planes[p].length; - m_buffers[m_nbuffers].start[p] = mmap(planes[p].length, planes[p].m.mem_offset); - if (MAP_FAILED == m_buffers[m_nbuffers].start[p]) { - perror("mmap"); - goto error; - } - memset(m_buffers[m_nbuffers].start[p], 0, - m_buffers[m_nbuffers].length[p]); - } - } else { - m_buffers[m_nbuffers].planes = 1; - m_buffers[m_nbuffers].length[0] = buf.length; - m_buffers[m_nbuffers].start[0] = mmap(buf.length, buf.m.offset); - if (MAP_FAILED == m_buffers[m_nbuffers].start[0]) { - perror("mmap"); - goto error; - } - memset(m_buffers[m_nbuffers].start[0], 0, - m_buffers[m_nbuffers].length[0]); - } - } - for (i = 0; i < m_nbuffers; ++i) { - if (!qbuf_mmap(i, buftype)) { - perror("VIDIOC_QBUF"); - goto error; - } - } - if (!streamon(buftype)) { - perror("VIDIOC_STREAMON"); - goto error; - } - m_snapshotAct->setEnabled(true); - m_genTab->setHaveBuffers(true); - return true; - - case methodUser: - if (!reqbufs_user(req, buftype, 3)) { - error("Cannot capture"); - break; - } - - if (req.count < 2) { - error("Too few buffers"); - reqbufs_user(req, buftype); - break; - } - - m_buffers = (buffer *)calloc(req.count, sizeof(*m_buffers)); - - if (!m_buffers) { - error("Out of memory"); - break; - } - - for (m_nbuffers = 0; m_nbuffers < req.count; ++m_nbuffers) { - v4l2_plane planes[VIDEO_MAX_PLANES]; - v4l2_buffer buf; - - memset(&buf, 0, sizeof(buf)); - - buf.type = buftype; - buf.memory = V4L2_MEMORY_USERPTR; - buf.index = m_nbuffers; - buf.length = VIDEO_MAX_PLANES; - buf.m.planes = planes; - - if (-1 == ioctl(VIDIOC_QUERYBUF, &buf)) { - perror("VIDIOC_QUERYBUF"); - goto error; - } - - if (V4L2_TYPE_IS_MULTIPLANAR(buftype)) { - m_buffers[m_nbuffers].planes = buf.length; - for (unsigned p = 0; p < buf.length; p++) { - m_buffers[m_nbuffers].length[p] = planes[p].length; - m_buffers[m_nbuffers].start[p] = calloc(1, planes[p].length); - if (m_buffers[m_nbuffers].start[p] == NULL) { - error("Out of memory"); - goto error; - } - } - } else { - m_buffers[m_nbuffers].planes = 1; - m_buffers[m_nbuffers].length[0] = buffer_size; - m_buffers[m_nbuffers].start[0] = calloc(1, buffer_size); - - if (!m_buffers[m_nbuffers].start[0]) { - error("Out of memory"); - goto error; - } - } - } - for (i = 0; i < m_nbuffers; ++i) - if (!qbuf_user(i, buftype, m_buffers[i].start, m_buffers[i].length)) { - perror("VIDIOC_QBUF"); - goto error; - } - if (!streamon(buftype)) { - perror("VIDIOC_STREAMON"); - goto error; - } - m_snapshotAct->setEnabled(true); - m_genTab->setHaveBuffers(true); - return true; - } - -error: - m_capStartAct->setChecked(false); - m_useGLAct->setEnabled(CaptureWinGL::isSupported()); - return false; -} - void ApplicationWindow::stopCapture() { stopAudio(); @@ -892,10 +714,7 @@ void ApplicationWindow::stopCapture() if (m_genTab->isRadio()) return; - __u32 buftype = m_genTab->bufType(); - v4l2_requestbuffers reqbufs; v4l2_encoder_cmd cmd; - unsigned i; m_capture->stop(); m_snapshotAct->setDisabled(true); @@ -904,36 +723,15 @@ void ApplicationWindow::stopCapture() case methodRead: memset(&cmd, 0, sizeof(cmd)); cmd.cmd = V4L2_ENC_CMD_STOP; - ioctl(VIDIOC_ENCODER_CMD, &cmd); + cv4l_ioctl(VIDIOC_ENCODER_CMD, &cmd); break; case methodMmap: - if (m_buffers == NULL) - break; - if (!streamoff(buftype)) - perror("VIDIOC_STREAMOFF"); - for (i = 0; i < m_nbuffers; ++i) - for (unsigned p = 0; p < m_buffers[i].planes; p++) - if (-1 == munmap(m_buffers[i].start[p], m_buffers[i].length[p])) - perror("munmap"); - // Free all buffers. - reqbufs_mmap(reqbufs, buftype, 1); // videobuf workaround - reqbufs_mmap(reqbufs, buftype, 0); - break; - case methodUser: - if (!streamoff(buftype)) - perror("VIDIOC_STREAMOFF"); - // Free all buffers. - reqbufs_user(reqbufs, buftype, 1); // videobuf workaround - reqbufs_user(reqbufs, buftype, 0); - for (i = 0; i < m_nbuffers; ++i) - for (unsigned p = 0; p < m_buffers[i].planes; p++) - free(m_buffers[i].start[p]); + m_queue.free(this); break; } - free(m_buffers); - m_buffers = NULL; + reopen(true); m_genTab->setHaveBuffers(false); refresh(); } @@ -949,14 +747,6 @@ bool ApplicationWindow::showFrames() return m_showFramesAct->isChecked(); } -void ApplicationWindow::startOutput(unsigned) -{ -} - -void ApplicationWindow::stopOutput() -{ -} - void ApplicationWindow::enableScaling(bool enable) { if (m_capture != NULL) @@ -983,16 +773,13 @@ void ApplicationWindow::updateColorspace() unsigned colorspace = m_genTab->getColorspace(); if (colorspace == 0) { - v4l2_format fmt; + cv4l_fmt fmt; - fmt.type = m_genTab->bufType(); + g_fmt(fmt); // don't use the wrapped ioctl since it doesn't // update colorspace correctly. - ::ioctl(fd(), VIDIOC_G_FMT, &fmt); - if (m_genTab->isPlanar()) - colorspace = fmt.fmt.pix_mp.colorspace; - else - colorspace = fmt.fmt.pix.colorspace; + ::ioctl(g_fd(), VIDIOC_G_FMT, &fmt); + colorspace = fmt.g_colorspace(); } m_capture->setColorspace(colorspace); } @@ -1005,9 +792,9 @@ void ApplicationWindow::updateDisplayColorspace() void ApplicationWindow::clearBuffers() { - if (m_capture && m_buffers) - for (unsigned b = 0; b < m_nbuffers; b++) - m_buffers[b].clear = true; + if (m_capture) + for (unsigned b = 0; b < sizeof(m_clear); b++) + m_clear[b] = true; } void ApplicationWindow::startAudio() @@ -1055,7 +842,7 @@ void ApplicationWindow::capStart(bool start) { if (m_genTab->isRadio()) { if (start) - startCapture(0); + startCapture(); else stopCapture(); @@ -1064,12 +851,6 @@ void ApplicationWindow::capStart(bool start) QImage::Format dstFmt = QImage::Format_RGB888; struct v4l2_fract interval; - v4l2_pix_format &srcPix = m_capSrcFormat.fmt.pix; - v4l2_pix_format &dstPix = m_capDestFormat.fmt.pix; - v4l2_pix_format_mplane &srcMPix = m_capSrcFormat.fmt.pix_mp; - v4l2_pix_format_mplane &dstMPix = m_capDestFormat.fmt.pix_mp; - __u32 buftype = m_genTab->bufType(); - bool isPlanar = m_genTab->isPlanar(); __u32 width, height, pixfmt; unsigned colorspace, field; @@ -1085,34 +866,42 @@ void ApplicationWindow::capStart(bool start) m_capMethod = m_genTab->capMethod(); if (m_genTab->isSlicedVbi()) { - v4l2_format fmt; + cv4l_fmt fmt; v4l2_std_id std; - g_fmt_sliced_vbi(fmt); - g_std(std); - fmt.fmt.sliced.service_set = (std & V4L2_STD_625_50) ? - V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; + s_type(V4L2_BUF_TYPE_SLICED_VBI_CAPTURE); + if (g_std(std)) { + error("this input isn't suitable for VBI\n"); + return; + } + if (g_fmt(fmt)) { + error("could not obtain an VBI format\n"); + return; + } + fmt.fmt.sliced.service_set = (std & V4L2_STD_525_60) ? + V4L2_SLICED_VBI_525 : V4L2_SLICED_VBI_625; s_fmt(fmt); memset(&m_vbiHandle, 0, sizeof(m_vbiHandle)); m_vbiTab->slicedFormat(fmt.fmt.sliced); m_vbiSize = fmt.fmt.sliced.io_size; m_frameData = new unsigned char[m_vbiSize]; - if (startCapture(m_vbiSize)) { - m_capNotifier = new QSocketNotifier(fd(), QSocketNotifier::Read, m_tabs); + if (startCapture()) { + m_capNotifier = new QSocketNotifier(g_fd(), QSocketNotifier::Read, m_tabs); connect(m_capNotifier, SIGNAL(activated(int)), this, SLOT(capVbiFrame())); } return; } if (m_genTab->isVbi()) { - v4l2_format fmt; + cv4l_fmt fmt; v4l2_std_id std; - if (!g_std(std)) { + s_type(V4L2_BUF_TYPE_VBI_CAPTURE); + if (g_std(std)) { error("this input isn't suitable for VBI\n"); return; } - if (!g_fmt_vbi(fmt)) { - error("could not obtain a VBI format\n"); + if (g_fmt(fmt)) { + error("could not obtain an VBI format\n"); return; } if (fmt.fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { @@ -1120,7 +909,6 @@ void ApplicationWindow::capStart(bool start) return; } s_fmt(fmt); - g_std(std); if (!vbi_prepare(&m_vbiHandle, &fmt.fmt.vbi, std)) { error("no services possible\n"); return; @@ -1139,58 +927,49 @@ void ApplicationWindow::capStart(bool start) m_capture->show(); statusBar()->showMessage("No frame"); - if (startCapture(m_vbiSize)) { - m_capNotifier = new QSocketNotifier(fd(), QSocketNotifier::Read, m_tabs); + if (startCapture()) { + m_capNotifier = new QSocketNotifier(g_fd(), QSocketNotifier::Read, m_tabs); connect(m_capNotifier, SIGNAL(activated(int)), this, SLOT(capVbiFrame())); } return; } - g_fmt(buftype, m_capSrcFormat); + m_capSrcFormat.s_type(g_type()); + g_fmt(m_capSrcFormat); s_fmt(m_capSrcFormat); - if (m_genTab->get_interval(interval)) - set_interval(buftype, interval); + if (!m_genTab->get_interval(interval)) + set_interval(interval); - if (!isPlanar) - m_frameData = new unsigned char[srcPix.sizeimage]; - else - m_frameData = new unsigned char[srcMPix.plane_fmt[0].sizeimage + srcMPix.plane_fmt[1].sizeimage]; + m_frameData = new unsigned char[m_capSrcFormat.g_sizeimage(0) + + m_capSrcFormat.g_sizeimage(1)]; m_capDestFormat = m_capSrcFormat; - if (isPlanar) { - dstMPix.pixelformat = srcMPix.pixelformat; - width = srcMPix.width; - height = srcMPix.height; - pixfmt = srcMPix.pixelformat; - colorspace = srcMPix.colorspace; - field = srcMPix.field; - m_mustConvert = false; - } else if (m_capture->hasNativeFormat(srcPix.pixelformat)) { - dstPix.pixelformat = srcPix.pixelformat; - width = srcPix.width; - height = srcPix.height; - pixfmt = srcPix.pixelformat; - colorspace = srcPix.colorspace; - field = srcPix.field; + if (m_capture->hasNativeFormat(m_capSrcFormat.g_pixelformat())) { + width = m_capSrcFormat.g_width(); + height = m_capSrcFormat.g_height(); + pixfmt = m_capSrcFormat.g_pixelformat(); + colorspace = m_capSrcFormat.g_colorspace(); + field = m_capSrcFormat.g_field(); m_mustConvert = false; } else { m_mustConvert = true; - dstPix.pixelformat = V4L2_PIX_FMT_RGB24; + m_capDestFormat.s_pixelformat(V4L2_PIX_FMT_RGB24); // Make sure sizeimage is large enough. This is necessary if the mplane // plugin is in use since v4lconvert_try_format() bypasses the plugin. - dstPix.sizeimage = dstPix.width * dstPix.height * 3; - v4l2_format copy = m_capSrcFormat; + m_capDestFormat.s_sizeimage(m_capDestFormat.g_width() * + m_capDestFormat.g_height() * 3); + cv4l_fmt copy = m_capSrcFormat; v4lconvert_try_format(m_convertData, &m_capDestFormat, &m_capSrcFormat); // v4lconvert_try_format sometimes modifies the source format if it thinks // that there is a better format available. Restore our selected source // format since we do not want that happening. m_capSrcFormat = copy; - width = dstPix.width; - height = dstPix.height; - pixfmt = dstPix.pixelformat; - colorspace = dstPix.colorspace; - field = dstPix.field; + width = m_capDestFormat.g_width(); + height = m_capDestFormat.g_height(); + pixfmt = m_capDestFormat.g_pixelformat(); + colorspace = m_capDestFormat.g_colorspace(); + field = m_capDestFormat.g_field(); } // Ensure that the initial image is large enough for native 32 bit per pixel formats @@ -1224,8 +1003,8 @@ void ApplicationWindow::capStart(bool start) m_capture->show(); statusBar()->showMessage("No frame"); - if (startCapture(srcPix.sizeimage)) { - m_capNotifier = new QSocketNotifier(fd(), QSocketNotifier::Read, m_tabs); + if (startCapture()) { + m_capNotifier = new QSocketNotifier(g_fd(), QSocketNotifier::Read, m_tabs); connect(m_capNotifier, SIGNAL(activated(int)), this, SLOT(capFrame())); } } @@ -1244,7 +1023,7 @@ void ApplicationWindow::closeDevice() m_capStartAct->setEnabled(false); m_capStartAct->setChecked(false); m_saveRawAct->setEnabled(false); - if (fd() >= 0) { + if (g_fd() >= 0) { if (m_capNotifier) { delete m_capNotifier; delete m_capImage; @@ -1258,7 +1037,7 @@ void ApplicationWindow::closeDevice() delete m_frameData; m_frameData = NULL; v4lconvert_destroy(m_convertData); - v4l2::close(); + cv4l_fd::close(); delete m_capture; m_capture = NULL; } diff --git a/utils/qv4l2/qv4l2.h b/utils/qv4l2/qv4l2.h index 949e6a4..40fbaa7 100644 --- a/utils/qv4l2/qv4l2.h +++ b/utils/qv4l2/qv4l2.h @@ -33,7 +33,10 @@ #include #include -#include "v4l2-api.h" +// Must come before cv4l-helpers.h +#include + +#include "cv4l-helpers.h" #include "raw2sliced.h" #include "capture-win.h" @@ -80,7 +83,7 @@ struct buffer { class CaptureWin; -class ApplicationWindow: public QMainWindow, public v4l2 +class ApplicationWindow: public QMainWindow, cv4l_fd { Q_OBJECT @@ -100,17 +103,15 @@ public: private: CaptureWin *m_capture; - bool startCapture(unsigned buffer_size); + bool startCapture(); void stopCapture(); - void startOutput(unsigned buffer_size); - void stopOutput(); void newCaptureWin(); void startAudio(); void stopAudio(); - struct buffer *m_buffers; - struct v4l2_format m_capSrcFormat; - struct v4l2_format m_capDestFormat; + bool m_clear[64]; + cv4l_fmt m_capSrcFormat; + cv4l_fmt m_capDestFormat; unsigned char *m_frameData; unsigned m_nbuffers; struct v4lconvert_data *m_convertData; @@ -194,6 +195,8 @@ private: void updateFreqChannel(); bool showFrames(); + cv4l_queue m_queue; + const double m_pxw; const int m_minWidth; const int m_vMargin; diff --git a/utils/qv4l2/qv4l2.pro b/utils/qv4l2/qv4l2.pro index 939b71f..7ab39cc 100644 --- a/utils/qv4l2/qv4l2.pro +++ b/utils/qv4l2/qv4l2.pro @@ -7,8 +7,8 @@ INCLUDEPATH += . ../libv4l2util ../../lib/include ../../include CONFIG += debug # Input -HEADERS += qv4l2.h general-tab.h v4l2-api.h capture-win.h -SOURCES += qv4l2.cpp general-tab.cpp ctrl-tab.cpp v4l2-api.cpp capture-win.cpp +HEADERS += qv4l2.h general-tab.h capture-win.h +SOURCES += qv4l2.cpp general-tab.cpp ctrl-tab.cpp capture-win.cpp LIBS += -L../../lib/libv4l2 -lv4l2 -L../../lib/libv4lconvert -lv4lconvert -lrt -L../libv4l2util -lv4l2util -ldl -ljpeg RESOURCES += qv4l2.qrc diff --git a/utils/qv4l2/v4l2-api.cpp b/utils/qv4l2/v4l2-api.cpp deleted file mode 100644 index f79c335..0000000 --- a/utils/qv4l2/v4l2-api.cpp +++ /dev/null @@ -1,656 +0,0 @@ -/* v4l2-api: low-level wrapper around v4l2 devices - * - * Copyright (C) 2009 Hans Verkuil - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include "v4l2-api.h" - -bool v4l2::open(const QString &device, bool useWrapper) -{ - m_device = device; - m_useWrapper = useWrapper; - m_fd = ::open(device.toAscii(), O_RDWR | O_NONBLOCK); - if (m_fd < 0) { - error("Cannot open " + device); - return false; - } - if (!querycap(m_capability)) { - ::close(m_fd); - m_fd = -1; - error(device + " is not a V4L2 device"); - return false; - } - - if (m_useWrapper) { - int fd = ::v4l2_fd_open(m_fd, V4L2_ENABLE_ENUM_FMT_EMULATION); - - if (fd < 0) { - m_useWrapper = false; - error("Cannot use libv4l2 wrapper for " + device); - } - } - return true; -} - -void v4l2::close() -{ - if (useWrapper()) - ::v4l2_close(m_fd); - else - ::close(m_fd); - m_fd = -1; -} - -int v4l2::ioctl(unsigned cmd, void *arg) -{ - if (useWrapper()) - return v4l2_ioctl(m_fd, cmd, arg); - return ::ioctl(m_fd, cmd, arg); -} - -bool v4l2::ioctl(const QString &descr, unsigned cmd, void *arg) -{ - clear(); - int err = ioctl(cmd, arg); - - if (err < 0) { - QString s = strerror(errno); - error(descr + ": " + s); - } - return err >= 0; -} - -bool v4l2::ioctl_exists(unsigned cmd, void *arg) -{ - int err; - - if (useWrapper()) - err = v4l2_ioctl(m_fd, cmd, arg); - else - err = ::ioctl(m_fd, cmd, arg); - return !err || errno != ENOTTY; -} - -int v4l2::read(unsigned char *p, int size) -{ - if (useWrapper()) - return v4l2_read(m_fd, p, size); - return ::read(m_fd, p, size); -} - -void *v4l2::mmap(size_t length, int64_t offset) -{ - if (useWrapper()) - return v4l2_mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, offset); - return ::mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, offset); -} - -int v4l2::munmap(void *start, size_t length) -{ - if (useWrapper()) - return v4l2_munmap(start, length); - return ::munmap(start, length); -} - -void v4l2::error(const QString &error) -{ - if (!error.isEmpty()) - fprintf(stderr, "%s\n", error.toAscii().data()); -} - -QString v4l2::pixfmt2s(unsigned id) -{ - QString pixfmt; - - pixfmt += (char)(id & 0xff); - pixfmt += (char)((id >> 8) & 0xff); - pixfmt += (char)((id >> 16) & 0xff); - pixfmt += (char)((id >> 24) & 0xff); - return pixfmt; -} - -bool v4l2::querycap(v4l2_capability &cap) -{ - memset(&cap, 0, sizeof(cap)); - return ioctl(VIDIOC_QUERYCAP, &cap) >= 0; -} - -bool v4l2::queryctrl(v4l2_queryctrl &qc) -{ - return ioctl(VIDIOC_QUERYCTRL, &qc) >= 0; -} - -bool v4l2::querymenu(v4l2_querymenu &qm) -{ - return ioctl(VIDIOC_QUERYMENU, &qm) >= 0; -} - -bool v4l2::g_tuner(v4l2_tuner &tuner, unsigned index) -{ - memset(&tuner, 0, sizeof(tuner)); - tuner.index = index; - if (ioctl(VIDIOC_G_TUNER, &tuner) < 0) - return false; - if (tuner.rangehigh > INT_MAX) - tuner.rangehigh = INT_MAX; - return true; -} - -bool v4l2::s_tuner(v4l2_tuner &tuner) -{ - return ioctl("Set Tuner", VIDIOC_S_TUNER, &tuner); -} - -bool v4l2::g_modulator(v4l2_modulator &modulator) -{ - memset(&modulator, 0, sizeof(modulator)); - return ioctl(VIDIOC_G_MODULATOR, &modulator) >= 0; -} - -bool v4l2::s_modulator(v4l2_modulator &modulator) -{ - return ioctl("Set Modulator", VIDIOC_S_MODULATOR, &modulator); -} - -bool v4l2::g_input(int &input) -{ - return ioctl(VIDIOC_G_INPUT, &input) >= 0; -} - -bool v4l2::s_input(int input) -{ - return ioctl("Set Input", VIDIOC_S_INPUT, &input); -} - -bool v4l2::g_output(int &output) -{ - return ioctl(VIDIOC_G_OUTPUT, &output) >= 0; -} - -bool v4l2::s_output(int output) -{ - return ioctl("Set Output", VIDIOC_S_OUTPUT, &output); -} - -bool v4l2::g_audio(v4l2_audio &audio) -{ - memset(&audio, 0, sizeof(audio)); - return ioctl(VIDIOC_G_AUDIO, &audio) >= 0; -} - -bool v4l2::s_audio(int input) -{ - v4l2_audio audio; - - memset(&audio, 0, sizeof(audio)); - audio.index = input; - return ioctl("Set Audio Input", VIDIOC_S_AUDIO, &audio); -} - -bool v4l2::g_audout(v4l2_audioout &audout) -{ - memset(&audout, 0, sizeof(audout)); - return ioctl(VIDIOC_G_AUDOUT, &audout) >= 0; -} - -bool v4l2::s_audout(int output) -{ - v4l2_audioout audout; - - memset(&audout, 0, sizeof(audout)); - audout.index = output; - return ioctl("Set Audio Output", VIDIOC_S_AUDOUT, &audout); -} - -bool v4l2::g_std(v4l2_std_id &std) -{ - return ioctl(VIDIOC_G_STD, &std) >= 0; -} - -bool v4l2::s_std(v4l2_std_id std) -{ - return ioctl("Set TV Standard", VIDIOC_S_STD, &std); -} - -bool v4l2::query_std(v4l2_std_id &std) -{ - return ioctl("Query TV Standard", VIDIOC_QUERYSTD, &std); -} - -bool v4l2::g_dv_timings(v4l2_dv_timings &timings) -{ - int err = ioctl(VIDIOC_G_DV_TIMINGS, &timings); - return err >= 0; -} - -bool v4l2::s_dv_timings(v4l2_dv_timings &timings) -{ - return ioctl("Set Timings", VIDIOC_S_DV_TIMINGS, &timings); -} - -bool v4l2::query_dv_timings(v4l2_dv_timings &timings) -{ - return ioctl("Query Timings", VIDIOC_QUERY_DV_TIMINGS, &timings); -} - - -bool v4l2::g_frequency(v4l2_frequency &freq, unsigned index) -{ - memset(&freq, 0, sizeof(freq)); - freq.tuner = index; - freq.type = V4L2_TUNER_ANALOG_TV; - return ioctl(VIDIOC_G_FREQUENCY, &freq) >= 0; -} - -bool v4l2::s_frequency(v4l2_frequency &freq) -{ - return ioctl("Set Frequency", VIDIOC_S_FREQUENCY, &freq); -} - -bool v4l2::s_frequency(int val, bool low) -{ - v4l2_frequency f; - - memset(&f, 0, sizeof(f)); - f.type = low ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - f.frequency = val; - return s_frequency(f); -} - -bool v4l2::g_fmt(unsigned type, v4l2_format &fmt) -{ - memset(&fmt, 0, sizeof(fmt)); - fmt.type = type; - return ioctl(VIDIOC_G_FMT, &fmt) >= 0; -} - -bool v4l2::g_fmt_vbi(v4l2_format &fmt) -{ - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VBI_CAPTURE; - return ioctl(VIDIOC_G_FMT, &fmt) >= 0; -} - -bool v4l2::g_fmt_sliced_vbi(v4l2_format &fmt) -{ - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - return ioctl(VIDIOC_G_FMT, &fmt) >= 0; -} - -bool v4l2::try_fmt(v4l2_format &fmt) -{ - if (V4L2_TYPE_IS_MULTIPLANAR(fmt.type)) { - fmt.fmt.pix_mp.plane_fmt[0].bytesperline = 0; - fmt.fmt.pix_mp.plane_fmt[1].bytesperline = 0; - } else { - fmt.fmt.pix.bytesperline = 0; - } - return ioctl("Try Capture Format", VIDIOC_TRY_FMT, &fmt); -} - -bool v4l2::s_fmt(v4l2_format &fmt) -{ - if (V4L2_TYPE_IS_MULTIPLANAR(fmt.type)) { - fmt.fmt.pix_mp.plane_fmt[0].bytesperline = 0; - fmt.fmt.pix_mp.plane_fmt[1].bytesperline = 0; - } else { - fmt.fmt.pix.bytesperline = 0; - } - return ioctl("Set Capture Format", VIDIOC_S_FMT, &fmt); -} - -bool v4l2::enum_input(v4l2_input &in, bool init, int index) -{ - if (init) { - memset(&in, 0, sizeof(in)); - in.index = index; - } else { - in.index++; - } - return ioctl(VIDIOC_ENUMINPUT, &in) >= 0; -} - -bool v4l2::enum_output(v4l2_output &out, bool init, int index) -{ - if (init) { - memset(&out, 0, sizeof(out)); - out.index = index; - } else { - out.index++; - } - return ioctl(VIDIOC_ENUMOUTPUT, &out) >= 0; -} - -bool v4l2::enum_audio(v4l2_audio &audio, bool init) -{ - if (init) - memset(&audio, 0, sizeof(audio)); - else - audio.index++; - return ioctl(VIDIOC_ENUMAUDIO, &audio) >= 0; -} - -bool v4l2::enum_audout(v4l2_audioout &audout, bool init) -{ - if (init) - memset(&audout, 0, sizeof(audout)); - else - audout.index++; - return ioctl(VIDIOC_ENUMAUDOUT, &audout) >= 0; -} - -bool v4l2::enum_std(v4l2_standard &std, bool init, int index) -{ - if (init) { - memset(&std, 0, sizeof(std)); - std.index = index; - } else { - std.index++; - } - return ioctl(VIDIOC_ENUMSTD, &std) >= 0; -} - -bool v4l2::enum_dv_timings(v4l2_enum_dv_timings &timings, bool init, int index) -{ - if (init) { - memset(&timings, 0, sizeof(timings)); - timings.index = index; - } else { - timings.index++; - } - return ioctl(VIDIOC_ENUM_DV_TIMINGS, &timings) >= 0; -} - -bool v4l2::enum_fmt(v4l2_fmtdesc &fmt, unsigned type, bool init, int index) -{ - if (init) { - memset(&fmt, 0, sizeof(fmt)); - fmt.index = index; - } else { - fmt.index++; - } - fmt.type = type; - return ioctl(VIDIOC_ENUM_FMT, &fmt) >= 0; -} - -bool v4l2::enum_framesizes(v4l2_frmsizeenum &frm, __u32 init_pixfmt, int index) -{ - if (init_pixfmt) { - memset(&frm, 0, sizeof(frm)); - frm.pixel_format = init_pixfmt; - frm.index = index; - } else { - frm.index++; - } - return ioctl(VIDIOC_ENUM_FRAMESIZES, &frm) >= 0; -} - -bool v4l2::enum_frameintervals(v4l2_frmivalenum &frm, __u32 init_pixfmt, __u32 w, __u32 h, int index) -{ - 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 ioctl(VIDIOC_ENUM_FRAMEINTERVALS, &frm) >= 0; -} - -bool v4l2::reqbufs_user(v4l2_requestbuffers &reqbuf, __u32 buftype, int count) -{ - memset(&reqbuf, 0, sizeof (reqbuf)); - reqbuf.type = buftype; - reqbuf.memory = V4L2_MEMORY_USERPTR; - reqbuf.count = count; - - return ioctl(VIDIOC_REQBUFS, &reqbuf) >= 0; -} - -bool v4l2::reqbufs_mmap(v4l2_requestbuffers &reqbuf, __u32 buftype, int count) -{ - memset(&reqbuf, 0, sizeof (reqbuf)); - reqbuf.type = buftype; - reqbuf.memory = V4L2_MEMORY_MMAP; - reqbuf.count = count; - - return ioctl(VIDIOC_REQBUFS, &reqbuf) >= 0; -} - -bool v4l2::dqbuf_mmap(v4l2_buffer &buf, __u32 buftype, bool &again) -{ - v4l2_plane *planes = buf.m.planes; - unsigned length = buf.length; - int res; - - memset(&buf, 0, sizeof(buf)); - buf.length = length; - buf.m.planes = planes; - buf.type = buftype; - buf.memory = V4L2_MEMORY_MMAP; - res = ioctl(VIDIOC_DQBUF, &buf); - again = res < 0 && errno == EAGAIN; - return res >= 0 || again; -} - -bool v4l2::dqbuf_user(v4l2_buffer &buf, __u32 buftype, bool &again) -{ - v4l2_plane *planes = buf.m.planes; - unsigned length = buf.length; - int res; - - memset(&buf, 0, sizeof(buf)); - buf.length = length; - buf.m.planes = planes; - buf.type = buftype; - buf.memory = V4L2_MEMORY_USERPTR; - res = ioctl(VIDIOC_DQBUF, &buf); - again = res < 0 && errno == EAGAIN; - return res >= 0 || again; -} - -bool v4l2::qbuf(v4l2_buffer &buf) -{ - return ioctl(VIDIOC_QBUF, &buf) >= 0; -} - -bool v4l2::qbuf_mmap(int index, __u32 buftype) -{ - v4l2_plane planes[VIDEO_MAX_PLANES]; - v4l2_buffer buf; - - memset(&buf, 0, sizeof(buf)); - buf.type = buftype; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = index; - buf.length = 2; - buf.m.planes = planes; - return qbuf(buf); -} - -bool v4l2::qbuf_user(int index, __u32 buftype, void *ptr[], size_t length[]) -{ - v4l2_plane planes[VIDEO_MAX_PLANES]; - v4l2_buffer buf; - - memset(&buf, 0, sizeof(buf)); - buf.type = buftype; - buf.memory = V4L2_MEMORY_USERPTR; - if (V4L2_TYPE_IS_MULTIPLANAR(buftype)) { - buf.length = 2; - buf.m.planes = planes; - planes[0].length = length[0]; - planes[0].m.userptr = (unsigned long)ptr[0]; - planes[1].length = length[1]; - planes[1].m.userptr = (unsigned long)ptr[1]; - } else { - buf.m.userptr = (unsigned long)ptr[0]; - buf.length = length[0]; - } - buf.index = index; - return qbuf(buf); -} - -bool v4l2::streamon(__u32 buftype) -{ - return ioctl("Start Streaming", VIDIOC_STREAMON, &buftype); -} - -bool v4l2::streamoff(__u32 buftype) -{ - return ioctl("Stop Streaming", VIDIOC_STREAMOFF, &buftype); -} - -bool v4l2::subscribe_event(v4l2_event_subscription &sub) -{ - return ioctl(VIDIOC_SUBSCRIBE_EVENT, &sub); -} - -bool v4l2::dqevent(v4l2_event &ev) -{ - return ioctl(VIDIOC_DQEVENT, &ev) >= 0; -} - -bool v4l2::set_interval(unsigned type, v4l2_fract interval) -{ - v4l2_streamparm parm; - - parm.type = type; - if (ioctl(VIDIOC_G_PARM, &parm) < 0) - return false; - - if (!(parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) - return false; - - parm.parm.capture.timeperframe = interval; - - return ioctl("Set FPS", VIDIOC_S_PARM, &parm); -} - -bool v4l2::get_interval(unsigned type, v4l2_fract &interval) -{ - v4l2_streamparm parm; - - parm.type = type; - if (ioctl(VIDIOC_G_PARM, &parm) >= 0 && - (parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) { - interval = parm.parm.capture.timeperframe; - return true; - } - - return false; -} - -v4l2_fract v4l2::g_pixel_aspect(unsigned type, unsigned &width, unsigned &height) -{ - 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; - if (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; -} - -bool v4l2::has_crop() -{ - v4l2_crop crop; - v4l2_cropcap cropcap; - - crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - return ioctl_exists(VIDIOC_G_CROP, &crop) && - ioctl_exists(VIDIOC_S_CROP, &crop) && - ioctl_exists(VIDIOC_CROPCAP, &cropcap); -} - -bool v4l2::input_has_crop() -{ - v4l2_crop crop; - v4l2_cropcap cropcap; - - crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - return ioctl(VIDIOC_G_CROP, &crop) == 0 && - ioctl(VIDIOC_S_CROP, &crop) == 0 && - ioctl(VIDIOC_CROPCAP, &cropcap) == 0 && - cropcap.bounds.width && cropcap.bounds.height; -} - -bool v4l2::has_compose() -{ - v4l2_selection sel; - - memset(&sel, 0, sizeof(sel)); - sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - sel.target = V4L2_SEL_TGT_COMPOSE; - return ioctl_exists(VIDIOC_G_SELECTION, &sel) && - ioctl_exists(VIDIOC_S_SELECTION, &sel); -} - -bool v4l2::input_has_compose() -{ - v4l2_selection sel; - - memset(&sel, 0, sizeof(sel)); - sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - sel.target = V4L2_SEL_TGT_COMPOSE; - return ioctl(VIDIOC_G_SELECTION, &sel) == 0 && - ioctl(VIDIOC_S_SELECTION, &sel) == 0; -} diff --git a/utils/qv4l2/v4l2-api.h b/utils/qv4l2/v4l2-api.h deleted file mode 100644 index ccbaabb..0000000 --- a/utils/qv4l2/v4l2-api.h +++ /dev/null @@ -1,128 +0,0 @@ -/* v4l2-api: low-level wrapper around v4l2 devices - * - * Copyright (C) 2009 Hans Verkuil - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef V4L2_API_H -#define V4L2_API_H - -#include -#include -#include - -class v4l2 -{ -public: - v4l2() : m_fd(-1) {} - v4l2(v4l2 &old) : - m_fd(old.m_fd), - m_device(old.m_device), - m_useWrapper(old.m_useWrapper), - m_capability(old.m_capability) - {} - - bool open(const QString &device, bool useWrapper = true); - void close(); - int read(unsigned char *p, int size); - int ioctl(unsigned cmd, void *arg); - bool ioctl(const QString &descr, unsigned cmd, void *arg); - bool ioctl_exists(unsigned cmd, void *arg); - void *mmap(size_t length, int64_t offset); - int munmap(void *_start, size_t length); - - inline int fd() const { return m_fd; } - inline bool useWrapper() const { return m_useWrapper; } - inline __u32 caps() const { - if (m_capability.capabilities & V4L2_CAP_DEVICE_CAPS) - return m_capability.device_caps; - return m_capability.capabilities; - } - inline const QString &device() const { return m_device; } - static QString pixfmt2s(unsigned pixelformat); - - virtual void error(const QString &text); - - bool querycap(v4l2_capability &cap); - bool queryctrl(v4l2_queryctrl &qc); - bool querymenu(v4l2_querymenu &qm); - bool g_tuner(v4l2_tuner &tuner, unsigned index = 0); - bool s_tuner(v4l2_tuner &tuner); - bool g_modulator(v4l2_modulator &modulator); - bool s_modulator(v4l2_modulator &modulator); - bool g_input(int &input); - bool s_input(int input); - bool g_output(int &output); - bool s_output(int output); - bool g_audio(v4l2_audio &audio); - bool s_audio(int input); - bool g_audout(v4l2_audioout &audout); - bool s_audout(int output); - bool s_std(v4l2_std_id std); - bool g_std(v4l2_std_id &std); - bool query_std(v4l2_std_id &std); - bool s_dv_timings(v4l2_dv_timings &timings); - bool g_dv_timings(v4l2_dv_timings &timings); - bool query_dv_timings(v4l2_dv_timings &timings); - bool g_frequency(v4l2_frequency &freq, unsigned index = 0); - bool s_frequency(v4l2_frequency &freq); - bool s_frequency(int freq, bool low = false); - bool g_fmt(unsigned type, v4l2_format &fmt); - bool g_fmt_vbi(v4l2_format &fmt); - bool g_fmt_sliced_vbi(v4l2_format &fmt); - bool try_fmt(v4l2_format &fmt); - bool s_fmt(v4l2_format &fmt); - bool enum_input(v4l2_input &in, bool init = false, int index = 0); - bool enum_output(v4l2_output &out, bool init = false, int index = 0); - bool enum_audio(v4l2_audio &audio, bool init = false); - bool enum_audout(v4l2_audioout &audout, bool init = false); - bool enum_std(v4l2_standard &std, bool init = false, int index = 0); - bool enum_dv_timings(v4l2_enum_dv_timings &timings, bool init = false, int index = 0); - bool enum_fmt(v4l2_fmtdesc &std, unsigned type, bool init = false, int index = 0); - bool enum_framesizes(v4l2_frmsizeenum &frm, __u32 init_pixfmt = 0, int index = 0); - bool enum_frameintervals(v4l2_frmivalenum &frm, __u32 init_pixfmt = 0, __u32 w = 0, __u32 h = 0, int index = 0); - - bool reqbufs_mmap(v4l2_requestbuffers &reqbuf, __u32 buftype, int count = 0); - bool reqbufs_user(v4l2_requestbuffers &reqbuf, __u32 buftype, int count = 0); - bool dqbuf_mmap(v4l2_buffer &buf, __u32 buftype, bool &again); - bool dqbuf_user(v4l2_buffer &buf, __u32 buftype, bool &again); - bool qbuf(v4l2_buffer &buf); - bool qbuf_mmap(int index, __u32 buftype); - bool qbuf_user(int index, __u32 buftype, void *ptr[], size_t length[]); - bool streamon(__u32 buftype); - bool streamoff(__u32 buftype); - v4l2_fract g_pixel_aspect(unsigned type, unsigned &width, unsigned &height); - bool has_crop(); - bool input_has_crop(); - bool has_compose(); - bool input_has_compose(); - - bool subscribe_event(v4l2_event_subscription &sub); - bool dqevent(v4l2_event &ev); - - bool set_interval(unsigned type, v4l2_fract interval); - bool get_interval(unsigned type, v4l2_fract &interval); -private: - void clear() { error(QString()); } - -private: - int m_fd; - QString m_device; - bool m_useWrapper; // true if using the libv4l2 wrappers - v4l2_capability m_capability; -}; - -#endif diff --git a/utils/qv4l2/vbi-tab.h b/utils/qv4l2/vbi-tab.h index 4ad730f..2eecac6 100644 --- a/utils/qv4l2/vbi-tab.h +++ b/utils/qv4l2/vbi-tab.h @@ -22,7 +22,6 @@ #define VBI_TAB_H #include "qv4l2.h" -#include "v4l2-api.h" class QTableWidget;