Fix another thumbnail crash

Initial rewrite of project's fps correction, related to #33
parent 29410e26
......@@ -105,29 +105,19 @@ QImage KThumb::getFrame(Mlt::Producer &producer, int framepos, int displayWidth,
QImage KThumb::getFrame(Mlt::Frame *frame, int width, int height, bool forceRescale)
{
if (frame == nullptr || !frame->is_valid()) {
QImage p(width, height, QImage::Format_ARGB32_Premultiplied);
p.fill(QColor(Qt::red).rgb());
return p;
qDebug()<<"* * * *INVALID FRAME";
return QImage();
}
int ow = forceRescale ? 0 : width;
int oh = forceRescale ? 0 : height;
mlt_image_format format = mlt_image_rgb24a;
ow += ow % 2;
const uchar *imagedata = frame->get_image(format, ow, oh);
if (imagedata) {
QImage image(ow, oh, QImage::Format_RGBA8888);
memcpy(image.bits(), imagedata, (unsigned)(ow * oh * 4));
if (!image.isNull()) {
if (ow > (2 * width)) {
// there was a scaling problem, do it manually
image = image.scaled(width, height);
}
return image;
}
QImage temp(ow, oh, QImage::Format_ARGB32);
memcpy(temp.scanLine(0), imagedata, (unsigned)(ow * oh * 4));
return temp.rgbSwapped();
}
QImage p(width, height, QImage::Format_ARGB32_Premultiplied);
p.fill(QColor(Qt::red).rgb());
return p;
return QImage();
}
// static
......
......@@ -30,6 +30,7 @@
#include "utils/thumbnailcache.hpp"
#include <QDir>
#include <QScopedPointer>
#include <QPainter>
#include <mlt++/MltProducer.h>
ThumbJob::ThumbJob(const QString &binId, int imageHeight, int frameNumber, bool persistent, bool reloadAllThumbs)
......@@ -41,8 +42,8 @@ ThumbJob::ThumbJob(const QString &binId, int imageHeight, int frameNumber, bool
, m_reloadAll(reloadAllThumbs)
, m_subClip(false)
{
//m_fullWidth += 8 - m_fullWidth % 8;
//m_imageHeight += m_imageHeight % 2;
m_fullWidth += 8 - m_fullWidth % 8;
m_imageHeight += m_imageHeight % 2;
auto item = pCore->projectItemModel()->getItemByBinId(binId);
Q_ASSERT(item->itemType() == AbstractProjectItem::ClipItem || item->itemType() == AbstractProjectItem::SubClipItem);
if (item->itemType() == AbstractProjectItem::ClipItem) {
......@@ -89,6 +90,7 @@ bool ThumbJob::startJob()
}
m_prod = m_binClip->thumbProducer();
if ((m_prod == nullptr) || !m_prod->is_valid()) {
qDebug()<<"********\nCOULD NOT READ THUMB PRODUCER\n********";
return false;
}
int max = m_prod->get_length();
......@@ -122,6 +124,11 @@ bool ThumbJob::commitResult(Fun &undo, Fun &redo)
if (!m_inCache) {
if (m_result.isNull()) {
qDebug() << "+++++\nINVALID RESULT IMAGE\n++++++++++++++";
m_result = QImage(m_fullWidth, m_imageHeight, QImage::Format_ARGB32_Premultiplied);
m_result.fill(Qt::red);
QPainter p(&m_result);
p.setPen(Qt::white);
p.drawText(0, 0, m_fullWidth, m_imageHeight, Qt::AlignCenter, i18n("Invalid"));
} else {
ThumbnailCache::get()->storeThumbnail(m_binClip->clipId(), m_frameNumber, m_result, m_persistent);
}
......
......@@ -1610,11 +1610,6 @@ void MainWindow::slotEditProjectSettings()
if (KdenliveSettings::audiothumbnails() != w->enableAudioThumbs()) {
slotSwitchAudioThumbs();
}
if (pCore->getCurrentProfile()->path() != profile || project->profileChanged(profile)) {
pCore->setCurrentProfile(profile);
pCore->projectManager()->slotResetProfiles();
slotUpdateDocumentState(true);
}
if (project->getDocumentProperty(QStringLiteral("proxyparams")) != w->proxyParams() ||
project->getDocumentProperty(QStringLiteral("proxyextension")) != w->proxyExtension()) {
modified = true;
......@@ -1692,6 +1687,16 @@ void MainWindow::slotEditProjectSettings()
}
}
}
if (pCore->getCurrentProfile()->path() != profile || project->profileChanged(profile)) {
if (!qFuzzyCompare(pCore->getCurrentProfile()->fps() - ProfileRepository::get()->getProfile(profile)->fps(), 0.)) {
// Fps was changed, we save the project to an xml file with updated profile and reload project
pCore->projectManager()->saveWithUpdatedProfile(profile);
} else {
pCore->setCurrentProfile(profile);
pCore->projectManager()->slotResetProfiles();
slotUpdateDocumentState(true);
}
}
if (modified) {
project->setModified();
}
......
......@@ -1480,6 +1480,7 @@ const QString GLWidget::sceneList(const QString &root, const QString &fullPath)
m_producer->optimise();
xmlConsumer.set("terminate_on_pause", 1);
xmlConsumer.set("store", "kdenlive");
xmlConsumer.set("time_format", "clock");
// Disabling meta creates cleaner files, but then we don't have access to metadata on the fly (meta channels, etc)
// And we must use "avformat" instead of "avformat-novalidate" on project loading which causes a big delay on project opening
// xmlConsumer.set("no_meta", 1);
......
......@@ -422,7 +422,7 @@ void ProjectSettings::accept()
}
}
}
if (!m_savedProject && selectedProfile() != pCore->getCurrentProfile()->path()) {
if (selectedProfile() != pCore->getCurrentProfile()->path()) {
if (KMessageBox::warningContinueCancel(
this,
i18n("Changing the profile of your project cannot be undone.\nIt is recommended to save your project before attempting this operation "
......
......@@ -30,7 +30,7 @@ the Free Software Foundation, either version 3 of the License, or
#include "timeline2/model/builders/meltBuilder.hpp"
#include "timeline2/view/timelinecontroller.h"
#include "timeline2/view/timelinewidget.h"
#include "profiles/profilerepository.hpp"
#include <KActionCollection>
#include <KJob>
......@@ -874,3 +874,60 @@ std::shared_ptr<DocUndoStack> ProjectManager::undoStack()
{
return current()->commandStack();
}
void ProjectManager::saveWithUpdatedProfile(const QString updatedProfile)
{
// First backup current project with fps appended
const QString currentFile = m_project->url().toLocalFile();
QString backupFile = currentFile.section(QLatin1Char('.'), 0, -2);
backupFile.append(QString("-%1.kdenlive").arg((int)(pCore->getCurrentFps() * 100)));
if (!saveFileAs(backupFile)) {
KMessageBox::error(qApp->activeWindow(), i18n("Cannot write backup file %1", backupFile));
return;
}
closeCurrentDocument();
// Now update to new profile
auto &newProfile = ProfileRepository::get()->getProfile(updatedProfile);
QFile f(backupFile);
QDomDocument doc;
doc.setContent(&f, false);
f.close();
QDomElement mltProfile = doc.documentElement().firstChildElement(QStringLiteral("profile"));
if (!mltProfile.isNull()) {
mltProfile.setAttribute(QStringLiteral("frame_rate_num"), newProfile->frame_rate_num());
mltProfile.setAttribute(QStringLiteral("frame_rate_den"), newProfile->frame_rate_den());
mltProfile.setAttribute(QStringLiteral("display_aspect_num"), newProfile->display_aspect_num());
mltProfile.setAttribute(QStringLiteral("display_aspect_den"), newProfile->display_aspect_den());
mltProfile.setAttribute(QStringLiteral("sample_aspect_num"), newProfile->sample_aspect_num());
mltProfile.setAttribute(QStringLiteral("sample_aspect_den"), newProfile->sample_aspect_den());
mltProfile.setAttribute(QStringLiteral("colorspace"), newProfile->colorspace());
mltProfile.setAttribute(QStringLiteral("progressive"), newProfile->progressive());
mltProfile.setAttribute(QStringLiteral("description"), newProfile->description());
mltProfile.setAttribute(QStringLiteral("width"), newProfile->width());
mltProfile.setAttribute(QStringLiteral("height"), newProfile->height());
}
QDomNodeList playlists = doc.documentElement().elementsByTagName(QStringLiteral("playlist"));
for (int i = 0; i < playlists.count(); ++i) {
QDomElement e = playlists.at(i).toElement();
if (e.attribute(QStringLiteral("id")) == QLatin1String("main_bin")) {
Xml::setXmlProperty(e, QStringLiteral("kdenlive:docproperties.profile"), updatedProfile);
break;
}
}
QFile file(currentFile);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
return;
}
QTextStream out(&file);
out << doc.toString();
if (file.error() != QFile::NoError) {
KMessageBox::error(qApp->activeWindow(), i18n("Cannot write to file %1", currentFile));
file.close();
return;
}
file.close();
openFile(QUrl::fromLocalFile(currentFile));
}
......@@ -81,6 +81,11 @@ public:
*/
virtual std::shared_ptr<DocUndoStack> undoStack();
/** @brief This will create a backup file with fps appended to project name,
* and save the project with an updated profile info, then reopen it.
*/
void saveWithUpdatedProfile(const QString updatedProfile);
public slots:
void newFile(bool showProjectSettings = true, bool force = false);
/** @brief Shows file open dialog. */
......
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