From bddf7dbd05d7a0c980934baa9caa71b991b92b2a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Fri, 21 Dec 2012 02:18:48 +0100 Subject: [PATCH] Fix Blackmagic Decklink output, cleanup pause / play stuff in all configs (SDL / OpenGL / Decklink) --- src/kdenlivesettingsdialog.cpp | 12 ++- src/kdenlivesettingsdialog.h | 1 + src/renderer.cpp | 130 ++++++++++++++++++--------------- src/renderer.h | 6 +- src/stopmotion/stopmotion.cpp | 8 +- src/widgets/configsdl_ui.ui | 95 ++++++++++++------------ 6 files changed, 138 insertions(+), 114 deletions(-) diff --git a/src/kdenlivesettingsdialog.cpp b/src/kdenlivesettingsdialog.cpp index c42b1d79..847bad75 100644 --- a/src/kdenlivesettingsdialog.cpp +++ b/src/kdenlivesettingsdialog.cpp @@ -189,6 +189,8 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(const QMap& map QWidget *p6 = new QWidget; m_configSdl.setupUi(p6); + m_configSdl.reload_blackmagic->setIcon(KIcon("view-refresh")); + connect(m_configSdl.reload_blackmagic, SIGNAL(clicked(bool)), this, SLOT(slotReloadBlackMagic())); #ifndef USE_OPENGL m_configSdl.kcfg_openglmonitors->setHidden(true); @@ -1109,7 +1111,15 @@ void KdenliveSettingsDialog::slotEditVideo4LinuxProfile() delete w; } - +void KdenliveSettingsDialog::slotReloadBlackMagic() +{ + Render::getBlackMagicDeviceList(m_configCapture.kcfg_decklink_capturedevice, true); + if (!Render::getBlackMagicOutputDeviceList(m_configSdl.kcfg_blackmagic_output_device), true) { + // No blackmagic card found + m_configSdl.kcfg_external_display->setEnabled(false); + } + m_configSdl.kcfg_external_display->setEnabled(KdenliveSettings::decklink_device_found()); +} #include "kdenlivesettingsdialog.moc" diff --git a/src/kdenlivesettingsdialog.h b/src/kdenlivesettingsdialog.h index ed57d12d..e54df0c1 100644 --- a/src/kdenlivesettingsdialog.h +++ b/src/kdenlivesettingsdialog.h @@ -79,6 +79,7 @@ private slots: void slotUpdateProxyProfile(int ix = 0); void slotUpdateV4lProfile(int ix = 0); void slotEditVideo4LinuxProfile(); + void slotReloadBlackMagic(); private: KPageWidgetItem *m_page1; diff --git a/src/renderer.cpp b/src/renderer.cpp index 9742f033..bf473fe1 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -30,10 +30,6 @@ #include "slideshowclip.h" #include "profilesdialog.h" -#ifdef USE_BLACKMAGIC -#include "blackmagic/devices.h" -#endif - #include #include @@ -77,29 +73,36 @@ static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr if (self->analyseAudio) { self->showAudio(frame); } - if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) { + if (frame.get_double("_speed") == 0) self->emitConsumerStopped(); + else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) { self->pause(); - self->emitConsumerStopped(); + self->emitConsumerStopped(true); } } - -static void consumer_paused(mlt_consumer, Render * self, mlt_frame /*frame_ptr*/) +/* +static void consumer_paused(mlt_consumer, Render * self, mlt_frame frame_ptr) { // detect if the producer has finished playing. Is there a better way to do it? - self->emitConsumerStopped(); -} + Mlt::Frame frame(frame_ptr); + if (!frame.is_valid()) return; + if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) { + self->pause(); + self->emitConsumerStopped(true); + } + else self->emitConsumerStopped(); +}*/ static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr) { // detect if the producer has finished playing. Is there a better way to do it? Mlt::Frame frame(frame_ptr); - if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) { + if (frame.get_double("_speed") == 0) self->emitConsumerStopped(); + else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) { self->pause(); - self->emitConsumerStopped(); + self->emitConsumerStopped(true); } - else if (frame.get_double("_speed") == 0) self->emitConsumerStopped(); self->showFrame(frame); } @@ -215,30 +218,27 @@ void Render::buildConsumer(const QString &profileName) m_blackClip = new Mlt::Producer(*m_mltProfile, "colour", "black"); m_blackClip->set("id", "black"); m_blackClip->set("mlt_type", "producer"); - - if (KdenliveSettings::external_display() && m_name != Kdenlive::clipMonitor) { -#ifdef USE_BLACKMAGIC + if (KdenliveSettings::external_display() && m_name != Kdenlive::clipMonitor && m_winid != 0) { // Use blackmagic card for video output - QMap< QString, QString > profileProperties = ProfilesDialog::getSettingsFromFile(profileName); int device = KdenliveSettings::blackmagic_output_device(); if (device >= 0) { - if (BMInterface::isSupportedProfile(device, profileProperties)) { - QString decklink = "decklink:" + QString::number(KdenliveSettings::blackmagic_output_device()); - if (!m_mltConsumer) { - m_mltConsumer = new Mlt::Consumer(*m_mltProfile, decklink.toUtf8().constData()); - m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show); - mlt_log_set_callback(kdenlive_callback); - } - if (m_mltConsumer->is_valid()) { - m_externalConsumer = true; - m_mltConsumer->set("terminate_on_pause", 0); - m_mltConsumer->set("deinterlace_method", "onefield"); - m_mltConsumer->set("real_time", KdenliveSettings::mltthreads()); - } - if (m_mltConsumer && m_mltConsumer->is_valid()) return; - } else KMessageBox::informationList(qApp->activeWindow(), i18n("Your project's profile %1 is not compatible with the blackmagic output card. Please see supported profiles below. Switching to normal video display.", m_mltProfile->description()), BMInterface::supportedModes(KdenliveSettings::blackmagic_output_device())); + QString decklink = "decklink:" + QString::number(KdenliveSettings::blackmagic_output_device()); + if (!m_mltConsumer) { + m_mltConsumer = new Mlt::Consumer(*m_mltProfile, decklink.toUtf8().constData()); + m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show); + mlt_log_set_callback(kdenlive_callback); + } + if (m_mltConsumer->is_valid()) { + m_externalConsumer = true; + m_mltConsumer->set("terminate_on_pause", 0); + m_mltConsumer->set("deinterlace_method", "onefield"); + m_mltConsumer->set("rescale", "nearest"); + m_mltConsumer->set("buffer", "1"); + m_mltConsumer->set("real_time", KdenliveSettings::mltthreads()); + } + if (m_mltConsumer && m_mltConsumer->is_valid()) return; + KMessageBox::information(qApp->activeWindow(), i18n("Your project's profile %1 is not compatible with the blackmagic output card. Please see supported profiles below. Switching to normal video display.", m_mltProfile->description())); } -#endif } m_externalConsumer = false; QString videoDriver = KdenliveSettings::videodrivername(); @@ -256,22 +256,39 @@ void Render::buildConsumer(const QString &profileName) if (m_winid == 0) { // OpenGL monitor if (!m_mltConsumer) { - m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio"); - m_mltConsumer->set("scrub_audio", 1); + if (KdenliveSettings::external_display() && m_name != Kdenlive::clipMonitor) { + int device = KdenliveSettings::blackmagic_output_device(); + if (device >= 0) { + QString decklink = "decklink:" + QString::number(KdenliveSettings::blackmagic_output_device()); + m_mltConsumer = new Mlt::Consumer(*m_mltProfile, decklink.toUtf8().constData()); + // Set defaults for decklink consumer + if (m_mltConsumer) { + m_mltConsumer->set("terminate_on_pause", 0); + m_mltConsumer->set("deinterlace_method", "onefield"); + m_mltConsumer->set("real_time", KdenliveSettings::mltthreads()); + m_externalConsumer = true; + } + } + } + if (!m_mltConsumer || !m_mltConsumer->is_valid()) { + m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio"); + m_mltConsumer->set("scrub_audio", 1); + m_mltConsumer->set("preview_off", 1); + m_mltConsumer->set("preview_format", mlt_image_rgb24a); + } + m_mltConsumer->set("buffer", "1"); m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_gl_frame_show); } - m_mltConsumer->set("preview_off", 1); - m_mltConsumer->set("preview_format", mlt_image_rgb24a); } else { if (!m_mltConsumer) { m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_preview"); m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show); - m_pauseEvent = m_mltConsumer->listen("consumer-sdl-paused", this, (mlt_listener) consumer_paused); + //m_pauseEvent = m_mltConsumer->listen("consumer-sdl-paused", this, (mlt_listener) consumer_paused); + m_mltConsumer->set("progressive", 1); } m_mltConsumer->set("window_id", m_winid); } m_mltConsumer->set("resize", 1); - m_mltConsumer->set("terminate_on_pause", 1); m_mltConsumer->set("window_background", KdenliveSettings::window_background().name().toUtf8().constData()); m_mltConsumer->set("rescale", "nearest"); mlt_log_set_callback(kdenlive_callback); @@ -294,7 +311,6 @@ void Render::buildConsumer(const QString &profileName) if (!audioDriver.isEmpty()) m_mltConsumer->set("audio_driver", audioDriver.toUtf8().constData()); - m_mltConsumer->set("progressive", 1); m_mltConsumer->set("audio_buffer", 1024); m_mltConsumer->set("frequency", 48000); m_mltConsumer->set("real_time", KdenliveSettings::mltthreads()); @@ -401,7 +417,7 @@ void Render::seek(int time) requestedSeekPosition = time; m_mltProducer->seek(time); //m_mltConsumer->purge(); - if (m_paused) { + if (m_paused && !m_externalConsumer) { refresh(); } } @@ -1543,9 +1559,9 @@ void Render::pause() return; m_paused = true; m_mltProducer->set_speed(0.0); - m_mltConsumer->set("refresh", 0); - if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop(); - m_mltProducer->seek(m_mltConsumer->position()); + /*m_mltConsumer->set("refresh", 0); + //if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop(); + m_mltProducer->seek(m_mltConsumer->position());*/ } void Render::switchPlay(bool play) @@ -1558,17 +1574,14 @@ void Render::switchPlay(bool play) if (play && m_paused) { if (m_name == Kdenlive::clipMonitor && m_mltConsumer->position() == m_mltProducer->get_out()) m_mltProducer->seek(0); m_paused = false; + m_mltProducer->set_speed(1.0); if (m_mltConsumer->is_stopped()) { m_mltConsumer->start(); } - m_mltProducer->set_speed(1.0); m_mltConsumer->set("refresh", 1); } else if (!play) { m_paused = true; - m_mltProducer->set_speed(0.0); - m_mltConsumer->set("refresh", 0); - if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop(); - m_mltProducer->seek(m_mltConsumer->position()); + m_mltProducer->pause(); } } @@ -1576,7 +1589,7 @@ void Render::play(double speed) { requestedSeekPosition = SEEK_INACTIVE; if (!m_mltProducer) return; - double current_speed = m_mltProducer->get_speed(); + double current_speed = m_mltProducer->get_speed(); if (current_speed == speed) return; if (m_isZoneMode) resetZoneMode(); // if (speed == 0.0) m_mltProducer->set("out", m_mltProducer->get_length() - 1); @@ -1668,7 +1681,6 @@ void Render::refresh() return; if (m_mltConsumer) { if (m_mltConsumer->is_stopped()) m_mltConsumer->start(); - m_paused = false; //m_mltConsumer->purge(); m_mltConsumer->set("refresh", 1); } @@ -1744,10 +1756,10 @@ void Render::emitFrameNumber() } } -void Render::emitConsumerStopped() +void Render::emitConsumerStopped(bool forcePause) { // This is used to know when the playing stopped - if (m_mltProducer) { + if (m_mltProducer && (forcePause || (!m_paused && m_mltProducer->get_speed() == 0))) { double pos = m_mltProducer->position(); m_paused = true; if (m_isLoopMode) play(m_loopStart); @@ -4538,9 +4550,9 @@ const QString Render::activeClipId() } //static -bool Render::getBlackMagicDeviceList(KComboBox *devicelist) +bool Render::getBlackMagicDeviceList(KComboBox *devicelist, bool force) { - if (!KdenliveSettings::decklink_device_found()) return false; + if (!force && !KdenliveSettings::decklink_device_found()) return false; Mlt::Profile profile; Mlt::Producer bm(profile, "decklink"); int found_devices = 0; @@ -4553,6 +4565,7 @@ bool Render::getBlackMagicDeviceList(KComboBox *devicelist) devicelist->setEnabled(false); return false; } + KdenliveSettings::setDecklink_device_found(true); for (int i = 0; i < found_devices; i++) { char *tmp = qstrdup(QString("device.%1").arg(i).toUtf8().constData()); devicelist->addItem(bm.get(tmp)); @@ -4561,14 +4574,14 @@ bool Render::getBlackMagicDeviceList(KComboBox *devicelist) return true; } -bool Render::getBlackMagicOutputDeviceList(KComboBox *devicelist) +bool Render::getBlackMagicOutputDeviceList(KComboBox *devicelist, bool force) { - if (!KdenliveSettings::decklink_device_found()) return false; + 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); + bm.set("list_devices", 1);; found_devices = bm.get_int("devices"); } else KdenliveSettings::setDecklink_device_found(false); @@ -4576,6 +4589,7 @@ bool Render::getBlackMagicOutputDeviceList(KComboBox *devicelist) devicelist->setEnabled(false); return false; } + KdenliveSettings::setDecklink_device_found(true); for (int i = 0; i < found_devices; i++) { char *tmp = qstrdup(QString("device.%1").arg(i).toUtf8().constData()); devicelist->addItem(bm.get(tmp)); diff --git a/src/renderer.h b/src/renderer.h index 1534a4c5..835b3c20 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -173,7 +173,7 @@ Q_OBJECT public: void emitFrameUpdated(Mlt::Frame&); void emitFrameNumber(); - void emitConsumerStopped(); + void emitConsumerStopped(bool forcePause = false); /** @brief Returns the aspect ratio of the consumer. */ double consumerRatio() const; @@ -323,8 +323,8 @@ Q_OBJECT public: void unlockService(Mlt::Tractor *tractor); const QString activeClipId(); /** @brief Fill a combobox with the found blackmagic devices */ - static bool getBlackMagicDeviceList(KComboBox *devicelist); - static bool getBlackMagicOutputDeviceList(KComboBox *devicelist); + static bool getBlackMagicDeviceList(KComboBox *devicelist, bool force = false); + static bool getBlackMagicOutputDeviceList(KComboBox *devicelist, bool force = false); /** @brief Frame rendering is handeled by Kdenlive, don't show video through SDL display */ void disablePreview(bool disable); int requestedSeekPosition; diff --git a/src/stopmotion/stopmotion.cpp b/src/stopmotion/stopmotion.cpp index dc6c7b6e..b937eff3 100644 --- a/src/stopmotion/stopmotion.cpp +++ b/src/stopmotion/stopmotion.cpp @@ -16,9 +16,6 @@ ***************************************************************************/ #include "stopmotion.h" -#ifdef USE_BLACKMAGIC -#include "blackmagic/devices.h" -#endif #ifdef USE_V4L #include "v4l/v4lcapture.h" #endif @@ -262,11 +259,10 @@ StopmotionWidget::StopmotionWidget(MonitorManager *manager, KUrl projectFolder, m_monitor->videoBox->setLineWidth(4); layout->addWidget(m_monitor->videoBox); -#ifdef USE_BLACKMAGIC - if (BMInterface::getBlackMagicDeviceList(capture_device)) { + if (KdenliveSettings::decklink_device_found()) { // Found a BlackMagic device } -#endif + if (QFile::exists(KdenliveSettings::video4vdevice())) { #ifdef USE_V4L // Video 4 Linux device detection diff --git a/src/widgets/configsdl_ui.ui b/src/widgets/configsdl_ui.ui index b3f2cf0f..42df8669 100644 --- a/src/widgets/configsdl_ui.ui +++ b/src/widgets/configsdl_ui.ui @@ -6,18 +6,12 @@ 0 0 - 336 - 252 + 376 + 257 - - - 0 - - - 0 - - + + Warning: changes to the drivers and devices can make Kdenlive unstable. Change only if you know what you do. @@ -27,7 +21,7 @@ - + Use OpenGL for video display (restart Kdenlive to apply) @@ -50,7 +44,7 @@ - + @@ -69,7 +63,7 @@ - + @@ -82,7 +76,7 @@ - + @@ -112,7 +106,7 @@ - + @@ -123,39 +117,48 @@ - - - + + + + Qt::Horizontal + + + + + + Use external display (Blackmagic card) - + + + + + + Output device + + + + + + true - - false + + + 0 + 0 + + + + + + + + ... - - - - - Output device - - - - - - - - 0 - 0 - - - - - - + Qt::Vertical @@ -171,16 +174,16 @@ - - KComboBox - QComboBox -
kcombobox.h
-
KColorButton QPushButton
kcolorbutton.h
+ + KComboBox + QComboBox +
kcombobox.h
+
-- 2.39.2