Add Cache job for bin clip preview

parent 0f45483c
Pipeline #5181 canceled with stage
......@@ -31,6 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "jobs/jobmanager.h"
#include "jobs/loadjob.hpp"
#include "jobs/thumbjob.hpp"
#include "jobs/cachejob.hpp"
#include "kdenlivesettings.h"
#include "lib/audio/audioStreamInfo.h"
#include "mltcontroller/clipcontroller.h"
......@@ -1401,12 +1402,20 @@ void ProjectClip::getThumbFromPercent(int percent)
{
// extract a maximum of 25 frames for bin preview
percent /= 4;
int framePos = getFramePlaytime() * percent / 25;
int duration = getFramePlaytime();
int framePos = duration * percent / 25;
if (ThumbnailCache::get()->hasThumbnail(m_binId, framePos)) {
setThumbnail(ThumbnailCache::get()->getThumbnail(m_binId, framePos));
} else {
// Generate percent thumbs
//TODO: Generate bin cache whithout creating a job for each thumb
pCore->jobManager()->startJob<ThumbJob>({m_binId}, -1, QString(), 150, framePos, true, false);
int id;
if (pCore->jobManager()->hasPendingJob(m_binId, AbstractClipJob::CACHEJOB, &id)) {
} else {
std::set<int>frames;
for (int i = 1; i <= 100; ++i) {
frames.insert(duration * i / 25);
}
pCore->jobManager()->startJob<CacheJob>({m_binId}, -1, QString(), 150, frames);
}
}
}
......@@ -3,6 +3,7 @@ set(kdenlive_SRCS
jobs/abstractclipjob.cpp
jobs/audiothumbjob.cpp
jobs/jobmanager.cpp
jobs/cachejob.cpp
jobs/loadjob.cpp
jobs/meltjob.cpp
jobs/scenesplitjob.cpp
......
......@@ -51,7 +51,8 @@ public:
ANALYSECLIPJOB = 7,
LOADJOB = 8,
AUDIOTHUMBJOB = 9,
SPEEDJOB = 10
SPEEDJOB = 10,
CACHEJOB = 11
};
AbstractClipJob(JOBTYPE type, QString id, QObject *parent = nullptr);
~AbstractClipJob() override;
......
/***************************************************************************
* Copyright (C) 2019 by Jean-Baptiste Mardelle *
* This file is part of Kdenlive. See www.kdenlive.org. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) version 3 or any later version accepted by the *
* membership of KDE e.V. (or its successor approved by the membership *
* of KDE e.V.), which shall act as a proxy defined in Section 14 of *
* version 3 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "cachejob.hpp"
#include "bin/projectclip.h"
#include "bin/projectitemmodel.h"
#include "bin/projectsubclip.h"
#include "core.h"
#include "doc/kthumb.h"
#include "klocalizedstring.h"
#include "macros.hpp"
#include "utils/thumbnailcache.hpp"
#include <QImage>
#include <QScopedPointer>
#include <mlt++/MltProducer.h>
CacheJob::CacheJob(const QString &binId, int imageHeight, std::set<int> frames)
: AbstractClipJob(CACHEJOB, binId)
, m_frames(frames)
, m_fullWidth(imageHeight * pCore->getCurrentDar() + 0.5)
, m_imageHeight(imageHeight)
, m_done(false)
{
if (m_fullWidth % 8 > 0) {
m_fullWidth += 8 - m_fullWidth % 8;
}
m_imageHeight += m_imageHeight % 2;
auto item = pCore->projectItemModel()->getItemByBinId(binId);
Q_ASSERT(item->itemType() == AbstractProjectItem::ClipItem);
}
const QString CacheJob::getDescription() const
{
return i18n("Extracting thumbs from clip %1", m_clipId);
}
bool CacheJob::startJob()
{
// We reload here, because things may have changed since creation of this job
m_binClip = pCore->projectItemModel()->getClipByBinID(m_clipId);
if (m_binClip->clipType() != ClipType::Video && m_binClip->clipType() != ClipType::AV) {
// Don't create thumbnail for audio clips
m_done = false;
return true;
}
m_prod = m_binClip->thumbProducer();
if ((m_prod == nullptr) || !m_prod->is_valid()) {
qDebug() << "********\nCOULD NOT READ THUMB PRODUCER\n********";
return false;
}
for (int i : m_frames) {
if (ThumbnailCache::get()->hasThumbnail(m_binClip->clipId(), i)) {
continue;
}
m_prod->seek(i);
QScopedPointer<Mlt::Frame> frame(m_prod->get_frame());
frame->set("deinterlace_method", "onefield");
frame->set("top_field_first", -1);
frame->set("rescale.interp", "nearest");
if ((frame != nullptr) && frame->is_valid()) {
QImage result = KThumb::getFrame(frame.data());
ThumbnailCache::get()->storeThumbnail(m_binClip->clipId(), i, result, true);
}
}
m_done = true;
return true;
}
bool CacheJob::commitResult(Fun &undo, Fun &redo)
{
Q_ASSERT(!m_resultConsumed);
m_resultConsumed = true;
return m_done;
}
/***************************************************************************
* Copyright (C) 2019 by Jean-Baptiste Mardelle *
* This file is part of Kdenlive. See www.kdenlive.org. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) version 3 or any later version accepted by the *
* membership of KDE e.V. (or its successor approved by the membership *
* of KDE e.V.), which shall act as a proxy defined in Section 14 of *
* version 3 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#pragma once
#include "abstractclipjob.h"
#include <memory>
#include <set>
/* @brief This class represents the job that corresponds to computing the thumb of a clip
*/
class ProjectClip;
namespace Mlt {
class Producer;
}
class CacheJob : public AbstractClipJob
{
Q_OBJECT
public:
/* @brief Extract a thumb for given clip.
@param frameNumber is the frame to extract. Leave to -1 for default
@param persistent: if true, we will use the persistent cache (for query and saving)
*/
CacheJob(const QString &binId, int imageHeight, std::set<int> frames);
const QString getDescription() const override;
bool startJob() override;
/** @brief This is to be called after the job finished.
By design, the job should store the result of the computation but not share it with the rest of the code. This happens when we call commitResult */
bool commitResult(Fun &undo, Fun &redo) override;
private:
std::set<int> m_frames;
int m_fullWidth;
int m_imageHeight;
std::shared_ptr<ProjectClip> m_binClip;
std::shared_ptr<Mlt::Producer> m_prod;
bool m_done{false};
bool m_inCache{false};
bool m_subClip{false}; // true if we operate on a subclip
};
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