]> git.sesse.net Git - kdenlive/commitdiff
Improve profile autodetection
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 20 Sep 2010 13:34:58 +0000 (13:34 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 20 Sep 2010 13:34:58 +0000 (13:34 +0000)
svn path=/trunk/kdenlive/; revision=4913

src/kdenlivedoc.cpp
src/kdenlivedoc.h
src/monitor.cpp
src/profilesdialog.cpp
src/profilesdialog.h
src/projectlist.cpp

index c2a6e8368f96cf2ff55166f44240b729223428b7..3e60ea7b250e9bab5f5f131be23b451e63cb4c7f 100644 (file)
@@ -718,7 +718,7 @@ bool KdenliveDoc::setProfilePath(QString path)
     return (current_fps != m_fps);
 }
 
-double KdenliveDoc::dar()
+double KdenliveDoc::dar() const
 {
     return (double) m_profile.display_aspect_num / m_profile.display_aspect_den;
 }
index da9e5881a5113cd1bd7096563a9afae76e8478a4..a938d8d88354dcfc8064601a4c4d8546629ac455 100644 (file)
@@ -107,7 +107,7 @@ Q_OBJECT public:
     void syncGuides(QList <Guide *> guides);
     void setZoom(int horizontal, int vertical);
     QPoint zoom() const;
-    double dar();
+    double dar() const;
     double projectDuration() const;
     bool saveSceneList(const QString &path, const QString &scene);
     int tracksCount() const;
index f9043b5a6038004247c37146ff71562d83823ccb..292623f6aeddee66e31069025affad07d0cf2198 100644 (file)
 
 
 Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget *parent) :
-        QWidget(parent),
-        render(NULL),
-        m_name(name),
-        m_monitorManager(manager),
-        m_currentClip(NULL),
-        m_ruler(new SmallRuler(m_monitorManager)),
-        m_overlay(NULL),
-        m_isActive(false),
-        m_scale(1),
-        m_length(0),
-        m_dragStarted(false),
-        m_effectScene(NULL),
-        m_effectView(NULL)
+    QWidget(parent),
+    render(NULL),
+    m_name(name),
+    m_monitorManager(manager),
+    m_currentClip(NULL),
+    m_ruler(new SmallRuler(m_monitorManager)),
+    m_overlay(NULL),
+    m_isActive(false),
+    m_scale(1),
+    m_length(0),
+    m_dragStarted(false),
+    m_effectScene(NULL),
+    m_effectView(NULL)
 {
     m_ui.setupUi(this);
     QVBoxLayout *layout = new QVBoxLayout;
@@ -739,7 +739,7 @@ void Monitor::slotSetXml(DocClipBase *clip, QPoint zone, const int position)
         render->setProducer(NULL, -1);
         return;
     }
-    if (m_currentClip != NULL) activateMonitor();
+    if (m_currentClip != NULL || clip != NULL) activateMonitor();
     if (clip != m_currentClip) {
         m_currentClip = clip;
         updateMarkers(clip);
@@ -871,8 +871,8 @@ bool Monitor::effectSceneDisplayed()
 }
 
 MonitorRefresh::MonitorRefresh(QWidget* parent) :
-        QWidget(parent),
-        m_renderer(NULL)
+    QWidget(parent),
+    m_renderer(NULL)
 {
     setAttribute(Qt::WA_PaintOnScreen);
     setAttribute(Qt::WA_OpaquePaintEvent);
@@ -891,7 +891,7 @@ void MonitorRefresh::paintEvent(QPaintEvent *event)
 }
 
 Overlay::Overlay(QWidget* parent) :
