diff --git a/src/v4l2sinkproperties.cpp b/src/v4l2sinkproperties.cpp index 22f334e..d2d0d7c 100644 --- a/src/v4l2sinkproperties.cpp +++ b/src/v4l2sinkproperties.cpp @@ -18,6 +18,12 @@ #include #include +#include +#include +#include +#include +#include + V4l2sinkProperties::V4l2sinkProperties(QWidget *parent) : QDialog(parent), ui(new Ui::V4l2sinkProperties) @@ -35,9 +41,17 @@ V4l2sinkProperties::V4l2sinkProperties(QWidget *parent) : const char* device = config_get_string(config, "V4l2sink", "DevicePath"); const char* format = config_get_string(config, "V4l2sink", "Format"); + init_devices(device); + ui->checkBox_auto->setChecked(autostart); - ui->lineEdit_dev->setText(device); - + + QMapIterator i(devices); + while (i.hasNext()) { + i.next(); + ui->comboBox_device->addItem(i.value(), i.key()); + } + ui->comboBox_device->setCurrentIndex(ui->comboBox_device->findData(device)); + ui->comboBox_format->addItem(V4L2SINK_YUV420, V4L2SINK_YUV420); ui->comboBox_format->addItem(V4L2SINK_NV12, V4L2SINK_NV12); ui->comboBox_format->addItem(V4L2SINK_YUY2, V4L2SINK_YUY2); @@ -60,6 +74,63 @@ V4l2sinkProperties::~V4l2sinkProperties() delete ui; } +void V4l2sinkProperties::init_devices(const char* device) +{ + QDir dir("/sys/class/video4linux"); + dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + dir.setSorting(QDir::Name); + QFileInfoList list = dir.entryInfoList(); + + for (int i = 0; i < list.size(); ++i) { + int fd; + uint32_t caps; + struct v4l2_capability video_cap; + + QFileInfo fileInfo = list.at(i); + QString fileName = fileInfo.fileName(); + + if (!fileName.startsWith("video")) + continue; + QString devPath = QString("/dev/%1").arg(fileName); + + if ((fd = ::open(devPath.toLatin1(), O_RDWR | O_NONBLOCK)) == -1) { + continue; + } + + if (::ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1) { + ::close(fd); + continue; + } + + if (video_cap.capabilities & V4L2_CAP_DEVICE_CAPS) { + caps = video_cap.device_caps; + } else { + caps = video_cap.capabilities; + } + + if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { + ::close(fd); + continue; + } + + if (strcmp((char*) video_cap.driver, "v4l2 loopback") != 0) { + ::close(fd); + continue; + } + + /* make sure device names are unique */ + char dev_name[68]; + sprintf(dev_name, "%s (%s)", video_cap.card, video_cap.bus_info); + devices.insert(devPath, QString::fromLocal8Bit(dev_name)); + ::close(fd); + } + + QString cur_device = QString::fromLocal8Bit(device); + if (!devices.contains(cur_device)) { + devices.remove(cur_device); + } +} + void V4l2sinkProperties::closeEvent(QCloseEvent *event) { saveSettings(); @@ -68,7 +139,7 @@ void V4l2sinkProperties::closeEvent(QCloseEvent *event) void V4l2sinkProperties::saveSettings() { bool autostart = ui->checkBox_auto->isChecked(); - QByteArray ba_dev_name = ui->lineEdit_dev->text().toUtf8(); + QByteArray ba_dev_name = ui->comboBox_device->currentData().toString().toUtf8(); QByteArray ba_format = ui->comboBox_format->currentData().toString(). toUtf8(); config_t* config = obs_frontend_get_global_config(); @@ -85,7 +156,7 @@ void V4l2sinkProperties::onStart() { QByteArray ba_format = ui->comboBox_format->currentData().toString() .toUtf8(); - QByteArray ba_dev_name = ui->lineEdit_dev->text().toUtf8(); + QByteArray ba_dev_name = ui->comboBox_device->currentData().toString().toUtf8(); signal_handler_t *handler = v4l2sink_get_signal_handler(); signal_handler_connect(handler, "v4l2close", output_stopped , this); enableStart(false); diff --git a/src/v4l2sinkproperties.h b/src/v4l2sinkproperties.h index 5c8dab4..42d6cfc 100644 --- a/src/v4l2sinkproperties.h +++ b/src/v4l2sinkproperties.h @@ -17,6 +17,8 @@ #define V4L2SINKPROPERTIES_H #include +#include +#include #include "v4l2sink.h" #define V4L2SINK_NV12 "NV12" @@ -46,7 +48,9 @@ private Q_SLOTS: void onStop(); private: + void init_devices(const char* device); Ui::V4l2sinkProperties *ui; + QMap devices; }; static void output_started(void *data, calldata_t *cd); diff --git a/src/v4l2sinkproperties.ui b/src/v4l2sinkproperties.ui index 8d6b290..dc9941e 100644 --- a/src/v4l2sinkproperties.ui +++ b/src/v4l2sinkproperties.ui @@ -79,11 +79,7 @@ - - - /dev/video0 - - +