]> git.sesse.net Git - kdenlive/commitdiff
Basic webcam (video4linux) autodetection
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 26 Oct 2010 20:42:55 +0000 (20:42 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 26 Oct 2010 20:42:55 +0000 (20:42 +0000)
svn path=/trunk/kdenlive/; revision=5053

14 files changed:
src/CMakeLists.txt
src/blackmagic/capture.cpp
src/blackmagic/capture.h
src/kdenlivesettingsdialog.cpp
src/stopmotion/capturehandler.h
src/stopmotion/stopmotion.cpp
src/v4l/src.c
src/v4l/src.h
src/v4l/src_v4l2.c
src/v4l/v4lcapture.cpp
src/v4l/v4lcapture.h
src/widgets/wizardcapture_ui.ui [new file with mode: 0644]
src/wizard.cpp
src/wizard.h

index 5d0ecb12352f7773810e63f7fe7063364a77bfdb..5166e0d3122315c4d2facd2fe661274a640d8091 100644 (file)
@@ -89,6 +89,7 @@ kde4_add_ui_files(kdenlive_UI
   widgets/geometryval_ui.ui
   widgets/wizardstandard_ui.ui
   widgets/wizardextra_ui.ui
+  widgets/wizardcapture_ui.ui
   widgets/wizardcheck_ui.ui
   widgets/wizardmltcheck_ui.ui
   widgets/spacerdialog_ui.ui
index 8afb4d25aede8fd4b89b558fdb6c3396ab8936d9..cb953b824c54ffe707d310d33121699cad9f1c97 100644 (file)
@@ -492,7 +492,7 @@ BmdCaptureHandler::BmdCaptureHandler(QVBoxLayout *lay, QWidget *parent):
 {
 }
 
-QString BmdCaptureHandler::getDeviceName(QString)
+QString BmdCaptureHandler::getDeviceName(QString, int *, int *)
 {
     return QString();
 }
index b58b40c1383ce11be798cb5c265394bbf2e20a65..db716c80c505be26c088a7b148ee2a53e505d0fc 100644 (file)
@@ -59,7 +59,7 @@ public:
     void showOverlay(QImage img, bool transparent = true);
     void hideOverlay();
     void hidePreview(bool hide);
-    QString getDeviceName(QString);
+    QString getDeviceName(QString, int *, int *);
 
 private:
     IDeckLinkIterator       *deckLinkIterator;
index 97861f63287184c6be6bdbb74cac207d2eeb8c22..f17c9f75d5f3ddd5cea4ede6a0077626efa67dcf 100644 (file)
@@ -83,11 +83,15 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(QWidget * parent) :
     m_configCapture.setupUi(p4);
 
     V4lCaptureHandler v4l(NULL);
+    int width;
+    int height;
     // Video 4 Linux device detection
     for (int i = 0; i < 10; i++) {
         QString path = "/dev/video" + QString::number(i);
         if (QFile::exists(path)) {
-            m_configCapture.kcfg_detectedv4ldevices->addItem(v4l.getDeviceName(path.toUtf8().constData()), path);
+            QString deviceName = v4l.getDeviceName(path.toUtf8().constData(), &width, &height);
+            m_configCapture.kcfg_detectedv4ldevices->addItem(deviceName, path);
+            if (width > 0) m_configCapture.kcfg_detectedv4ldevices->setItemData(m_configCapture.kcfg_detectedv4ldevices->count() - 1, QString("%1x%2").arg(width).arg(height), Qt::UserRole + 1);
         }
     }
     connect(m_configCapture.kcfg_detectedv4ldevices, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdatev4lDevice()));
@@ -642,6 +646,8 @@ void KdenliveSettingsDialog::slotUpdatev4lDevice()
 {
     QString device = m_configCapture.kcfg_detectedv4ldevices->itemData(m_configCapture.kcfg_detectedv4ldevices->currentIndex()).toString();
     if (!device.isEmpty()) m_configCapture.kcfg_video4vdevice->setText(device);
+    QString size = m_configCapture.kcfg_detectedv4ldevices->itemData(m_configCapture.kcfg_detectedv4ldevices->currentIndex(), Qt::UserRole + 1).toString();
+    if (!size.isEmpty()) m_configCapture.kcfg_video4size->setText(size);
 }
 
 
index c91a5d5ff555dcba4e874b6d3f391949e9889a10..f43fddae8b2d631e89d984d9f21ad9302f249db7 100644 (file)
@@ -38,7 +38,7 @@ public:
     virtual void showOverlay(QImage img, bool transparent = true) = 0;
     virtual void hideOverlay() = 0;
     virtual void hidePreview(bool hide) = 0;
-    virtual QString getDeviceName(QString input) = 0;
+    virtual QString getDeviceName(QString input, int *width, int *height) = 0;
     static void yuv2rgb(unsigned char *yuv_buffer, unsigned char *rgb_buffer, int width, int height);
 
 protected:
index 2094396e7bfca0b1145a8ad2fe68f330074cf5c0..e4e89f05470d37dbe1da8c86ccee7f92f2ab2449 100644 (file)
@@ -191,7 +191,7 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, const QList< QAction * >
     }
     if (QFile::exists(KdenliveSettings::video4vdevice())) {
         if (m_bmCapture == NULL) m_bmCapture = new V4lCaptureHandler(m_layout);
-        capture_device->addItem(m_bmCapture->getDeviceName(KdenliveSettings::video4vdevice()), "v4l");
+        capture_device->addItem(m_bmCapture->getDeviceName(KdenliveSettings::video4vdevice(), 0, 0), "v4l");
     }
 
     connect(m_bmCapture, SIGNAL(frameSaved(const QString)), this, SLOT(slotNewThumb(const QString)));
