diff --git a/src/bin/bin.cpp b/src/bin/bin.cpp index 5c653485b8f14eff46dc768e6a627715b47995b7..c7a431ebd40735369583b8e79324d197e3c9736b 100644 --- a/src/bin/bin.cpp +++ b/src/bin/bin.cpp @@ -3043,3 +3043,9 @@ void Bin::slotSendAudioThumb(QString id) } } +bool Bin::isEmpty() const +{ + // TODO: return true if we only have folders + if (m_clipCounter == 1) return true; + return m_rootFolder->isEmpty(); +} diff --git a/src/bin/bin.h b/src/bin/bin.h index 2f18afa133093103c5dc0802536fa3dccf25cc6c..00ffbe2b22793623e56b08b4f812313df51a077c 100644 --- a/src/bin/bin.h +++ b/src/bin/bin.h @@ -468,6 +468,8 @@ public: void emitRefreshPanel(const QString &id); /** @brief Audio thumbs just finished creating, update on monitor display. */ void emitRefreshAudioThumbs(const QString &id); + /** @brief Returns true if there is no clip. */ + bool isEmpty() const; private slots: void slotAddClip(); diff --git a/src/definitions.cpp b/src/definitions.cpp index 9cc0ce093c6fc8d1a3b96f9f41022212087286e1..5a789e7277f7781480a8613a8a66ca659cf3d473 100644 --- a/src/definitions.cpp +++ b/src/definitions.cpp @@ -31,6 +31,23 @@ QDebug operator << (QDebug qd, const ItemInfo &info) return qd.maybeSpace(); } +QDebug operator << (QDebug qd, const MltVideoProfile &profile) +{ + qd << "Profile "<< &profile; + qd << "\tProfile fps num " << profile.frame_rate_num; + qd << "\tProfile fps den " << profile.frame_rate_den; + qd << "\tProfile width " << profile.width, + qd << "\tProfile height " << profile.height; + qd << "\tProfile progressive " << profile.progressive; + qd << "\tProfile sar num " << profile.sample_aspect_num; + qd << "\tProfile sar den " << profile.sample_aspect_den; + qd << "\tProfile dar num " << profile.display_aspect_num; + qd << "\tProfile dar den " << profile.display_aspect_den; + qd << "\tProfile colorspace " << profile.colorspace; + qd << "\tProfile description " << profile.description; + return qd.maybeSpace(); +} + MltVideoProfile::MltVideoProfile() : frame_rate_num(0), @@ -51,13 +68,15 @@ bool MltVideoProfile::operator==(const MltVideoProfile &point) const if (!description.isEmpty() && point.description == description) { return true; } - return point.frame_rate_num == frame_rate_num && - point.frame_rate_den == frame_rate_den && + int fps = frame_rate_num * 100 / frame_rate_den; + int sar = sample_aspect_num * 100 / sample_aspect_den; + int dar = display_aspect_num * 100 / display_aspect_den; + return point.frame_rate_num * 100 / point.frame_rate_den == fps && point.width == width && point.height == height && point.progressive == progressive && - point.sample_aspect_num == sample_aspect_num && - point.sample_aspect_den == sample_aspect_den && + point.sample_aspect_num * 100 / point.sample_aspect_den == sar && + point.display_aspect_num * 100 / point.display_aspect_den == dar && point.colorspace == colorspace; } diff --git a/src/definitions.h b/src/definitions.h index b4b1936e24b073209452d05ba26f49c1337456c6..8a41daa065df735193c7490bb1432294f66fa057 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -285,5 +285,6 @@ private: }; QDebug operator << (QDebug qd, const ItemInfo &info); +QDebug operator << (QDebug qd, const MltVideoProfile &profile); #endif diff --git a/src/dialogs/profilesdialog.cpp b/src/dialogs/profilesdialog.cpp index bf3f78b925675dd830bd223c3ddf155fe04f0aa8..e1e5cec64a88a4b16bac79e42fb18ed63f889769 100644 --- a/src/dialogs/profilesdialog.cpp +++ b/src/dialogs/profilesdialog.cpp @@ -293,7 +293,13 @@ MltVideoProfile ProfilesDialog::getVideoProfile(const QString &name) //qDebug() << "// WARNING, COULD NOT FIND PROFILE " << name; return result; } + return getProfileFromPath(path, name); +} + +MltVideoProfile ProfilesDialog::getProfileFromPath(const QString &path, const QString &name) +{ KConfig confFile(path, KConfig::SimpleConfig); + MltVideoProfile result; result.path = name; result.description = confFile.entryMap().value(QStringLiteral("description")); result.frame_rate_num = confFile.entryMap().value(QStringLiteral("frame_rate_num")).toInt(); @@ -342,7 +348,7 @@ bool ProfilesDialog::existingProfileDescription(const QString &desc) } // List custom profiles - QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("/profiles/"), QStandardPaths::LocateDirectory); + QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("profiles/"), QStandardPaths::LocateDirectory); for (int i = 0; i < customProfiles.size(); ++i) { QDir customDir(customProfiles.at(i)); profilesFiles = customDir.entryList(profilesFilter, QDir::Files); @@ -365,37 +371,22 @@ QString ProfilesDialog::existingProfile(const MltVideoProfile &profile) QDir mltDir(KdenliveSettings::mltpath()); QStringList profilesFiles = mltDir.entryList(profilesFilter, QDir::Files); for (int i = 0; i < profilesFiles.size(); ++i) { - KConfig confFile(mltDir.absoluteFilePath(profilesFiles.at(i)), KConfig::SimpleConfig); - if (profile.display_aspect_den != confFile.entryMap().value(QStringLiteral("display_aspect_den")).toInt()) continue; - if (profile.display_aspect_num != confFile.entryMap().value(QStringLiteral("display_aspect_num")).toInt()) continue; - if (profile.sample_aspect_den != confFile.entryMap().value(QStringLiteral("sample_aspect_den")).toInt()) continue; - if (profile.sample_aspect_num != confFile.entryMap().value(QStringLiteral("sample_aspect_num")).toInt()) continue; - if (profile.width != confFile.entryMap().value(QStringLiteral("width")).toInt()) continue; - if (profile.height != confFile.entryMap().value(QStringLiteral("height")).toInt()) continue; - if (profile.frame_rate_den != confFile.entryMap().value(QStringLiteral("frame_rate_den")).toInt()) continue; - if (profile.frame_rate_num != confFile.entryMap().value(QStringLiteral("frame_rate_num")).toInt()) continue; - if (profile.progressive != confFile.entryMap().value(QStringLiteral("progressive")).toInt()) continue; - if (profile.colorspace != confFile.entryMap().value(QStringLiteral("colorspace")).toInt()) continue; - return profilesFiles.at(i); + MltVideoProfile test = getProfileFromPath(mltDir.absoluteFilePath(profilesFiles.at(i)), profilesFiles.at(i)); + if (test == profile) { + return profilesFiles.at(i); + } } // Check custom profiles - QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("/profiles/"), QStandardPaths::LocateDirectory); + QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("profiles/"), QStandardPaths::LocateDirectory); for (int i = 0; i < customProfiles.size(); ++i) { profilesFiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files); for (int j = 0; j < profilesFiles.size(); ++j) { - KConfig confFile(customProfiles.at(i) + profilesFiles.at(j), KConfig::SimpleConfig); - if (profile.display_aspect_den != confFile.entryMap().value(QStringLiteral("display_aspect_den")).toInt()) continue; - if (profile.display_aspect_num != confFile.entryMap().value(QStringLiteral("display_aspect_num")).toInt()) continue; - if (profile.sample_aspect_den != confFile.entryMap().value(QStringLiteral("sample_aspect_den")).toInt()) continue; - if (profile.sample_aspect_num != confFile.entryMap().value(QStringLiteral("sample_aspect_num")).toInt()) continue; - if (profile.width != confFile.entryMap().value(QStringLiteral("width")).toInt()) continue; - if (profile.height != confFile.entryMap().value(QStringLiteral("height")).toInt()) continue; - if (profile.frame_rate_den != confFile.entryMap().value(QStringLiteral("frame_rate_den")).toInt()) continue; - if (profile.frame_rate_num != confFile.entryMap().value(QStringLiteral("frame_rate_num")).toInt()) continue; - if (profile.progressive != confFile.entryMap().value(QStringLiteral("progressive")).toInt()) continue; - if (profile.colorspace != confFile.entryMap().value(QStringLiteral("colorspace")).toInt()) continue; - return customProfiles.at(i) + profilesFiles.at(j); + QString path = customProfiles.at(i) + profilesFiles.at(j); + MltVideoProfile test = getProfileFromPath(path, path); + if (test == profile) { + return path; + } } } return QString(); @@ -418,7 +409,7 @@ QMap ProfilesDialog::getProfilesInfo() } // List custom profiles - QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("/profiles/"), QStandardPaths::LocateDirectory); + QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("profiles/"), QStandardPaths::LocateDirectory); for (int i = 0; i < customProfiles.size(); ++i) { profilesFiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files); for (int j = 0; j < profilesFiles.size(); ++j) { @@ -487,7 +478,7 @@ QMap ProfilesDialog::getProfilesFromProperties(int width, int } // List custom profiles - QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("/profiles/"), QStandardPaths::LocateDirectory); + QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("profiles/"), QStandardPaths::LocateDirectory); for (int i = 0; i < customProfiles.size(); ++i) { QStringList profiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files); for (int j = 0; j < profiles.size(); ++j) { diff --git a/src/dialogs/profilesdialog.h b/src/dialogs/profilesdialog.h index 554af1cf275b07ee4cdc9ab31e48ce558b5b84b3..39caf49eee45c7a9ac58b69d47d510bdf5be73ff 100644 --- a/src/dialogs/profilesdialog.h +++ b/src/dialogs/profilesdialog.h @@ -76,6 +76,9 @@ public: * @return The int code */ static int getColorspaceFromDescription(const QString &description); + /** @brief Build a profile from it's url */ + static MltVideoProfile getProfileFromPath(const QString &path, const QString &name); + protected: virtual void closeEvent(QCloseEvent *event); diff --git a/src/doc/kdenlivedoc.cpp b/src/doc/kdenlivedoc.cpp index 98dd538a6e8962fbdec7aa965d1f8632895248f8..3d0b3667093e826a254edfba2317655798f3310c 100644 --- a/src/doc/kdenlivedoc.cpp +++ b/src/doc/kdenlivedoc.cpp @@ -99,6 +99,7 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup bool success = false; connect(m_commandStack, SIGNAL(indexChanged(int)), this, SLOT(slotModified())); connect(m_render, SIGNAL(setDocumentNotes(QString)), this, SLOT(slotSetDocumentNotes(QString))); + connect(pCore->monitorManager(), &MonitorManager::switchProfile, this, &KdenliveDoc::switchProfile); //connect(m_commandStack, SIGNAL(cleanChanged(bool)), this, SLOT(setModified(bool))); // Init clip modification tracker @@ -890,6 +891,9 @@ bool KdenliveDoc::addClip(QDomElement elem, const QString &clipId) { const QString producerId = clipId.section('_', 0, 0); elem.setAttribute(QStringLiteral("id"), producerId); + if (KdenliveSettings::checkfirstprojectclip() && pCore->bin()->isEmpty()) { + elem.setAttribute("checkProfile", 1); + } pCore->bin()->createClip(elem); m_render->getFileProperties(elem, producerId, 150, true); @@ -1554,4 +1558,33 @@ void KdenliveDoc::resetProfile() { m_profile = ProfilesDialog::getVideoProfile(KdenliveSettings::current_profile()); updateProjectProfile(); + emit docModified(true); } + +void KdenliveDoc::switchProfile(MltVideoProfile profile, const QString &id, const QDomElement &xml) +{ + // Request profile update + QString matchingProfile = ProfilesDialog::existingProfile(profile); + if (!matchingProfile.isEmpty()) { + // We found a known matching profile, switch and inform user + m_profile = profile; + QMap< QString, QString > profileProperties = ProfilesDialog::getSettingsFromFile(matchingProfile); + m_profile.path = matchingProfile; + m_profile.description = profileProperties.value("description"); + updateProjectProfile(); + pCore->bin()->displayMessage(i18n("Switched to clip profile: %1", m_profile.description), KMessageWidget::Information); + emit docModified(true); + } else { + // No known profile, ask user if he wants to use clip profile anyway + if (KMessageBox::questionYesNo(QApplication::activeWindow(), i18n("No existing profile found for your clip (%1x%2, %3fps)\nDo you want to switch to that custom profile ?", profile.width, profile.height, QString::number((double)profile.frame_rate_num / profile.frame_rate_den, 'f', 2))) == KMessageBox::Yes) { + m_profile = profile; + m_profile.description = QString("%1x%2 %3fps").arg(profile.width).arg(profile.height).arg(QString::number((double)profile.frame_rate_num / profile.frame_rate_den, 'f', 2)); + ProfilesDialog::saveProfile(m_profile); + updateProjectProfile(); + pCore->bin()->displayMessage(i18n("Switched to clip profile: %1", m_profile.description), KMessageWidget::Information); + emit docModified(true); + } + } + renderer()->getFileProperties(xml, id, 150, true); +} + diff --git a/src/doc/kdenlivedoc.h b/src/doc/kdenlivedoc.h index 425cca17339d14cd2628cea52c80da3f5bacc2d5..b8a679e421ae222547325941977a5eccd27fef27 100644 --- a/src/doc/kdenlivedoc.h +++ b/src/doc/kdenlivedoc.h @@ -219,6 +219,7 @@ private slots: void slotProcessModifiedClips(); void slotModified(); void slotSetDocumentNotes(const QString ¬es); + void switchProfile(MltVideoProfile profile, const QString &id, const QDomElement &xml); signals: void resetProjectList(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d8a7bb10e5da4c4ec890ba93193708aeb033f6d5..7b88f8af54949a2a21fb2157e6add7aba488473d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -27,7 +27,6 @@ #include "dialogs/kdenlivesettingsdialog.h" #include "dialogs/clipcreationdialog.h" #include "effectslist/initeffects.h" -#include "dialogs/profilesdialog.h" #include "project/dialogs/projectsettings.h" #include "project/clipmanager.h" #include "monitor/monitor.h" @@ -143,7 +142,9 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString & qRegisterMetaType ("stringMap"); qRegisterMetaType ("audioByteArray"); qRegisterMetaType< QVector > (); + qRegisterMetaType ("QDomElement"); qRegisterMetaType ("requestClipInfo"); + qRegisterMetaType ("MltVideoProfile"); Core::build(this); diff --git a/src/monitor/glwidget.cpp b/src/monitor/glwidget.cpp index 226b6e19f7ca982bfd971976c67dbeadda23dfbc..aed127feeb80b67825e11bc2b3726e65986f3a5d 100644 --- a/src/monitor/glwidget.cpp +++ b/src/monitor/glwidget.cpp @@ -947,7 +947,7 @@ int GLWidget::reconfigure(Mlt::Profile *profile) /*if (!m_monitorProfile->progressive()) m_consumer->set("progressive", property("progressive").toBool());*/ m_consumer->set("volume", (double)volume / 100); - m_consumer->set("progressive", 1); + //m_consumer->set("progressive", 1); m_consumer->set("rescale", KdenliveSettings::mltinterpolation().toUtf8().constData()); m_consumer->set("deinterlace_method", KdenliveSettings::mltdeinterlacer().toUtf8().constData()); m_consumer->set("buffer", 25); diff --git a/src/monitor/monitor.cpp b/src/monitor/monitor.cpp index de96c92bb5413c423c658f0b6f2f17b61a906055..419d949f6e84ca9a48c00db6898c915f72b2e886 100644 --- a/src/monitor/monitor.cpp +++ b/src/monitor/monitor.cpp @@ -288,6 +288,7 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren connect(render, SIGNAL(durationChanged(int,int)), this, SLOT(adjustRulerSize(int,int))); connect(render, SIGNAL(rendererStopped(int)), this, SLOT(rendererStopped(int))); + connect(render, &Render::switchProfile, m_monitorManager, &MonitorManager::switchProfile); connect(m_glMonitor, SIGNAL(analyseFrame(QImage)), render, SLOT(emitFrameUpdated(QImage))); connect(m_glMonitor, SIGNAL(audioSamplesSignal(const audioShortVector&,int,int,int)), render, SIGNAL(audioSamplesSignal(const audioShortVector&,int,int,int))); diff --git a/src/monitor/monitormanager.h b/src/monitor/monitormanager.h index c6920dfb973a851e53569625f3fc392b86309095..8f6e8cb4daa0b469dac71f19cf473df29d0d370e 100644 --- a/src/monitor/monitormanager.h +++ b/src/monitor/monitormanager.h @@ -136,7 +136,8 @@ signals: void addEffect(QDomElement); /** @brief Monitor activated, refresh overlay options actions */ void updateOverlayInfos(int, int); - + /** @brief First clip does not match profect profile, switch. */ + void switchProfile(MltVideoProfile profile, const QString &id, const QDomElement &xml); }; #endif diff --git a/src/renderer.cpp b/src/renderer.cpp index fe38b16a530dbecad3d1b4b0f4cfc3f006fa10bc..c951c1aa957f74d0133b8130bd39b1ef40f76856 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -607,6 +607,23 @@ void Render::processFileProperties() producer = new Mlt::Producer(*m_qmlView->profile(), "xml-string", doc.toString().toUtf8().constData()); } else { producer = new Mlt::Producer(*m_qmlView->profile(), 0, path.toUtf8().constData()); + if (producer->is_valid() && info.xml.hasAttribute("checkProfile")) { + // Check if clip profile matches + Mlt::Profile *blankProfile = new Mlt::Profile(); + blankProfile->set_explicit(false); + blankProfile->from_producer(*producer); + MltVideoProfile clipProfile = ProfilesDialog::getVideoProfile(*blankProfile); + MltVideoProfile projectProfile = ProfilesDialog::getVideoProfile(*m_qmlView->profile()); + if (clipProfile != projectProfile) { + // Profiles do not match, adjust profile + delete producer; + delete blankProfile; + m_processingClipId.removeAll(info.clipId); + info.xml.removeAttribute("checkProfile"); + emit switchProfile(clipProfile, info.clipId, info.xml); + return; + } + } } if (producer == NULL || producer->is_blank() || !producer->is_valid()) { qDebug() << " / / / / / / / / ERROR / / / / // CANNOT LOAD PRODUCER: "<