[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdenlive/refactoring_timeline] src: Reintroduce Blackmagic external monitor support
From:       Jean-Baptiste Mardelle <null () kde ! org>
Date:       2018-09-14 8:31:23
Message-ID: E1g0jVb-0003Sn-Dd () code ! kde ! org
[Download RAW message or body]

Git commit 8a75aab84d70f716323a4d2e0c25d2d1e617d3f9 by Jean-Baptiste Mardelle.
Committed on 14/09/2018 at 08:31.
Pushed by mardelle into branch 'refactoring_timeline'.

Reintroduce Blackmagic external monitor support

M  +76   -10   src/dialogs/kdenlivesettingsdialog.cpp
M  +4    -1    src/dialogs/kdenlivesettingsdialog.h
M  +1    -0    src/mainwindow.cpp
M  +18   -2    src/monitor/glwidget.cpp
M  +2    -0    src/monitor/glwidget.h
M  +5    -0    src/monitor/monitor.cpp
M  +2    -0    src/monitor/monitor.h
M  +12   -0    src/monitor/monitormanager.cpp
M  +2    -0    src/monitor/monitormanager.h
M  +5    -0    src/project/projectmanager.cpp
M  +3    -0    src/project/projectmanager.h

https://commits.kde.org/kdenlive/8a75aab84d70f716323a4d2e0c25d2d1e617d3f9