index 7aadb6cde4d6cadaea27c69b84b7b13094fb3649..96bb64cf5798cb5dd0dd8b54fe6b5c3084fc595f 100644 (file)
@@ -79,10 +79,10 @@ int src_open(src_t *src, char *source)
        return 0;
 }
 
-const char *src_query(src_t *src, char *source)
+const char *src_query(src_t *src, char *source, int *width, int *height)
 {
     src->source = source;
-    return src_v4l2.query(src);
+    return src_v4l2.query(src, width, height);
 }
 
 int src_close(src_t *src)
index 5f9aba54661f62f73fb410e7a5f66adb55e09764..011a95191b861a0f2f20b9a46773632d05612b58 100644 (file)
@@ -119,7 +119,7 @@ typedef struct {
        int (*open)(src_t *);
        int (*close)(src_t *);
        int (*grab)(src_t *);
-       const char *(*query)(src_t *);
+       const char *(*query)(src_t *, int*, int*);
        
 } src_mod_t;
 
@@ -207,7 +207,7 @@ typedef struct {
 extern int src_open(src_t *src, char *source);
 extern int src_close(src_t *src);
 extern int src_grab(src_t *src);
-extern const char *src_query(src_t *src, char *source);
+extern const char *src_query(src_t *src, char *source, int *width, int *height);
 
 extern int src_set_option(src_option_t ***options, char *name, char *value);
 extern int src_get_option_by_number(src_option_t **opt, int number, char **name, char **value);
index 56c4dbad0ae7e61caf1b7a676533174032fed9dc..641913f6bf230a333eb26eb11ff864d9ef053e5a 100644 (file)
@@ -802,7 +802,7 @@ int src_v4l2_set_read(src_t *src)
        return(0);
 }
 
-static const char *src_v4l2_query(src_t *src)
+static const char *src_v4l2_query(src_t *src, int *width, int *height)
 {
        if(!src->source)
        {
@@ -836,7 +836,24 @@ static const char *src_v4l2_query(src_t *src)
            fprintf(stderr, "Cannot get capabilities.");
            return NULL;
        }
-       char * res = (char*) s->cap.card;       
+       char * res = (char*) s->cap.card;
+       if(!s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
+           width = 0;
+           height = 0;
+       }
+       else {
+           struct v4l2_format format;
+           memset(&format,0,sizeof(format));
+            format.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+            if (ioctl(s->fd,VIDIOC_G_FMT,&format) < 0) {
+                fprintf(stderr, "Cannot get format.");
+            }
+            else {
+               *width = format.fmt.pix.width;
+               *height = format.fmt.pix.height;
+               fprintf(stderr, "Size: %d, %d.", width, height);
+           }
+       }
        src_v4l2_close(src);
        return res;
 }