-        QLabel(parent)
+    QLabel(parent)
 {
     setAttribute(Qt::WA_TransparentForMouseEvents);
     //setAttribute(Qt::WA_OpaquePaintEvent);
index 9710e12c857e7da5bce2fb1ef97a9a77bc10aaa8..fca5e8eac2a9e3693ba22159096e91515f570134 100644 (file)
@@ -395,11 +395,24 @@ QMap< QString, QString > ProfilesDialog::getSettingsForProfile(const QString pro
 }
 
 // static
-QString ProfilesDialog::getPathFromProperties(int width, int height, double fps, bool useDisplayWidth)
+bool ProfilesDialog::matchProfile(int width, int height, double fps, double par, bool isImage, MltVideoProfile profile)
+{
+    int profileWidth;
+    if (isImage) {
+        // when using image, compare with display width
+        profileWidth = profile.height * profile.display_aspect_num / profile.display_aspect_den + 0.5;
+    } else profileWidth = profile.width;
+    if (width != profileWidth || height != profile.height || (fps > 0 && qAbs(profile.frame_rate_num / profile.frame_rate_den - fps) > 0.4) || (par > 0 && qAbs(profile.sample_aspect_num / profile.sample_aspect_den - par) > 0.1)) return false;
+    return true;
+}
+
+// static
+QMap <QString, QString> ProfilesDialog::getProfilesFromProperties(int width, int height, double fps, double par, bool useDisplayWidth)
 {
     QStringList profilesNames;
     QStringList profilesFiles;
     QStringList profilesFilter;
+    QMap <QString, QString> result;
     profilesFilter << "*";
     // List the Mlt profiles
     profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
@@ -411,8 +424,9 @@ QString ProfilesDialog::getPathFromProperties(int width, int height, double fps,
         else profileWidth = values.value("width").toInt();
         if (profileWidth == width && values.value("height").toInt() == height) {
             double profile_fps = values.value("frame_rate_num").toDouble() / values.value("frame_rate_den").toDouble();
-            if (fps <= 0 || qAbs(profile_fps - fps) < 0.5)
-                return profilesFiles.at(i);
+            double profile_par = values.value("sample_aspect_num").toDouble() / values.value("sample_aspect_den").toDouble();
+            if ((fps <= 0 || qAbs(profile_fps - fps) < 0.5) && (par <= 0 || qAbs(profile_par - par) < 0.1))
+                result.insert(profilesFiles.at(i), values.value("description"));
         }
     }
 
@@ -428,12 +442,13 @@ QString ProfilesDialog::getPathFromProperties(int width, int height, double fps,
             else profileWidth = values.value("width").toInt();
             if (profileWidth == width && values.value("height").toInt() == height) {
                 double profile_fps = values.value("frame_rate_num").toDouble() / values.value("frame_rate_den").toDouble();
-                if (fps <= 0 || qAbs(profile_fps - fps) < 0.5)
-                    return customProfiles.at(i) + profiles.at(j);
+                double profile_par = values.value("sample_aspect_num").toDouble() / values.value("sample_aspect_den").toDouble();
+                if ((fps <= 0 || qAbs(profile_fps - fps) < 0.5) && (par <= 0 || qAbs(profile_par - par) < 0.1))
+                    result.insert(profiles.at(j), values.value("description"));
             }
         }
     }
-    return QString();
+    return result;
 }
 
 // static
index 0ee22a5d8e250910866cca283dcbcfbedb5c6810..54d263afbcbbd9385a6c193fcec9043db99ddd54 100644 (file)
@@ -42,12 +42,29 @@ public:
     static QString existingProfile(MltVideoProfile profile);
     static bool existingProfileDescription(const QString &desc);
 
+    /** @brief Check if a given profile matches passed properties:
+     *  @param width The profile frame width
+     *  @param height The profile frame height
+     *  @param fps The profile fps
+     *  @param par The sample aspect ratio
+     *  @param isImage If true, compare width with profile's display width ( = dar * height)
+     *  @param profile The profile to match
+     *  @return true if properties match profile */
+    static bool matchProfile(int width, int height, double fps, double par, bool isImage, MltVideoProfile profile);
+
     /** @brief Find a profile to match parameter properties:
      *  @param width The profile frame width
      *  @param height The profile frame height
      *  @param fps The profile fps
-     *  @param useDisplayWidth If true, compare width with profile's display width ( = dar * height) */
-    static QString getPathFromProperties(int width, int height, double fps, bool useDisplayWidth = false);
+     *  @param par The sample aspect ratio
+     *  @param useDisplayWidth If true, compare width with profile's display width ( = dar * height)
+     *  @return A string list of the matching profiles description */
+    static QMap <QString, QString> getProfilesFromProperties(int width, int height, double fps, double par, bool useDisplayWidth = false);
+
+    /** @brief Returns an value from a string by replacing "%width" and "%height" with given profile values:
+     *  @param profile The profile that gives width & height
+     *  @param eval The string to be evaluated, for example: "%width / 2"
+     *  @return the evaluated value */
     static double getStringEval(const MltVideoProfile &profile, QString eval);
 
 protected:
