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; }
GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) : QGridLayout(parent), v4l2(fd), m_row(0), m_col(0), m_cols(n), m_audioInput(NULL), m_tvStandard(NULL), m_videoPreset(NULL), m_freq(NULL), m_vidCapFormats(NULL), m_frameSize(NULL), m_vidOutFormats(NULL) { setSpacing(3); setSizeConstraint(QLayout::SetMinimumSize); if (querycap(m_querycap)) { addLabel("Device:"); addLabel(device + (useWrapper() ? " (wrapped)" : ""), Qt::AlignLeft); addLabel("Driver:"); addLabel((char *)m_querycap.driver, Qt::AlignLeft); addLabel("Card:"); addLabel((char *)m_querycap.card, Qt::AlignLeft); addLabel("Bus:"); addLabel((char *)m_querycap.bus_info, Qt::AlignLeft); } g_tuner(m_tuner); v4l2_standard vs; if (enum_std(vs, true)) { addLabel("TV Standard"); m_tvStandard = new QComboBox(parent); do { m_tvStandard->addItem((char *)vs.name); } while (enum_std(vs)); addWidget(m_tvStandard); connect(m_tvStandard, SIGNAL(activated(int)), SLOT(standardChanged(int))); updateStandard(); } v4l2_dv_enum_preset preset; if (enum_dv_preset(preset, true)) { addLabel("Video Preset"); m_videoPreset = new QComboBox(parent); do { m_videoPreset->addItem((char *)preset.name); } while (enum_dv_preset(preset)); addWidget(m_videoPreset); connect(m_videoPreset, SIGNAL(activated(int)), SLOT(presetChanged(int))); updatePreset(); } v4l2_input vin; if (enum_input(vin, true)) { addLabel("Input"); m_videoInput = new QComboBox(parent); do { m_videoInput->addItem((char *)vin.name); } while (enum_input(vin)); addWidget(m_videoInput); connect(m_videoInput, SIGNAL(activated(int)), SLOT(inputChanged(int))); updateVideoInput(); } v4l2_output vout; if (enum_output(vout, true)) { addLabel("Output"); m_videoOutput = new QComboBox(parent); do { m_videoOutput->addItem((char *)vout.name); } while (enum_output(vout)); addWidget(m_videoOutput); connect(m_videoOutput, SIGNAL(activated(int)), SLOT(outputChanged(int))); updateVideoOutput(); } v4l2_audio vaudio; if (enum_audio(vaudio, true)) { addLabel("Input Audio"); m_audioInput = new QComboBox(parent); do { m_audioInput->addItem((char *)vaudio.name); } while (enum_audio(vaudio)); addWidget(m_audioInput); connect(m_audioInput, SIGNAL(activated(int)), SLOT(inputAudioChanged(int))); updateAudioInput(); } v4l2_audioout vaudout; if (enum_audout(vaudout, true)) { addLabel("Output Audio"); m_audioOutput = new QComboBox(parent); do { m_audioOutput->addItem((char *)vaudout.name); } while (enum_audout(vaudout)); addWidget(m_audioOutput); connect(m_audioOutput, SIGNAL(activated(int)), SLOT(outputAudioChanged(int))); updateAudioOutput(); } if (m_tuner.type) { m_freq = new QSpinBox(parent); m_freq->setMinimum(m_tuner.rangelow); m_freq->setMaximum(m_tuner.rangehigh); m_freq->setWhatsThis(QString("Frequency\nLow: %1\nHigh: %2") .arg(m_tuner.rangelow).arg(m_tuner.rangehigh)); connect(m_freq, SIGNAL(valueChanged(int)), SLOT(freqChanged(int))); updateFreq(); addLabel("Frequency"); addWidget(m_freq); addLabel("Frequency Table"); m_freqTable = new QComboBox(parent); for (int i = 0; v4l2_channel_lists[i].name; i++) { m_freqTable->addItem(v4l2_channel_lists[i].name); } addWidget(m_freqTable); connect(m_freqTable, SIGNAL(activated(int)), SLOT(freqTableChanged(int))); addLabel("Channels"); m_freqChannel = new QComboBox(parent); m_freqChannel->setSizeAdjustPolicy(QComboBox::AdjustToContents); addWidget(m_freqChannel); connect(m_freqChannel, SIGNAL(activated(int)), SLOT(freqChannelChanged(int))); updateFreqChannel(); } v4l2_fmtdesc fmt; addLabel("Capture Image Formats"); m_vidCapFormats = new QComboBox(parent); if (enum_fmt_cap(fmt, true)) { do { m_vidCapFormats->addItem(pixfmt2s(fmt.pixelformat) + " - " + (const char *)fmt.description); } while (enum_fmt_cap(fmt)); } addWidget(m_vidCapFormats); connect(m_vidCapFormats, SIGNAL(activated(int)), SLOT(vidCapFormatChanged(int))); addLabel("Frame Width"); m_frameWidth = new QSpinBox(parent); addWidget(m_frameWidth); connect(m_frameWidth, SIGNAL(editingFinished()), SLOT(frameWidthChanged())); addLabel("Frame Height"); m_frameHeight = new QSpinBox(parent); addWidget(m_frameHeight); connect(m_frameHeight, SIGNAL(editingFinished()), SLOT(frameHeightChanged())); addLabel("Frame Size"); m_frameSize = new QComboBox(parent); m_frameSize->setSizeAdjustPolicy(QComboBox::AdjustToContents); addWidget(m_frameSize); connect(m_frameSize, SIGNAL(activated(int)), SLOT(frameSizeChanged(int))); addLabel("Frame Interval"); m_frameInterval = new QComboBox(parent); m_frameInterval->setSizeAdjustPolicy(QComboBox::AdjustToContents); addWidget(m_frameInterval); connect(m_frameInterval, SIGNAL(activated(int)), SLOT(frameIntervalChanged(int))); updateVidCapFormat(); if (caps() & V4L2_CAP_VIDEO_OUTPUT) { addLabel("Output Image Formats"); m_vidOutFormats = new QComboBox(parent); if (enum_fmt_out(fmt, true)) { do { m_vidOutFormats->addItem(pixfmt2s(fmt.pixelformat) + " - " + (const char *)fmt.description); } while (enum_fmt_out(fmt)); } addWidget(m_vidOutFormats); connect(m_vidOutFormats, SIGNAL(activated(int)), SLOT(vidOutFormatChanged(int))); } addLabel("Capture Method"); m_capMethods = new QComboBox(parent); if (m_querycap.capabilities & V4L2_CAP_STREAMING) { v4l2_requestbuffers reqbuf; // Yuck. The videobuf framework does not accept a 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_cap(reqbuf, 1)) { m_capMethods->addItem("User pointer I/O", QVariant(methodUser)); reqbufs_user_cap(reqbuf, 0); } if (reqbufs_mmap_cap(reqbuf, 1)) { m_capMethods->addItem("Memory mapped I/O", QVariant(methodMmap)); reqbufs_mmap_cap(reqbuf, 0); } } if (m_querycap.capabilities & V4L2_CAP_READWRITE) { m_capMethods->addItem("read()", QVariant(methodRead)); } addWidget(m_capMethods); QGridLayout::addWidget(new QWidget(parent), rowCount(), 0, 1, n); setRowStretch(rowCount() - 1, 1); }
/* ** Push all values of the current capture into the stack; returns ** number of values pushed */ static int pushcapture (CapState *cs) { lua_State *L = cs->L; luaL_checkstack(L, 4, "too many captures"); switch (captype(cs->cap)) { case Cposition: { lua_pushinteger(L, cs->cap->s - cs->s + 1); cs->cap++; return 1; } case Cconst: { pushluaval(cs); cs->cap++; return 1; } case Carg: { int arg = (cs->cap++)->idx; if (arg + FIXEDARGS > cs->ptop) return luaL_error(L, "reference to absent extra argument #%d", arg); lua_pushvalue(L, arg + FIXEDARGS); return 1; } case Csimple: { int k = pushnestedvalues(cs, 1); lua_insert(L, -k); /* make whole match be first result */ return k; } case Cruntime: { lua_pushvalue(L, (cs->cap++)->idx); /* value is in the stack */ return 1; } case Cstring: { luaL_Buffer b; luaL_buffinit(L, &b); stringcap(&b, cs); luaL_pushresult(&b); return 1; } case Csubst: { luaL_Buffer b; luaL_buffinit(L, &b); substcap(&b, cs); luaL_pushresult(&b); return 1; } case Cgroup: { if (cs->cap->idx == 0) /* anonymous group? */ return pushnestedvalues(cs, 0); /* add all nested values */ else { /* named group: add no values */ nextcap(cs); /* skip capture */ return 0; } } case Cbackref: return backrefcap(cs); case Ctable: return tablecap(cs); case Cfunction: return functioncap(cs); case Cnum: return numcap(cs); case Cquery: return querycap(cs); case Cfold: return foldcap(cs); default: assert(0); return 0; } }