index 8ede6e3fc426254256af8fd1ffb1c7fa56fb98e4..013a7c80c79dacc4b9b908b103a541afb78413cf 100644 (file)
@@ -96,7 +96,7 @@ V4lCaptureHandler::V4lCaptureHandler(QVBoxLayout *lay, QWidget *parent):
     lay->addWidget(m_display);
 }
 
-QString V4lCaptureHandler::getDeviceName(QString input)
+QString V4lCaptureHandler::getDeviceName(QString input, int *width, int *height)
 {
     fswebcam_config_t *config;
     /* Prepare the configuration structure. */
@@ -154,8 +154,7 @@ QString V4lCaptureHandler::getDeviceName(QString input)
     v4lsrc.fps        = config->fps;
     v4lsrc.option     = config->option;
     char *source = config->device;
-
-    QString deviceName = src_query(&v4lsrc, source);
+    QString deviceName = src_query(&v4lsrc, source, width, height);
     kDebug() << "DEVIE NAME: " << deviceName << ".";
     return deviceName.isEmpty() ? input : deviceName;
 }
index a1778b3b23da3ea673ebc5a3ea1a5bb5947ac973..ffa35b9358642135ad3c62b47a3811e88f8ec5d1 100644 (file)
@@ -44,7 +44,7 @@ public:
     void showOverlay(QImage img, bool transparent = true);
     void hideOverlay();
     void hidePreview(bool hide);
-    QString getDeviceName(QString input);
+    QString getDeviceName(QString input, int *width, int *height);
 
 private:
     bool m_update;
diff --git a/src/widgets/wizardcapture_ui.ui b/src/widgets/wizardcapture_ui.ui
new file mode 100644 (file)
index 0000000..0c151a6
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WizardCapture_UI</class>
+ <widget class="QWidget" name="WizardCapture_UI">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>273</width>
+    <height>153</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0" colspan="3">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Autodetected capture devices</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="3">
+    <widget class="QPushButton" name="button_reload">
+     <property name="text">
+      <string>Check</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0" colspan="4">
+    <widget class="QTreeWidget" name="device_list">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
+     <property name="allColumnsShowFocus">
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text">
+       <string>Device Name</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Capacities</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item row="3" column="1">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>1</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="2" column="0" colspan="4">
+    <widget class="QLabel" name="v4l_status">
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
index ea1084d580afad30f78ad1e54afff2528f314375..ad6a9e11061b81a77648189fe8a18cbab92dd23b 100644 (file)
@@ -20,6 +20,7 @@
 #include "wizard.h"
 #include "kdenlivesettings.h"
 #include "profilesdialog.h"
+#include "v4l/v4lcapture.h"
 #include "kdenlive-config.h"
 
 #include <KStandardDirs>
@@ -39,7 +40,7 @@ const double recommendedMltVersion = 510;
 static const char kdenlive_version[] = VERSION;
 
 Wizard::Wizard(bool upgrade, QWidget *parent) :
-        QWizard(parent)
+    QWizard(parent)
 {
     setWindowTitle(i18n("Config Wizard"));
     setPixmap(QWizard::WatermarkPixmap, QPixmap(KStandardDirs::locate("appdata", "banner.png")));
@@ -122,6 +123,15 @@ Wizard::Wizard(bool upgrade, QWidget *parent) :
     slotCheckThumbs();
     addPage(page3);
 
+    QWizardPage *page6 = new QWizardPage;
+    page6->setTitle(i18n("Webcam"));
+    m_capture.setupUi(page6);
+    connect(m_capture.button_reload, SIGNAL(clicked()), this, SLOT(slotDetectWebcam()));
+    connect(m_capture.device_list, SIGNAL(itemSelectionChanged()), this, SLOT(slotUpdateCaptureParameters()));
+    m_capture.button_reload->setIcon(KIcon("view-refresh"));
+
+    addPage(page6);
+
 
     QWizardPage *page5 = new QWizardPage;
     page5->setTitle(i18n("Checking system"));
@@ -130,10 +140,57 @@ Wizard::Wizard(bool upgrade, QWidget *parent) :
 
     listViewDelegate = new WizardDelegate(m_check.programList);
     m_check.programList->setItemDelegate(listViewDelegate);
-
+    slotDetectWebcam();
     QTimer::singleShot(500, this, SLOT(slotCheckMlt()));
 }
 
