Improve profile autodetection

svn path=/trunk/kdenlive/; revision=4913
parent 63748133
......@@ -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;
}
......
......@@ -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;
......
......@@ -45,19 +45,19 @@
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);
......
......@@ -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
......
......@@ -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:
......
......@@ -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));
}
......
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