Fix mem leak when another process was writing a clip that is included in a project.

A reload operation was performed every 2 seconds while the clip was still being written, leading to
corrupt clip duration and huge memory consumption leading to system freeze
parent 1bddf7ca
......@@ -92,7 +92,7 @@ void FileWatcher::slotProcessModifiedUrls()
{
auto checkList = m_modifiedUrls;
for (const QString &path : checkList) {
if (m_fileWatcher->ctime(path).msecsTo(QDateTime::currentDateTime()) > 1000) {
if (m_fileWatcher->ctime(path).msecsTo(QDateTime::currentDateTime()) > 2000) {
for (const QString &id : m_occurences[path]) {
emit binClipModified(id);
}
......
......@@ -325,9 +325,7 @@ void ProjectClip::reloadProducer(bool refreshOnly, bool audioStreamChanged, bool
pCore->jobManager()->startJob<ThumbJob>({clipId()}, loadjobId, QString(), -1, true, true);
} else {
// If another load job is running?
if (loadjobId > -1) {
pCore->jobManager()->discardJobs(clipId(), AbstractClipJob::LOADJOB);
}
pCore->jobManager()->discardJobs(clipId());
if (QFile::exists(m_path) && !hasProxy()) {
clearBackupProperties();
}
......@@ -362,7 +360,7 @@ void ProjectClip::reloadProducer(bool refreshOnly, bool audioStreamChanged, bool
discardAudioThumb(true);
}
if (KdenliveSettings::audiothumbnails()) {
pCore->jobManager()->startJob<AudioThumbJob>({clipId()}, loadjobId, QString());
pCore->jobManager()->startJob<AudioThumbJob>({clipId()}, loadJob, QString());
}
}
}
......@@ -437,6 +435,7 @@ bool ProjectClip::setProducer(std::shared_ptr<Mlt::Producer> producer, bool repl
qDebug() << "################### ProjectClip::setproducer";
QMutexLocker locker(&m_producerMutex);
updateProducer(producer);
emit producerChanged(m_binId, producer);
m_thumbsProducer.reset();
connectEffectStack();
......
......@@ -113,6 +113,10 @@ bool AudioThumbJob::computeWithMlt()
bool AudioThumbJob::computeWithFFMPEG()
{
if (!KdenliveSettings::audiothumbnails()) {
// We only wanted the thumb generation
return m_done;
}
QString filePath = m_prod->get("kdenlive:originalurl");
if (filePath.isEmpty() || !QFile::exists(filePath)) {
filePath = m_prod->get("resource");
......@@ -214,8 +218,10 @@ bool AudioThumbJob::computeWithFFMPEG()
if (m_ffmpegProcess) {
disconnect(m_ffmpegProcess.get(), &QProcess::readyReadStandardOutput, this, &AudioThumbJob::updateFfmpegProgress);
m_ffmpegProcess->kill();
m_successful = false;
}
m_audioLevels.clear();
m_done = true;
m_successful = false;
});
m_ffmpegProcess->start(KdenliveSettings::ffmpegpath(), args);
m_ffmpegProcess->waitForFinished(-1);
......@@ -249,7 +255,11 @@ bool AudioThumbJob::computeWithFFMPEG()
intraOffset = offset / 10;
}
long maxLevel = 1;
QVector <long> ffmpegLevels;
if (!m_successful) {
m_done = true;
return true;
}
std::vector <long> ffmpegLevels;
for (int i = 0; i < m_lengthInFrames; i++) {
channelsData.resize((size_t)rawChannels.size());
std::fill(channelsData.begin(), channelsData.end(), 0);
......@@ -261,18 +271,25 @@ bool AudioThumbJob::computeWithFFMPEG()
channelsData[k] += abs(rawChannels[k][pos + j]);
}
}
steps = qMax(steps, 1);
for (long &k : channelsData) {
if (steps != 0) {
k /= steps;
if (!m_successful) {
break;
}
k /= steps;
maxLevel = qMax(k, maxLevel);
ffmpegLevels << k;
}
int p = 80 + (i * 20 / m_lengthInFrames);
if (p != progress) {
emit jobProgress(p);
progress = p;
}
ffmpegLevels.insert(ffmpegLevels.end(), channelsData.begin(), channelsData.end());
}
if (!m_successful) {
m_done = true;
return true;
}
for (long &v : ffmpegLevels) {
m_audioLevels << (uint8_t) (255 * v / maxLevel);
......@@ -296,7 +313,7 @@ void AudioThumbJob::updateFfmpegProgress()
if (m_ffmpegProcess == nullptr) {
return;
}
QString result = m_ffmpegProcess->readAllStandardOutput();
const QString result = m_ffmpegProcess->readAllStandardOutput();
const QStringList lines = result.split(QLatin1Char('\n'));
for (const QString &data : lines) {
if (data.startsWith(QStringLiteral("out_time_ms"))) {
......@@ -375,10 +392,12 @@ bool AudioThumbJob::startJob()
ok = computeWithMlt();
}
}
m_ffmpegProcess.reset();
Q_ASSERT(ok == m_done);
if (!m_successful) {
// Job was aborted
m_done = true;
m_audioLevels.clear();
return false;
}
......@@ -418,7 +437,6 @@ bool AudioThumbJob::startJob()
bool AudioThumbJob::commitResult(Fun &undo, Fun &redo)
{
Q_ASSERT(!m_resultConsumed);
m_ffmpegProcess.reset();
if (!m_done) {
qDebug() << "ERROR: Trying to consume invalid results";
return false;
......
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