+void Wizard::slotDetectWebcam()
+{
+    m_capture.device_list->clear();
+
+    // Video 4 Linux device detection
+    V4lCaptureHandler v4l(NULL);
+    int width = 0;
+    int height = 0;
+    for (int i = 0; i < 10; i++) {
+        QString path = "/dev/video" + QString::number(i);
+        if (QFile::exists(path)) {
+            QString deviceName = v4l.getDeviceName(path.toUtf8().constData(), &width, &height);
+            QString captureSize;
+            if (width > 0) captureSize = QString::number(width) + "x" + QString::number(height);
+            if (!deviceName.isEmpty()) {
+                QTreeWidgetItem *item = new QTreeWidgetItem(m_capture.device_list, QStringList() << deviceName << captureSize);
+                item->setData(0, Qt::UserRole, path);
+                if (!captureSize.isEmpty()) item->setData(0, Qt::UserRole + 1, captureSize);
+            }
+        }
+    }
+    if (m_capture.device_list->topLevelItemCount() > 0) {
+        m_capture.v4l_status->setText(i18n("Select your default video4linux device"));
+        // select default device
+        bool found = false;
+        for (int i = 0; i < m_capture.device_list->topLevelItemCount(); i++) {
+            QTreeWidgetItem * item = m_capture.device_list->topLevelItem(i);
+            if (item && item->data(0, Qt::UserRole).toString() == KdenliveSettings::video4vdevice()) {
+                m_capture.device_list->setCurrentItem(item);
+                found = true;
+                break;
+            }
+        }
+        if (!found) m_capture.device_list->setCurrentItem(m_capture.device_list->topLevelItem(0));
+    } else m_capture.v4l_status->setText(i18n("No device found, plug your webcam and refresh."));
+}
+
+void Wizard::slotUpdateCaptureParameters()
+{
+    QTreeWidgetItem * item = m_capture.device_list->currentItem();
+    if (!item) return;
+    QString device = item->data(0, Qt::UserRole).toString();
+    if (!device.isEmpty()) KdenliveSettings::setVideo4vdevice(device);
+
+    QString size = item->data(0, Qt::UserRole + 1).toString();
+    if (!size.isEmpty()) KdenliveSettings::setVideo4size(size);
+}
 
 void Wizard::checkMltComponents()
 {
@@ -388,7 +445,7 @@ void Wizard::installExtraMimes(QString baseName, QStringList globs)
     } else {
         QStringList extensions = mime->patterns();
         QString comment = mime->comment();
-        foreach(const QString &glob, globs) {
+        foreach(const QString & glob, globs) {
             if (!extensions.contains(glob)) extensions << glob;
         }
         kDebug() << "EXTS: " << extensions;
@@ -415,7 +472,7 @@ void Wizard::installExtraMimes(QString baseName, QStringList globs)
             writer.writeEndElement(); // comment
         }
 
-        foreach(const QString& pattern, extensions) {
+        foreach(const QString & pattern, extensions) {
             writer.writeStartElement(nsUri, "glob");
             writer.writeAttribute("pattern", pattern);
             writer.writeEndElement(); // glob
index 633ba299eb2469996be7228b44074ce085f94c44..da2a551329df064093124830e3b7c33d49b02761 100644 (file)
@@ -33,6 +33,7 @@
 #include "ui_wizardextra_ui.h"
 #include "ui_wizardcheck_ui.h"
 #include "ui_wizardmltcheck_ui.h"
+#include "ui_wizardcapture_ui.h"
 
 class WizardDelegate: public QItemDelegate
 {
@@ -85,6 +86,7 @@ private:
     Ui::WizardStandard_UI m_standard;
     Ui::WizardExtra_UI m_extra;
     Ui::WizardMltCheck_UI m_mltCheck;
+    Ui::WizardCapture_UI m_capture;
     Ui::WizardCheck_UI m_check;
     QVBoxLayout *m_startLayout;
     bool m_systemCheckIsOk;
@@ -102,6 +104,8 @@ private slots:
     void slotCheckSelectedItem();
     void slotCheckMlt();
     void slotShowWebInfos();
+    void slotDetectWebcam();
+    void slotUpdateCaptureParameters();
 };
 
 #endif