index 8264afeec9aec3f7f37a8071e7d830c30aaf7f1a..18562312f62821e09ddc82d3d787e8be209bf200 100644 (file)
@@ -1473,6 +1473,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
     int max = m_doc->clipManager()->clipsCount();
     if (item && m_infoQueue.isEmpty() && m_thumbnailQueue.isEmpty()) {
         m_listView->setCurrentItem(item);
+        bool displayClipInMonitor = true;
         if (item->parent()) {
             if (item->parent()->type() == PROJECTFOLDERTYPE)
                 static_cast <FolderProjectItem *>(item->parent())->switchIcon();
@@ -1481,29 +1482,47 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
             int width = properties.value("frame_size").section('x', 0, 0).toInt();
             int height = properties.value("frame_size").section('x', -1).toInt();
             double fps = properties.value("fps").toDouble();
-            int renderWidth = -1;
-            int renderHeight = -1;
-            double renderFps = -1;
-            if (item->clipType() == IMAGE) {
-                renderWidth = m_doc->renderer()->renderWidth();
-                renderHeight = m_doc->height();
-            } else if (item->clipType() == AV || item->clipType() == VIDEO) {
-                renderWidth = m_doc->width();
-                renderHeight = m_doc->height();
-                renderFps = m_doc->fps();
-            }
-            if ((renderWidth > 0 && width != renderWidth) || (renderHeight > 0 && height != renderHeight) || (renderFps > 0 && qAbs(fps - renderFps) > 0.5)) {
-                QString suggestedProfile = ProfilesDialog::getPathFromProperties(width, height, fps, item->clipType() == IMAGE);
-                if (!suggestedProfile.isEmpty()) {
-                    QString description = ProfilesDialog::getSettingsFromFile(suggestedProfile).value("description");
-                    if (KMessageBox::questionYesNo(this, i18n("Your clip does not match current project's profile.\nDo you want to adjust the profile (clip size: %1, fps: %2)?\nSuggested profile is %3", properties.value("frame_size"), fps, description)) == KMessageBox::Yes) {
-                        //Change project profile
-                        emit updateProfile(suggestedProfile);
-                    }
-                } else KMessageBox::information(this, i18n("Your clip does not match current project's profile.\nNo existing profile found to match the clip's properties.\nClip size: %1\nFps: %2\n", properties.value("frame_size"), fps));
+            double par = properties.value("aspect_ratio").toDouble();
+            if (item->clipType() == IMAGE || item->clipType() == AV || item->clipType() == VIDEO) {
+                if (ProfilesDialog::matchProfile(width, height, fps, par, item->clipType() == IMAGE, m_doc->mltProfile()) == false) {
+                    // get a list of compatible profiles
+                    QMap <QString, QString> suggestedProfiles = ProfilesDialog::getProfilesFromProperties(width, height, fps, par, item->clipType() == IMAGE);
+                    if (!suggestedProfiles.isEmpty()) {
+                        KDialog *dialog = new KDialog(this);
+                        dialog->setCaption(i18n("Change project profile"));
+                        dialog->setButtons(KDialog::Ok | KDialog::Cancel);
+
+                        QWidget container;
+                        QVBoxLayout *l = new QVBoxLayout;
+                        QLabel *label = new QLabel(i18n("Your clip does not match current project's profile.\nDo you want to change the project profile?\n\nThe following profiles match the clip (size: %1, fps: %2)", properties.value("frame_size"), fps));
+                        l->addWidget(label);
+                        QListWidget *list = new QListWidget;
+                        list->setAlternatingRowColors(true);
+                        QMapIterator<QString, QString> i(suggestedProfiles);
+                        while (i.hasNext()) {
+                            i.next();
+                            QListWidgetItem *item = new QListWidgetItem(i.value(), list);
+                            item->setData(Qt::UserRole, i.key());
+                            item->setToolTip(i.key());
+                        }
+                        list->setCurrentRow(0);
+                        l->addWidget(list);
+                        container.setLayout(l);
+                        dialog->setButtonText(KDialog::Ok, i18n("Update profile"));
+                        dialog->setMainWidget(&container);
+                        if (dialog->exec() == QDialog::Accepted) {
+                            //Change project profile
+                            displayClipInMonitor = false;
+                            if (list->currentItem())
+                                emit updateProfile(list->currentItem()->data(Qt::UserRole).toString());
+                        }
+                        delete list;
+                        delete label;
+                    } else KMessageBox::information(this, i18n("Your clip does not match current project's profile.\nNo existing profile found to match the clip's properties.\nClip size: %1\nFps: %2\n", properties.value("frame_size"), fps));
+                }
             }
         }
-        emit clipSelected(item->referencedClip());
+        if (displayClipInMonitor) emit clipSelected(item->referencedClip());
     } else {
         emit displayMessage(i18n("Loading clips"), (int)(100 *(max - m_infoQueue.count()) / max));
     }