Commit f0c53cf4 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

* Fix clip monitor position changed when clip dragged in timeline.

* Fix play action playing wrong monitor
* Fix Movit crashes
* Fix Movit thumbnails for title clips
* Might Fix some titles crashes
BUG: 352823
parent d280557c
......@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "timecode.h"
#include "doc/kthumb.h"
#include "kdenlivesettings.h"
#include "timeline/clip.h"
#include "project/projectcommands.h"
#include "mltcontroller/clipcontroller.h"
#include "lib/audio/audioStreamInfo.h"
......@@ -46,8 +47,8 @@ ProjectClip::ProjectClip(const QString &id, QIcon thumb, ClipController *control
AbstractProjectItem(AbstractProjectItem::ClipItem, id, parent)
, audioFrameCache()
, m_controller(controller)
, m_gpuProducer(NULL)
, m_abortAudioThumb(false)
, m_thumbsProducer(NULL)
{
m_clipStatus = StatusReady;
m_thumbnail = thumb;
......@@ -68,9 +69,9 @@ ProjectClip::ProjectClip(const QDomElement& description, QIcon thumb, ProjectFol
AbstractProjectItem(AbstractProjectItem::ClipItem, description, parent)
, audioFrameCache()
, m_controller(NULL)
, m_gpuProducer(NULL)
, m_abortAudioThumb(false)
, m_type(Unknown)
, m_thumbsProducer(NULL)
{
Q_ASSERT(description.hasAttribute("id"));
m_clipStatus = StatusWaiting;
......@@ -95,6 +96,7 @@ ProjectClip::~ProjectClip()
{
// controller is deleted in bincontroller
abortAudioThumbs();
delete m_thumbsProducer;
}
QString ProjectClip::getToolTip() const
......@@ -308,7 +310,7 @@ void ProjectClip::abortAudioThumbs()
}
}
Mlt::Producer *ProjectClip::producer()
Mlt::Producer *ProjectClip::originalProducer()
{
if (!m_controller) {
return NULL;
......@@ -316,6 +318,28 @@ Mlt::Producer *ProjectClip::producer()
return &m_controller->originalProducer();
}
Mlt::Producer *ProjectClip::thumbProducer()
{
QMutexLocker locker(&m_producerMutex);
if (m_thumbsProducer) {
return m_thumbsProducer;
}
if (!m_controller) {
return NULL;
}
Mlt::Producer prod = m_controller->originalProducer();
Clip clip(prod);
m_thumbsProducer = clip.softClone(ClipController::getPassPropertiesList());
// Check if we are using GPU accel, then we need to use alternate producer
if (KdenliveSettings::gpu_accel()) {
Mlt::Filter scaler(*prod.profile(), "swscale");
Mlt::Filter converter(*prod.profile(), "avcolor_space");
m_thumbsProducer->attach(scaler);
m_thumbsProducer->attach(converter);
}
return m_thumbsProducer;
}
ClipController *ProjectClip::controller()
{
return m_controller;
......@@ -695,20 +719,8 @@ QVariant ProjectClip::data(DataType type) const
void ProjectClip::slotExtractImage(QList <int> frames)
{
Mlt::Producer *prod = producer();
Mlt::Producer *prod = thumbProducer();
if (prod == NULL || !prod->is_valid()) return;
// Check if we are using GPU accel, then we need to use alternate producer
if (KdenliveSettings::gpu_accel()) {
if (m_gpuProducer == NULL) {
QString service = prod->get("mlt_service");
m_gpuProducer = new Mlt::Producer(*prod->profile(), service.toUtf8().constData(), prod->get("resource"));
Mlt::Filter scaler(*prod->profile(), "swscale");
Mlt::Filter converter(*prod->profile(), "avcolor_space");
m_gpuProducer->attach(scaler);
m_gpuProducer->attach(converter);
}
prod = m_gpuProducer;
}
int fullWidth = (int)((double) 150 * prod->profile()->dar() + 0.5);
QDir thumbFolder(bin()->projectFolder().path() + "/thumbs/");
for (int i = 0; i < frames.count(); i++) {
......@@ -731,20 +743,8 @@ void ProjectClip::slotExtractImage(QList <int> frames)
void ProjectClip::slotExtractSubImage(QList <int> frames)
{
Mlt::Producer *prod = producer();
Mlt::Producer *prod = thumbProducer();
if (prod == NULL || !prod->is_valid()) return;
// Check if we are using GPU accel, then we need to use alternate producer
if (KdenliveSettings::gpu_accel()) {
if (m_gpuProducer == NULL) {
QString service = prod->get("mlt_service");
m_gpuProducer = new Mlt::Producer(*prod->profile(), service.toUtf8().constData(), prod->get("resource"));
Mlt::Filter scaler(*prod->profile(), "swscale");
Mlt::Filter converter(*prod->profile(), "avcolor_space");
m_gpuProducer->attach(scaler);
m_gpuProducer->attach(converter);
}
prod = m_gpuProducer;
}
int fullWidth = (int)((double) 150 * prod->profile()->dar() + 0.5);
QDir thumbFolder(bin()->projectFolder().path() + "/thumbs/");
for (int i = 0; i < frames.count(); i++) {
......@@ -789,7 +789,7 @@ int ProjectClip::audioChannels() const
void ProjectClip::slotCreateAudioThumbs()
{
Mlt::Producer *prod = producer();
Mlt::Producer *prod = originalProducer();
if (!prod || !prod->is_valid()) return;
AudioStreamInfo *audioInfo = m_controller->audioInfo();
if (audioInfo == NULL) return;
......
......@@ -137,7 +137,8 @@ public:
bool isReady() const;
/** @brief Returns this clip's producer. */
Mlt::Producer *producer();
Mlt::Producer *originalProducer();
Mlt::Producer *thumbProducer();
ClipController *controller();
......@@ -215,7 +216,6 @@ private:
QList <int> m_markers;
/** @brief The Clip controller for this clip. */
ClipController *m_controller;
Mlt::Producer *m_gpuProducer;
/** @brief Generate and store file hash if not available. */
const QString getFileHash() const;
/** @brief Store clip url temporarily while the clip controller has not been created. */
......@@ -224,6 +224,8 @@ private:
/** @brief Indicates whether audio thumbnail creation is running. */
QFuture<void> m_audioThumbsThread;
ClipType m_type;
Mlt::Producer *m_thumbsProducer;
QMutex m_producerMutex;
const QString geometryWithOffset(const QString &data, int offset);
signals:
......
......@@ -194,7 +194,7 @@ const QString ClipController::clipId()
// static
const char *ClipController::getPassPropertiesList()
{
return "kdenlive:proxy,kdenlive:originalurl,force_aspect_num,force_aspect_den,force_aspect_ratio,force_fps,force_progressive,force_tff,threads,force_colorspace,set.force_full_luma,templatetext,file_hash";
return "kdenlive:proxy,kdenlive:originalurl,force_aspect_num,force_aspect_den,force_aspect_ratio,force_fps,force_progressive,force_tff,threads,force_colorspace,set.force_full_luma,templatetext,file_hash,xmldata";
}
QMap <QString, QString> ClipController::getPropertiesFromPrefix(const QString &prefix, bool withPrefix)
......
......@@ -139,8 +139,21 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren
QToolButton *playButton = new QToolButton(m_toolbar);
m_playMenu = new QMenu(i18n("Play..."), this);
m_playAction = static_cast<KDualAction*> (manager->getAction("monitor_play"));
QAction *originalPlayAction = static_cast<KDualAction*> (manager->getAction("monitor_play"));
m_playAction = new KDualAction(i18n("Play"), i18n("Pause"), this);
m_playAction->setInactiveIcon(QIcon::fromTheme("media-playback-start"));
m_playAction->setActiveIcon(QIcon::fromTheme("media-playback-pause"));
QString strippedTooltip = m_playAction->toolTip().remove(QRegExp("\\s\\(.*\\)"));
// append shortcut if it exists for action
if (originalPlayAction->shortcut() == QKeySequence(0)) {
m_playAction->setToolTip( strippedTooltip);
}
else {
m_playAction->setToolTip( strippedTooltip + " (" + originalPlayAction->shortcut().toString() + ")");
}
m_playMenu->addAction(m_playAction);
connect(m_playAction, &QAction::triggered, this, &Monitor::slotPlay);
playButton->setMenu(m_playMenu);
playButton->setPopupMode(QToolButton::MenuButtonPopup);
......@@ -586,7 +599,9 @@ void Monitor::mouseReleaseEvent(QMouseEvent * event)
if (m_dragStarted && event->button() != Qt::RightButton) {
if (m_glMonitor->geometry().contains(event->pos())) {
if (isActive()) slotPlay();
else slotActivateMonitor();
else {
slotActivateMonitor();
}
} //else event->ignore(); //QWidget::mouseReleaseEvent(event);
}
m_dragStarted = false;
......@@ -919,6 +934,7 @@ void Monitor::adjustRulerSize(int length, int offset)
void Monitor::stop()
{
m_playAction->setActive(false);
if (render) render->stop();
}
......@@ -1479,3 +1495,4 @@ bool Monitor::stopCapture()
return true;
}
......@@ -35,7 +35,6 @@
#include <QTimer>
#include <QDebug>
MonitorManager::MonitorManager(QObject *parent) :
QObject(parent),
m_document(NULL),
......
......@@ -31,6 +31,7 @@
#include "dialogs/profilesdialog.h"
#include "mltcontroller/bincontroller.h"
#include "bin/projectclip.h"
#include "timeline/clip.h"
#include "monitor/glwidget.h"
#include "mltcontroller/clipcontroller.h"
#include <mlt++/Mlt.h>
......@@ -865,8 +866,22 @@ void Render::processFileProperties()
if (frame && frame->is_valid()) {
if (!mltService.contains("avformat")) {
// Fetch thumbnail
QImage img = KThumb::getFrame(frame, fullWidth, info.imageHeight);
emit replyGetImage(info.clipId, img);
QImage img;
if (KdenliveSettings::gpu_accel()) {
delete frame;
Clip clp(*producer);
Mlt::Producer *glProd = clp.softClone(ClipController::getPassPropertiesList());
Mlt::Filter scaler(*m_qmlView->profile(), "swscale");
Mlt::Filter converter(*m_qmlView->profile(), "avcolor_space");
glProd->attach(scaler);
glProd->attach(converter);
frame = glProd->get_frame();
img = KThumb::getFrame(frame, fullWidth, info.imageHeight);
delete glProd;
} else {
img = KThumb::getFrame(frame, fullWidth, info.imageHeight);
}
emit replyGetImage(info.clipId, img);
}
else {
filePropertyMap["frame_size"] = QString::number(frame->get_int("width")) + 'x' + QString::number(frame->get_int("height"));
......@@ -890,12 +905,13 @@ void Render::processFileProperties()
// Check if we are using GPU accel, then we need to use alternate producer
Mlt::Producer *tmpProd = NULL;
if (KdenliveSettings::gpu_accel()) {
QString service = producer->get("mlt_service");
tmpProd = new Mlt::Producer(*m_qmlView->profile(), service.toUtf8().constData(), path.toUtf8().constData());
Mlt::Filter scaler(*m_qmlView->profile(), "swscale");
Mlt::Filter converter(*m_qmlView->profile(), "avcolor_space");
tmpProd->attach(scaler);
tmpProd->attach(converter);
delete frame;
Clip clp(*producer);
tmpProd = clp.softClone(ClipController::getPassPropertiesList());
Mlt::Filter scaler(*m_qmlView->profile(), "swscale");
Mlt::Filter converter(*m_qmlView->profile(), "avcolor_space");
tmpProd->attach(scaler);
tmpProd->attach(converter);
frame = tmpProd->get_frame();
}
else {
......@@ -1455,15 +1471,12 @@ void Render::stop()
QMutexLocker locker(&m_mutex);
m_isActive = false;
if (m_mltProducer == NULL) return;
if (m_isZoneMode) resetZoneMode();
m_mltProducer->set_speed(0.0);
if (m_mltConsumer) {
m_mltConsumer->purge();
if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop();
}
if (m_mltProducer) {
if (m_isZoneMode) resetZoneMode();
m_mltProducer->set_speed(0.0);
}
}
void Render::stop(const GenTime & startTime)
......
......@@ -132,3 +132,13 @@ QByteArray Clip::xml()
Mlt::Producer *Clip::clone() {
return new Mlt::Producer(*m_producer.profile(), "xml-string", xml().constData());
}
Mlt::Producer *Clip::softClone(const char*list) {
QString service = m_producer.get("mlt_service");
QString resource = m_producer.get("resource");
Mlt::Producer *clone = new Mlt::Producer(*m_producer.profile(), service.toUtf8().constData(), resource.toUtf8().constData());
Mlt::Properties original(m_producer.get_properties());
Mlt::Properties cloneProps(clone->get_properties());
cloneProps.pass_list(original, list);
return clone;
}
......@@ -39,7 +39,12 @@ public:
~Clip();
Clip& operator=(Clip& other);
QByteArray xml();
/** @brief: Clone a producer (creates a completely independant copy) */
Mlt::Producer *clone();
/** @brief: Clone a producer without using xml-string producer.
* When Movit is used, we must use this because xml-string crashes (probably attaches some normalizers)
*/
Mlt::Producer *softClone(const char*list);
void deleteEffects();
void addEffects(Mlt::Service& service);
void replaceEffects(Mlt::Service& service);
......
......@@ -97,7 +97,7 @@ ClipItem::ClipItem(ProjectClip *clip, const ItemInfo& info, double fps, double s
m_endThumbTimer.setSingleShot(true);
connect(&m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb()));
connect(m_binClip, SIGNAL(thumbReady(int,QImage)), this, SLOT(slotThumbReady(int,QImage)));
if (generateThumbs) QTimer::singleShot(200, this, SLOT(slotFetchThumbs()));
if (generateThumbs && KdenliveSettings::videothumbnails()) QTimer::singleShot(200, this, SLOT(slotFetchThumbs()));
}
} else if (m_clipType == Color) {
m_baseColor = m_binClip->getProducerColorProperty("resource");
......
......@@ -1718,7 +1718,6 @@ bool CustomTrackView::insertDropClips(const QMimeData *data, const QPoint &pos)
m_selectionGroup->setSelected(true);
} else if (data->hasFormat("kdenlive/producerslist")) {
QStringList ids = QString(data->data("kdenlive/producerslist")).split(';');
qDebug()<<"// DROP 2: "<<ids;
QList <GenTime> offsetList;
QList <ItemInfo> infoList;
GenTime start = GenTime((int)(framePos.x() + 0.5), m_document->fps());
......
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