diff --git a/src/dialogs/kdenlivesettingsdialog.cpp \
b/src/dialogs/kdenlivesettingsdialog.cpp index 60de2f553..634eb9b8b 100644
--- a/src/dialogs/kdenlivesettingsdialog.cpp
+++ b/src/dialogs/kdenlivesettingsdialog.cpp
@@ -345,8 +345,8 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(const \
QMap<QString, QString> &map  m_configSdl.kcfg_gpu_accel->setEnabled(gpuAllowed);
     m_configSdl.kcfg_gpu_accel->setToolTip(i18n("GPU processing needs MLT compiled \
with Movit and Rtaudio modules"));  
-    Render::getBlackMagicDeviceList(m_configCapture.kcfg_decklink_capturedevice);
-    if (!Render::getBlackMagicOutputDeviceList(m_configSdl.kcfg_blackmagic_output_device)) \
{ +    getBlackMagicDeviceList(m_configCapture.kcfg_decklink_capturedevice);
+    if (!getBlackMagicOutputDeviceList(m_configSdl.kcfg_blackmagic_output_device)) {
         // No blackmagic card found
         m_configSdl.kcfg_external_display->setEnabled(false);
     }
@@ -376,6 +376,62 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(const \
QMap<QString, QString> &map  }
 }
 
+//static
+bool KdenliveSettingsDialog::getBlackMagicDeviceList(KComboBox *devicelist, bool \
force) +{
+    if (!force && !KdenliveSettings::decklink_device_found()) {
+        return false;
+    }
+    Mlt::Profile profile;
+    Mlt::Producer bm(profile, "decklink");
+    int found_devices = 0;
+    if (bm.is_valid()) {
+        bm.set("list_devices", 1);
+        found_devices = bm.get_int("devices");
+    } else {
+        KdenliveSettings::setDecklink_device_found(false);
+    }
+    if (found_devices <= 0) {
+        devicelist->setEnabled(false);
+        return false;
+    }
+    KdenliveSettings::setDecklink_device_found(true);
+    for (int i = 0; i < found_devices; ++i) {
+        char *tmp = \
qstrdup(QStringLiteral("device.%1").arg(i).toUtf8().constData()); +        \
devicelist->addItem(bm.get(tmp)); +        delete[] tmp;
+    }
+    return true;
+}
+
+bool KdenliveSettingsDialog::getBlackMagicOutputDeviceList(KComboBox *devicelist, \
bool force) +{
+    if (!force && !KdenliveSettings::decklink_device_found()) {
+        return false;
+    }
+    Mlt::Profile profile;
+    Mlt::Consumer bm(profile, "decklink");
+    int found_devices = 0;
+    if (bm.is_valid()) {
+        bm.set("list_devices", 1);
+        found_devices = bm.get_int("devices");
+    } else {
+        KdenliveSettings::setDecklink_device_found(false);
+    }
+    if (found_devices <= 0) {
+        devicelist->setEnabled(false);
+        return false;
+    }
+    KdenliveSettings::setDecklink_device_found(true);
+    for (int i = 0; i < found_devices; ++i) {
+        char *tmp = \
qstrdup(QStringLiteral("device.%1").arg(i).toUtf8().constData()); +        \
devicelist->addItem(bm.get(tmp)); +        delete[] tmp;
+    }
+    devicelist->addItem(QStringLiteral("test"));
+    return true;
+}
+
 void KdenliveSettingsDialog::setupJogshuttleBtns(const QString &device)
 {
     QList<KComboBox *> list;
@@ -740,6 +796,8 @@ void KdenliveSettingsDialog::updateSettings()
     KdenliveSettings::setDefault_profile(m_pw->selectedProfile());
 
     bool resetProfile = false;
+    bool resetConsumer = false;
+    bool fullReset = false;
     bool updateCapturePath = false;
     bool updateLibrary = false;
 
@@ -850,13 +908,17 @@ void KdenliveSettingsDialog::updateSettings()
 
     if (m_configSdl.kcfg_external_display->isChecked() != \
                KdenliveSettings::external_display()) {
         KdenliveSettings::setExternal_display(m_configSdl.kcfg_external_display->isChecked());
                
-        resetProfile = true;
+        resetConsumer = true;
+        fullReset = true;
+    } else if (KdenliveSettings::external_display() && \
KdenliveSettings::blackmagic_output_device() != \
m_configSdl.kcfg_blackmagic_output_device->currentIndex()) { +        resetConsumer = \
true; +        fullReset = true;
     }
 
     value = m_configSdl.kcfg_audio_driver->itemData(m_configSdl.kcfg_audio_driver->currentIndex()).toString();
  if (value != KdenliveSettings::audiodrivername()) {
         KdenliveSettings::setAudiodrivername(value);
-        resetProfile = true;
+        resetConsumer = true;
     }
 
     if (value == QLatin1String("alsa")) {
@@ -864,17 +926,18 @@ void KdenliveSettingsDialog::updateSettings()
         value = m_configSdl.kcfg_audio_device->itemData(m_configSdl.kcfg_audio_device->currentIndex()).toString();
  if (value != KdenliveSettings::audiodevicename()) {
             KdenliveSettings::setAudiodevicename(value);
-            resetProfile = true;
+            resetConsumer = true;
         }
     } else if (!KdenliveSettings::audiodevicename().isEmpty()) {
         KdenliveSettings::setAudiodevicename(QString());
-        resetProfile = true;
+        resetConsumer = true;
     }
 
     value = m_configSdl.kcfg_audio_backend->itemData(m_configSdl.kcfg_audio_backend->currentIndex()).toString();
  if (value != KdenliveSettings::audiobackend()) {
         KdenliveSettings::setAudiobackend(value);
-        resetProfile = true;
+        resetConsumer = true;
+        fullReset = true;
     }
 
     if (m_configSdl.kcfg_window_background->color() != \
KdenliveSettings::window_background()) { @@ -884,7 +947,7 @@ void \
KdenliveSettingsDialog::updateSettings()  
     if (m_configSdl.kcfg_volume->value() != KdenliveSettings::volume()) {
         KdenliveSettings::setVolume(m_configSdl.kcfg_volume->value());
-        resetProfile = true;
+        resetConsumer = true;
     }
 
     if (m_configMisc.kcfg_tabposition->currentIndex() != \
KdenliveSettings::tabposition()) { @@ -943,6 +1006,9 @@ void \
KdenliveSettingsDialog::updateSettings()  
     KConfigDialog::settingsChangedSlot();
     // KConfigDialog::updateSettings();
+    if (resetConsumer) {
+        emit doResetConsumer(fullReset);
+    }
     if (resetProfile) {
         emit doResetProfile();
     }
@@ -1445,8 +1511,8 @@ void KdenliveSettingsDialog::slotEditVideo4LinuxProfile()
 
 void KdenliveSettingsDialog::slotReloadBlackMagic()
 {
-    Render::getBlackMagicDeviceList(m_configCapture.kcfg_decklink_capturedevice, \
                true);
-    if (!Render::getBlackMagicOutputDeviceList(m_configSdl.kcfg_blackmagic_output_device, \
true)) { +    getBlackMagicDeviceList(m_configCapture.kcfg_decklink_capturedevice, \
true); +    if (!getBlackMagicOutputDeviceList(m_configSdl.kcfg_blackmagic_output_device, \
true)) {  // No blackmagic card found
         m_configSdl.kcfg_external_display->setEnabled(false);
     }
diff --git a/src/dialogs/kdenlivesettingsdialog.h \
b/src/dialogs/kdenlivesettingsdialog.h index 3b8fdec60..5b4957b38 100644
--- a/src/dialogs/kdenlivesettingsdialog.h
+++ b/src/dialogs/kdenlivesettingsdialog.h
@@ -114,10 +114,13 @@ private:
     void saveCurrentV4lProfile();
     void loadEncodingProfiles();
     void setupJogshuttleBtns(const QString &device);
-
+    /** @brief Fill a combobox with the found blackmagic devices */
+    static bool getBlackMagicDeviceList(KComboBox *devicelist, bool force = false);
+    static bool getBlackMagicOutputDeviceList(KComboBox *devicelist, bool force = \
false);  signals:
     void customChanged();
     void doResetProfile();
+    void doResetConsumer(bool fullReset);
     void updateCaptureFolder();
     void updateLibraryFolder();
     // Screengrab method changed between fullsceen and region, update rec monitor
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 495d1611c..8f5f7ce77 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -2111,6 +2111,7 @@ void MainWindow::slotPreferences(int page, int option)
     connect(dialog, &KConfigDialog::settingsChanged, this, \
                &MainWindow::updateConfiguration);
     connect(dialog, &KConfigDialog::settingsChanged, this, \
                &MainWindow::configurationChanged);
     connect(dialog, &KdenliveSettingsDialog::doResetProfile, \
pCore->projectManager(), &ProjectManager::slotResetProfiles); +    connect(dialog, \
&KdenliveSettingsDialog::doResetConsumer, pCore->projectManager(), \
                &ProjectManager::slotResetConsumers);
     connect(dialog, &KdenliveSettingsDialog::checkTabPosition, this, \
                &MainWindow::slotCheckTabPosition);
     connect(dialog, &KdenliveSettingsDialog::restartKdenlive, this, \
                &MainWindow::slotRestart);
     connect(dialog, &KdenliveSettingsDialog::updateLibraryFolder, pCore.get(), \
                &Core::updateLibraryPath);
diff --git a/src/monitor/glwidget.cpp b/src/monitor/glwidget.cpp
index 9fa67013a..3ee9a3507 100644
--- a/src/monitor/glwidget.cpp
+++ b/src/monitor/glwidget.cpp
@@ -1124,12 +1124,15 @@ int GLWidget::reconfigure(Mlt::Profile *profile)
             m_consumer->stop();
             delete m_consumer;
         }
-        QString audioBackend = KdenliveSettings::audiobackend();
+        QString audioBackend = (KdenliveSettings::external_display()) ? \
QString("decklink:%1").arg(KdenliveSettings::blackmagic_output_device()) : \
KdenliveSettings::audiobackend();  if (serviceName.isEmpty() || serviceName != \
                audioBackend) {
             m_consumer = new Mlt::FilteredConsumer(*m_monitorProfile, \
audioBackend.toLatin1().constData());  if (m_consumer->is_valid()) {
                 serviceName = audioBackend;
                 setProperty("mlt_service", serviceName);
+                if (KdenliveSettings::external_display()) {
+                    m_consumer->set("terminate_on_pause", 0);
+                }
             } else {
                 // Warning, audio backend unavailable on system
                 delete m_consumer;
@@ -1224,11 +1227,13 @@ int GLWidget::reconfigure(Mlt::Profile *profile)
         // m_consumer->set("progressive", 1);
         m_consumer->set("rescale", \
                KdenliveSettings::mltinterpolation().toUtf8().constData());
         m_consumer->set("deinterlace_method", \
KdenliveSettings::mltdeinterlacer().toUtf8().constData()); +        /*
 #ifdef Q_OS_WIN
         m_consumer->set("audio_buffer", 2048);
 #else
         m_consumer->set("audio_buffer", 512);
 #endif
+        */
         m_consumer->set("buffer", 25);
         m_consumer->set("prefill", 1);
         m_consumer->set("scrub_audio", 1);
@@ -1313,7 +1318,7 @@ void GLWidget::onFrameDisplayed(const SharedFrame &frame)
     m_sharedFrame = frame;
     m_sendFrame = sendFrameForAnalysis;
     m_mutex.unlock();
-    update();
+    //update();
 }
 
 void GLWidget::mouseReleaseEvent(QMouseEvent *event)
@@ -1381,6 +1386,17 @@ void GLWidget::updateGamma()
     reconfigure();
 }
 
+void GLWidget::resetConsumer(bool fullReset)
+{
+    if (fullReset && m_consumer) {
+        m_consumer->purge();
+        m_consumer->stop();
+        delete m_consumer;
+        m_consumer = nullptr;
+    }
+    reconfigure();
+}
+
 const QString GLWidget::sceneList(const QString &root, const QString &fullPath)
 {
     QString playlist;
diff --git a/src/monitor/glwidget.h b/src/monitor/glwidget.h
index c730a84f9..8d74ecd56 100644
--- a/src/monitor/glwidget.h
+++ b/src/monitor/glwidget.h
@@ -99,6 +99,8 @@ public:
     /** @brief set to true if we want to emit a QImage of the frame for analysis */
     bool sendFrameForAnalysis;
     void updateGamma();
+    /** @brief delete and rebuild consumer, for example when external display is \
switched */ +    void resetConsumer(bool fullReset);
     Mlt::Profile *profile();
     void reloadProfile();
     void lockMonitor();
diff --git a/src/monitor/monitor.cpp b/src/monitor/monitor.cpp
index 9dda50f1f..ef36743b4 100644
--- a/src/monitor/monitor.cpp
+++ b/src/monitor/monitor.cpp
@@ -1441,6 +1441,11 @@ void Monitor::resetProfile()
     m_qmlManager->setProperty(QStringLiteral("fps"), QString::number(fps, 'g', 2));
 }
 
+void Monitor::resetConsumer(bool fullReset)
+{
+    m_glMonitor->resetConsumer(fullReset);
+}
+
 /*void Monitor::saveSceneList(const QString &path, const QDomElement &info)
 {
     if (render == nullptr) return;
diff --git a/src/monitor/monitor.h b/src/monitor/monitor.h
index e09c98f06..79dda7d79 100644
--- a/src/monitor/monitor.h
+++ b/src/monitor/monitor.h
@@ -92,6 +92,8 @@ public:
     Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *parent = \
nullptr);  ~Monitor();
     void resetProfile();
+    /** @brief Rebuild consumers after a property change */
+    void resetConsumer(bool fullReset);
     void setCustomProfile(const QString &profile, const Timecode &tc);
     void setupMenu(QMenu *goMenu, QMenu *overlayMenu, QAction *playZone, QAction \
                *loopZone, QMenu *markerMenu = nullptr, QAction *loopClip = nullptr);
     const QString sceneList(const QString &root, const QString &fullPath = \
                QString());
diff --git a/src/monitor/monitormanager.cpp b/src/monitor/monitormanager.cpp
index 6d36962e7..5a8621de1 100644
--- a/src/monitor/monitormanager.cpp
+++ b/src/monitor/monitormanager.cpp
@@ -310,6 +310,18 @@ void MonitorManager::resetProfiles(const Timecode &tc)
     m_projectMonitor->resetProfile();
 }
 
+void MonitorManager::resetConsumers(bool fullReset)
+{
+    bool clipMonitorActive = m_clipMonitor->isActive();
+    m_clipMonitor->resetConsumer(fullReset);
+    m_projectMonitor->resetConsumer(fullReset);
+    if (clipMonitorActive) {
+        refreshClipMonitor();
+    } else {
+        refreshProjectMonitor();
+    }
+}
+
 void MonitorManager::slotUpdateAudioMonitoring()
 {
     if (m_clipMonitor) {
diff --git a/src/monitor/monitormanager.h b/src/monitor/monitormanager.h
index 62aa1eaf0..fad9352e0 100644
--- a/src/monitor/monitormanager.h
+++ b/src/monitor/monitormanager.h
@@ -44,6 +44,8 @@ public:
     void removeMonitor(AbstractMonitor *monitor);
     Timecode timecode() const;
     void resetProfiles(const Timecode &tc);
+    /** @brief delete and rebuild consumer, for example when external display is \
switched */ +    void resetConsumers(bool fullReset);
     void stopActiveMonitor();
     void pauseActiveMonitor();
     AbstractMonitor *activeMonitor();
diff --git a/src/project/projectmanager.cpp b/src/project/projectmanager.cpp
index cba90afd8..3ff6f2d77 100644
--- a/src/project/projectmanager.cpp
+++ b/src/project/projectmanager.cpp
@@ -722,6 +722,11 @@ void ProjectManager::slotResetProfiles()
     pCore->monitorManager()->updateScopeSource();
 }
 
+void ProjectManager::slotResetConsumers(bool fullReset)
+{
+    pCore->monitorManager()->resetConsumers(fullReset);
+}
+
 void ProjectManager::slotExpandClip()
 {
     // TODO refac
diff --git a/src/project/projectmanager.h b/src/project/projectmanager.h
index 23b859f59..81aec76a3 100644
--- a/src/project/projectmanager.h
+++ b/src/project/projectmanager.h
@@ -122,6 +122,9 @@ public slots:
     /** @brief Update project and monitors profiles */
     void slotResetProfiles();
 
+    /** @brief Rebuild consumers after a property change */
+    void slotResetConsumers(bool fullReset);
+
     /** @brief Expand current timeline clip (recover clips and tracks from an MLT \
playlist) */  void slotExpandClip();
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic