]> git.sesse.net Git - kdenlive/commitdiff
Report dropped frame on decklink capture
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 28 May 2011 19:37:56 +0000 (19:37 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sat, 28 May 2011 19:37:56 +0000 (19:37 +0000)
svn path=/trunk/kdenlive/; revision=5613

src/kdenlivesettings.kcfg
src/mltdevicecapture.cpp
src/mltdevicecapture.h
src/recmonitor.cpp
src/recmonitor.h
src/widgets/recmonitor_ui.ui

index bac9fb88ff6fdd9eab2757affb3f42563f7bf99b..c9116df57af1b929e606f7095dc82e375adeddde 100644 (file)
   
   <entry name="decklink_parameters" type="String">
       <label>Default Decklink encoding parameters.</label>
-      <default>vcodec=mpeg2video minrate=0 b=12000k acodec=mp2 ab=128k ar=48000 threads=2</default>
+      <default>vcodec=mpeg2video b=12000k minrate=0 pix_fmt=yuv420p g=15 acodec=mp2 ac=2 ab=128k ar=48000 threads=%threads</default>
   </entry>
 
   <entry name="decklink_extension" type="String">
index 172dd4326bd94ac266c433b9ffbdc4378281a5a7..99a697917249ab35da6a194d0d30a42d0e5eb514 100644 (file)
@@ -35,6 +35,7 @@
 #include <QDir>
 #include <QString>
 #include <QApplication>
+#include <QThread>
 
 #include <cstdlib>
 #include <cstdarg>
@@ -88,6 +89,8 @@ MltDeviceCapture::MltDeviceCapture(QString profile, VideoPreviewContainer *surfa
     m_mltConsumer(NULL),
     m_mltProducer(NULL),
     m_mltProfile(NULL),
+    m_droppedFrames(0),
+    m_livePreview(true),
     m_captureDisplayWidget(surface),
     m_winid((int) surface->winId()),
     m_analyseAudio(KdenliveSettings::monitor_audio())
@@ -301,6 +304,14 @@ bool MltDeviceCapture::slotStartPreview(const QString &producer, bool xmlFormat)
 
 void MltDeviceCapture::gotCapturedFrame(Mlt::Frame& frame)
 {
+    if (m_mltProducer) {
+        int dropped = m_mltProducer->get_int("dropped");
+        if (dropped != m_droppedFrames) {
+            m_droppedFrames = dropped;
+            emit droppedFrames(m_droppedFrames);
+        }
+    }
+    if (!m_livePreview) return;
     mlt_image_format format = mlt_image_rgb24a;
     int width = 0;
     int height = 0;
@@ -347,9 +358,11 @@ void MltDeviceCapture::captureFrame(const QString &path)
     doCapture = 5;
 }
 
-bool MltDeviceCapture::slotStartCapture(const QString &params, const QString &path, const QString &playlist, bool xmlPlaylist)
+bool MltDeviceCapture::slotStartCapture(const QString &params, const QString &path, const QString &playlist, bool livePreview, bool xmlPlaylist)
 {
     stop();
+    m_livePreview = livePreview;
+    m_droppedFrames = 0;
     if (m_mltProfile) delete m_mltProfile;
     char *tmp = qstrdup(m_activeProfile.toUtf8().constData());
     m_mltProfile = new Mlt::Profile(tmp);
@@ -365,7 +378,9 @@ bool MltDeviceCapture::slotStartCapture(const QString &params, const QString &pa
     char *tmp2;
     for (int i = 0; i < paramList.count(); i++) {
         tmp = qstrdup(paramList.at(i).section("=", 0, 0).toUtf8().constData());
-        tmp2 = qstrdup(paramList.at(i).section("=", 1, 1).toUtf8().constData());
+        QString value = paramList.at(i).section("=", 1, 1);
+        if (value == "%threads") value = QString::number(QThread::idealThreadCount());
+        tmp2 = qstrdup(value.toUtf8().constData());
         m_mltConsumer->set(tmp, tmp2);
         delete[] tmp;
         delete[] tmp2;
index 158b71597e1f6898f59053dce2df7e294fc2bff3..2a332bf96a37a4f2288cd8eabfce0b585c006930 100644 (file)
@@ -76,7 +76,7 @@ Q_OBJECT public:
     /** @brief Starts the MLT Video4Linux process.
      * @param surface The widget onto which the frame should be painted
      */
-    bool slotStartCapture(const QString &params, const QString &path, const QString &playlist, bool xmlPlaylist = true);
+    bool slotStartCapture(const QString &params, const QString &path, const QString &playlist, bool livePreview, bool xmlPlaylist = true);
     bool slotStartPreview(const QString &producer, bool xmlFormat = false);
     /** @brief A frame arrived from the MLT Video4Linux process. */
     void gotCapturedFrame(Mlt::Frame& frame);
@@ -97,6 +97,8 @@ private:
     Mlt::Producer * m_mltProducer;
     Mlt::Profile *m_mltProfile;
     QString m_activeProfile;
+    int m_droppedFrames;
+    bool m_livePreview;
 
     /** @brief The surface onto which the captured frames should be painted. */
     VideoPreviewContainer *m_captureDisplayWidget;
@@ -125,6 +127,8 @@ signals:
     void audioSamplesSignal(const QVector<int16_t>&, int freq, int num_channels, int num_samples);
 
     void frameSaved(const QString);
+    
+    void droppedFrames(int);
 
 public slots:
 
index 8149d5d1bcbc6c3ff91570f51630f31354d019bd..a3f92948a2595f3ca51bf61b09f6dd5ed200803b 100644 (file)
@@ -240,7 +240,6 @@ void RecMonitor::slotVideoDeviceChanged(int ix)
         checkDeviceAvailability();
         break;
     case BLACKMAGIC:
-        //createBlackmagicDevice();
         m_recAction->setEnabled(true);
         m_stopAction->setEnabled(false);
         m_playAction->setEnabled(true);
@@ -292,24 +291,12 @@ void RecMonitor::slotVideoDeviceChanged(int ix)
     }
 }
 
-void RecMonitor::createBlackmagicDevice()
-{
-    //video_capture->setVisible(true);
-    if (m_bmCapture == NULL) {
-        QVBoxLayout *lay = new QVBoxLayout;
-        m_bmCapture = new BmdCaptureHandler(lay);
-        connect(m_bmCapture, SIGNAL(gotTimeCode(ulong)), this, SLOT(slotGotBlackMagicFrameNumber(ulong)));
-        connect(m_bmCapture, SIGNAL(gotMessage(const QString &)), this, SLOT(slotGotBlackmagicMessage(const QString &)));
-        video_capture->setLayout(lay);
-    }
-}
-
 void RecMonitor::slotGotBlackmagicFrameNumber(ulong ix)
 {
     m_dvinfo.setText(QString::number(ix));
 }
 
-void RecMonitor::slotGotBlackmagicMessage(const QString &message)
+void RecMonitor::slotSetInfoMessage(const QString &message)
 {
     m_logger.insertItem(0, message);
 }
@@ -488,6 +475,7 @@ void RecMonitor::slotStartCapture(bool play)
         m_manager->activateMonitor("record");
         if (m_captureDevice == NULL) {
             m_captureDevice = new MltDeviceCapture(path, m_videoBox, this);
+            connect(m_captureDevice, SIGNAL(droppedFrames(int)), this, SLOT(slotDroppedFrames(int)));
             m_captureDevice->sendFrameForAnalysis = m_analyse;
             m_manager->updateScopeSource();
         }
@@ -551,26 +539,11 @@ void RecMonitor::slotStartCapture(bool play)
 
 void RecMonitor::slotRecord()
 {
-    /*if (device_selector->currentIndex() == BLACKMAGIC) {
-        if (m_blackmagicCapturing) {
-            // We are capturing, stop it
-            m_bmCapture->stopCapture();
-            m_blackmagicCapturing = false;
-        } else {
-            // Start capture, get capture filename first
-            QString path = m_capturePath;
-            if (!path.endsWith("/")) path.append("/");
-            path.append(KdenliveSettings::hdmifilename());
-            m_bmCapture->startCapture(path);
-            m_blackmagicCapturing = true;
-        }
-        return;
-    }*/
-
     if (m_captureProcess->state() == QProcess::NotRunning && device_selector->currentIndex() == FIREWIRE) {
         slotStartCapture();
     }
     if (m_isCapturing) {
+        // User stopped capture
         switch (device_selector->currentIndex()) {
         case FIREWIRE:
             m_captureProcess->write("\e", 2);
@@ -582,6 +555,7 @@ void RecMonitor::slotRecord()
         case VIDEO4LINUX:
         case BLACKMAGIC:
             slotStopCapture();
+            slotSetInfoMessage(i18n("Capture stopped"));
             m_isCapturing = false;
             m_recAction->setChecked(false);
             if (autoaddbox->isChecked() && QFile::exists(m_captureFile.path())) emit addProjectClip(m_captureFile);
@@ -657,7 +631,7 @@ void RecMonitor::slotRecord()
 
             playlist.append("</tractor></mlt>");
 
-            if (m_captureDevice->slotStartCapture(KdenliveSettings::v4l_parameters(), m_captureFile.path(), playlist)) {
+            if (m_captureDevice->slotStartCapture(KdenliveSettings::v4l_parameters(), m_captureFile.path(), playlist, enable_preview->isChecked())) {
                 m_videoBox->setHidden(false);
                 m_isCapturing = true;
             }
@@ -681,18 +655,21 @@ void RecMonitor::slotRecord()
             profile = ProfilesDialog::getVideoProfile(path);
             if (m_captureDevice == NULL) {
                 m_captureDevice = new MltDeviceCapture(path, m_videoBox, this);
+                connect(m_captureDevice, SIGNAL(droppedFrames(int)), this, SLOT(slotDroppedFrames(int)));
                 m_captureDevice->sendFrameForAnalysis = m_analyse;
                 m_manager->updateScopeSource();
             }
                
             playlist = QString("<producer id=\"producer0\" in=\"0\" out=\"99999\"><property name=\"mlt_type\">producer</property><property name=\"length\">100000</property><property name=\"eof\">pause</property><property name=\"resource\">%1</property><property name=\"mlt_service\">decklink</property></producer>").arg(KdenliveSettings::decklink_capturedevice());
 
-            if (m_captureDevice->slotStartCapture(KdenliveSettings::decklink_parameters(), m_captureFile.path(), QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()), false)) {
+            if (m_captureDevice->slotStartCapture(KdenliveSettings::decklink_parameters(), m_captureFile.path(), QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()), enable_preview->isChecked(), false)) {
                 m_videoBox->setHidden(false);
                 m_isCapturing = true;
+                slotSetInfoMessage(i18n("Capturing to %1", m_captureFile.fileName()));
             }
             else {
-                video_frame->setText(i18n("Failed to start Decklink,\ncheck your parameters..."));                
+                video_frame->setText(i18n("Failed to start Decklink,\ncheck your parameters..."));
+                slotSetInfoMessage(i18n("Failed to start capture"));
                 m_videoBox->setHidden(true);
                 m_isCapturing = false;
                 m_recAction->setChecked(false);
@@ -937,6 +914,10 @@ void RecMonitor::analyseFrames(bool analyse)
     if (m_captureDevice) m_captureDevice->sendFrameForAnalysis = analyse;
 }
 
+void RecMonitor::slotDroppedFrames(int dropped)
+{
+    slotSetInfoMessage(i18n("%1 dropped frames", dropped));
+}
 
 #include "recmonitor.moc"
 
index c61b8041f6eb2dc8c3f88ac3a1e42d116a6d6773..5cfa920e8b2ec10f7ce6e5123bc14ac5234f67d1 100644 (file)
@@ -112,7 +112,6 @@ private:
     void checkDeviceAvailability();
     QPixmap mergeSideBySide(const QPixmap& pix, const QString txt);
     void manageCapturedFiles();
-    void createBlackmagicDevice();
 
 private slots:
     void slotStartCapture(bool play = true);
@@ -127,7 +126,8 @@ private slots:
     void slotReadDvgrabInfo();
     void slotUpdateFreeSpace();
     void slotGotBlackmagicFrameNumber(ulong ix);
-    void slotGotBlackmagicMessage(const QString &message);
+    void slotSetInfoMessage(const QString &message);
+    void slotDroppedFrames(int dropped);
 
 public slots:
     void refreshRecMonitor(bool visible);
index 7a2a4c31b2de5be697d0201920e27a4ea0d3c6d2..7393bb8047b27d55125a012a3a1320b31eac873f 100644 (file)
@@ -6,15 +6,15 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>210</width>
-    <height>152</height>
+    <width>371</width>
+    <height>186</height>
    </rect>
   </property>
   <layout class="QGridLayout" name="gridLayout">
    <property name="margin">
     <number>0</number>
    </property>
-   <item row="0" column="0" colspan="3">
+   <item row="0" column="0" colspan="4">
     <widget class="QFrame" name="video_capture">
      <property name="frameShape">
       <enum>QFrame::NoFrame</enum>
@@ -27,7 +27,7 @@
      </property>
     </widget>
    </item>
-   <item row="1" column="0" colspan="3">
+   <item row="1" column="0" colspan="4">
     <widget class="QLabel" name="video_frame">
      <property name="text">
       <string>Not connected</string>
@@ -37,7 +37,7 @@
      </property>
     </widget>
    </item>
-   <item row="2" column="0" colspan="3">
+   <item row="2" column="0" colspan="4">
     <widget class="QFrame" name="control_frame_firewire">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
@@ -69,7 +69,7 @@
      </property>
     </widget>
    </item>
-   <item row="3" column="2">
+   <item row="3" column="3">
     <widget class="KComboBox" name="device_selector">
      <item>
       <property name="text">
      </item>
     </widget>
    </item>
+   <item row="3" column="1">
+    <widget class="QCheckBox" name="enable_preview">
+     <property name="text">
+      <string>Preview while capturing</string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="2">
+    <spacer name="horizontalSpacer">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>40</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
   </layout>
  </widget>
  <customwidgets>