Fix possible crash when closing a project or deleting a clip with subclips

parent 7f68d553
......@@ -2686,7 +2686,7 @@ void Bin::loadSubClips(const QString&id, const QMap <QString,QString> data)
}
if (!missingThumbs.isEmpty()) {
// generate missing subclip thumbnails
QtConcurrent::run(clip, &ProjectClip::slotExtractSubImage, missingThumbs);
clip->slotExtractImage(missingThumbs);
}
}
......@@ -2703,7 +2703,9 @@ void Bin::addClipCut(const QString&id, int in, int out)
sub = new ProjectSubClip(clip, in, out, m_doc->timecode().getDisplayTimecodeFromFrames(in, KdenliveSettings::frametimecode()));
QStringList markersComment = clip->markersText(GenTime(in, m_doc->fps()), GenTime(out, m_doc->fps()));
sub->setDescription(markersComment.join(";"));
QtConcurrent::run(clip, &ProjectClip::slotExtractSubImage, QList <int>() << in);
QList <int> missingThumbs;
missingThumbs << in;
clip->slotExtractImage(missingThumbs);
}
void Bin::removeClipCut(const QString&id, int in, int out)
......
......@@ -919,48 +919,6 @@ void ProjectClip::doExtractImage()
}
}
void ProjectClip::slotExtractSubImage(QList <int> frames)
{
Mlt::Producer *prod = thumbProducer();
if (prod == NULL || !prod->is_valid()) return;
int fullWidth = 150 * prod->profile()->dar() + 0.5;
bool ok = false;
QDir thumbFolder = bin()->getCacheDir(CacheThumbs, &ok);
int max = prod->get_length();
for (int i = 0; i < frames.count(); i++) {
int pos = frames.at(i);
QString path = thumbFolder.absoluteFilePath(hash() + "#" + QString::number(pos) + ".png");
if (ok) {
QImage img(path);
if (!img.isNull()) {
for (int i = 0; i < count(); ++i) {
ProjectSubClip *clip = static_cast<ProjectSubClip *>(at(i));
if (clip && clip->zone().x() == pos) {
clip->setThumbnail(img);
}
}
continue;
}
}
pos = qBound(0, pos, max - 1);
prod->seek(pos);
Mlt::Frame *frame = prod->get_frame();
if (frame && frame->is_valid()) {
QImage img = KThumb::getFrame(frame, fullWidth, 150);
if (!img.isNull()) {
img.save(path);
for (int i = 0; i < count(); ++i) {
ProjectSubClip *clip = static_cast<ProjectSubClip *>(at(i));
if (clip && clip->zone().x() == pos) {
clip->setThumbnail(img);
}
}
}
}
delete frame;
}
}
int ProjectClip::audioChannels() const
{
if (!m_controller || !m_controller->audioInfo()) return 0;
......
......@@ -221,8 +221,6 @@ public slots:
void updateAudioThumbnail(QVariantList audioLevels);
/** @brief Extract image thumbnails for timeline. */
void slotExtractImage(QList <int> frames);
/** @brief Extract image thumbnails for clip's subclips. */
void slotExtractSubImage(QList <int> frames);
void slotCreateAudioThumbs();
/** @brief Set the Job status on a clip.
* @param jobType The job type
......
......@@ -48,6 +48,7 @@ ProjectSubClip::ProjectSubClip(ProjectClip *parent, int in, int out, const QStri
m_duration = timecode;
// Save subclip in MLT
parent->setProducerProperty("kdenlive:clipzone." + m_name, QString::number(in) + ";" + QString::number(out));
connect(parent, &ProjectClip::thumbReady, this, &ProjectSubClip::gotThumb);
}
ProjectSubClip::~ProjectSubClip()
......@@ -55,6 +56,14 @@ ProjectSubClip::~ProjectSubClip()
// controller is deleted in bincontroller
}
void ProjectSubClip::gotThumb(int pos, QImage img)
{
if (pos == m_in) {
setThumbnail(img);
disconnect(m_masterClip, &ProjectClip::thumbReady, this, &ProjectSubClip::gotThumb);
}
}
void ProjectSubClip::discard()
{
if (m_masterClip) m_masterClip->resetProducerProperty("kdenlive:clipzone." + m_name);
......
......@@ -72,7 +72,7 @@ public:
/** @brief Sets thumbnail for this clip. */
void setThumbnail(QImage);
/** @brief Remove reference to this subclip in the master clip, to be done before a subclip is deleted. */
void discard();
QPoint zone() const;
......@@ -84,6 +84,8 @@ private:
int m_in;
int m_out;
private slots:
void gotThumb(int pos, QImage img);
};
#endif
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