Commit 8a75aab8 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Reintroduce Blackmagic external monitor support

parent f77309cf
......@@ -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);
}
......
......@@ -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
......
......@@ -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);
......
......@@ -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;
......
......@@ -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();
......
......@@ -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;
......
......@@ -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());
......
......@@ -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) {
......
......@@ -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();
......
......@@ -722,6 +722,11 @@ void ProjectManager::slotResetProfiles()
pCore->monitorManager()->updateScopeSource();
}
void ProjectManager::slotResetConsumers(bool fullReset)
{
pCore->monitorManager()->resetConsumers(fullReset);
}
void ProjectManager::slotExpandClip()
{
// TODO refac
......
......@@ -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();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment