aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <[email protected]>2015-07-27 02:09:27 +0200
committerJean-Baptiste Mardelle <[email protected]>2015-07-27 02:09:27 +0200
commitac818ff4af0dde8e1a7d48450e03f0e0188afebe (patch)
treef4d5595c9343830f29e0e750032a9c103921e0fd
parentade3d0ef2a4745e62d32eba963bba22c72894325 (diff)
Fix timeline corruption when using video only clips and some other crashes
-rw-r--r--src/bin/bin.cpp22
-rw-r--r--src/bin/bin.h2
-rw-r--r--src/bin/projectclip.cpp4
-rw-r--r--src/mltcontroller/bincontroller.cpp10
-rw-r--r--src/mltcontroller/bincontroller.h2
-rw-r--r--src/monitor/monitor.cpp27
-rw-r--r--src/monitor/monitor.h3
-rw-r--r--src/monitor/recmanager.cpp2
-rw-r--r--src/project/projectmanager.cpp2
-rw-r--r--src/renderer.cpp1
-rw-r--r--src/renderer.h2
-rw-r--r--src/timeline/customtrackview.cpp9
-rw-r--r--src/timeline/customtrackview.h1
-rw-r--r--src/timeline/timeline.cpp15
-rw-r--r--src/timeline/track.cpp33
-rw-r--r--src/timeline/track.h2
16 files changed, 95 insertions, 42 deletions
diff --git a/src/bin/bin.cpp b/src/bin/bin.cpp
index e0ae4c4..e44cb52 100644
--- a/src/bin/bin.cpp
+++ b/src/bin/bin.cpp
@@ -417,7 +417,7 @@ void Bin::slotAddClip()
void Bin::deleteClip(const QString &id)
{
if (m_monitor->activeClipId() == id) {
- m_monitor->openClip(NULL);
+ emit openClip(NULL);
}
ProjectClip *clip = m_rootFolder->clip(id);
if (!clip) return;
@@ -493,7 +493,7 @@ void Bin::slotReloadClip()
AbstractProjectItem *item = static_cast<AbstractProjectItem*>(m_proxyModel->mapToSource(ix).internalPointer());
ProjectClip *currentItem = qobject_cast<ProjectClip*>(item);
if (currentItem) {
- m_monitor->openClip(NULL);
+ emit openClip(NULL);
QDomDocument doc;
QDomElement xml = currentItem->toXml(doc);
if (!xml.isNull()) {
@@ -543,6 +543,7 @@ void Bin::setMonitor(Monitor *monitor)
m_monitor = monitor;
connect(m_monitor, SIGNAL(addClipToProject(QUrl)), this, SLOT(slotAddClipToProject(QUrl)));
connect(m_monitor, SIGNAL(refreshCurrentClip()), this, SLOT(slotOpenCurrent()));
+ connect(this, SIGNAL(openClip(ClipController*,int,int)), m_monitor, SLOT(slotOpenClip(ClipController*,int,int)));
connect(m_eventEater, SIGNAL(focusClipMonitor()), m_monitor, SLOT(slotActivateMonitor()), Qt::UniqueConnection);
}
@@ -564,7 +565,7 @@ int Bin::lastClipId() const
void Bin::setDocument(KdenliveDoc* project)
{
// Remove clip from Bin's monitor
- m_monitor->openClip(NULL);
+ emit openClip(NULL);
closeEditing();
setEnabled(false);
@@ -912,7 +913,7 @@ void Bin::selectProxyModel(const QModelIndex &id)
showClipProperties(NULL);
emit masterClipSelected(NULL, m_monitor);
// Display black bg in clip monitor
- m_monitor->openClip(NULL);
+ emit openClip(NULL);
}
}
@@ -1341,7 +1342,7 @@ void Bin::slotProducerReady(requestClipInfo info, ClipController *controller)
m_doc->watchFile(clip->url());
}
}
- if (controller) clip->setProducer(controller, info.replaceProducer);
+ clip->setProducer(controller, info.replaceProducer);
QString currentClip = m_monitor->activeClipId();
if (currentClip.isEmpty()) {
//No clip displayed in monitor, check if item is selected
@@ -1359,9 +1360,8 @@ void Bin::slotProducerReady(requestClipInfo info, ClipController *controller)
}
}
else if (currentClip == info.clipId) {
- m_monitor->openClip(NULL);
+ emit openClip(NULL);
clip->setCurrent(true);
- //m_monitor->openClip(controller);
}
}
else {
@@ -1390,17 +1390,19 @@ void Bin::slotProducerReady(requestClipInfo info, ClipController *controller)
void Bin::slotOpenCurrent()
{
ProjectClip *currentItem = getFirstSelectedClip();
- if (currentItem) m_monitor->openClip(currentItem->controller());
+ if (currentItem) {
+ emit openClip(currentItem->controller());
+ }
}
void Bin::openProducer(ClipController *controller)
{
- m_monitor->openClip(controller);
+ emit openClip(controller);
}
void Bin::openProducer(ClipController *controller, int in, int out)
{
- m_monitor->openClipZone(controller, in, out);
+ emit openClip(controller, in, out);
}
void Bin::emitItemUpdated(AbstractProjectItem* item)
diff --git a/src/bin/bin.h b/src/bin/bin.h
index 8f8e4df..9add8e4 100644
--- a/src/bin/bin.h
+++ b/src/bin/bin.h
@@ -608,6 +608,8 @@ signals:
void refreshPanelMarkers();
/** @brief Analysis data changed, refresh panel. */
void updateAnalysisData(const QString &);
+ void openClip(ClipController *c, int in = -1, int out = -1);
+
};
#endif
diff --git a/src/bin/projectclip.cpp b/src/bin/projectclip.cpp
index 2af5a28..aa17fa0 100644
--- a/src/bin/projectclip.cpp
+++ b/src/bin/projectclip.cpp
@@ -271,9 +271,9 @@ void ProjectClip::setProducer(ClipController *controller, bool replaceProducer)
if (m_controller) {
// Replace clip for this controller
//m_controller->updateProducer(m_id, &(controller->originalProducer()));
- delete controller;
+ //delete controller;
}
- else {
+ else if (controller) {
// We did not yet have the controller, update info
m_controller = controller;
if (m_name.isEmpty()) m_name = m_controller->clipName();
diff --git a/src/mltcontroller/bincontroller.cpp b/src/mltcontroller/bincontroller.cpp
index fc664ce..a391ef7 100644
--- a/src/mltcontroller/bincontroller.cpp
+++ b/src/mltcontroller/bincontroller.cpp
@@ -118,6 +118,14 @@ void BinController::initializeBin(Mlt::Playlist playlist)
else {
// Controller has not been created yet
ClipController *controller = new ClipController(this, producer->parent());
+ // fix MLT somehow adding root to color producer's resource (report upstream)
+ if (strcmp(producer->parent().get("mlt_service"), "color") == 0) {
+ QString color = producer->parent().get("resource");
+ if (color.contains("/")) {
+ color = color.section("/", -1, -1);
+ producer->parent().set("resource", color.toUtf8().constData());
+ }
+ }
m_clipList.insert(id, controller);
}
}
@@ -214,8 +222,10 @@ void BinController::replaceProducer(const QString &id, Mlt::Producer &producer)
return;
}
ctrl->updateProducer(id, &producer);
+ emit prepareTimelineReplacement(id);
replaceBinPlaylistClip(id, producer);
producer.set("id", id.toUtf8().constData());
+ removeBinPlaylistClip("#" + id);
emit replaceTimelineProducer(id);
}
diff --git a/src/mltcontroller/bincontroller.h b/src/mltcontroller/bincontroller.h
index e435ec5..ffea410 100644
--- a/src/mltcontroller/bincontroller.h
+++ b/src/mltcontroller/bincontroller.h
@@ -194,6 +194,8 @@ signals:
void replaceTimelineProducer(const QString &id);
void setDocumentNotes(const QString &);
void updateTimelineProducer(const QString &);
+ /** @brief We want to replace a clip with another, but before we need to change clip producer id so that there is no interference*/
+ void prepareTimelineReplacement(const QString &);
};
#endif
diff --git a/src/monitor/monitor.cpp b/src/monitor/monitor.cpp
index faf9319..dadc4ce 100644
--- a/src/monitor/monitor.cpp
+++ b/src/monitor/monitor.cpp
@@ -1023,7 +1023,7 @@ void Monitor::updateClipProducer(const QString &playlist)
render->play(1.0);
}
-void Monitor::openClip(ClipController *controller)
+void Monitor::slotOpenClip(ClipController *controller, int in, int out)
{
if (render == NULL) return;
bool sameClip = controller == m_controller && controller != NULL;
@@ -1037,7 +1037,11 @@ void Monitor::openClip(ClipController *controller)
return;
}
updateMarkers();
- render->setProducer(m_controller->masterProducer(), -1, isActive());
+ render->setProducer(m_controller->masterProducer(), in, isActive());
+ if (out > -1) {
+ m_ruler->setZone(in, out);
+ setClipZone(QPoint(in, out));
+ }
}
else {
render->setProducer(NULL, -1, isActive());
@@ -1053,21 +1057,6 @@ void Monitor::openClip(ClipController *controller)
}
}
-void Monitor::openClipZone(ClipController *controller, int in, int out)
-{
- if (render == NULL) return;
- m_controller = controller;
- if (controller) {
- //render->setProducer(m_controller->zoneProducer(in, out), -1, isActive());
- render->setProducer(m_controller->masterProducer(), in, isActive());
- m_ruler->setZone(in, out);
- setClipZone(QPoint(in, out));
- }
- else {
- render->setProducer(NULL, -1, isActive());
- }
-}
-
const QString Monitor::activeClipId()
{
if (m_controller) {
@@ -1353,7 +1342,7 @@ void Monitor::reloadProducer(const QString &id)
{
if (!m_controller) return;
if (m_controller->clipId() == id)
- openClip(m_controller);
+ slotOpenClip(m_controller);
}
QString Monitor::getMarkerThumb(GenTime pos)
@@ -1511,7 +1500,7 @@ bool Monitor::startCapture(const QString &params, const QString &path, Mlt::Prod
bool Monitor::stopCapture()
{
m_glMonitor->stopCapture();
- openClip(NULL);
+ slotOpenClip(NULL);
m_glMonitor->reconfigure(m_monitorManager->profile());
return true;
}
diff --git a/src/monitor/monitor.h b/src/monitor/monitor.h
index 35fa817..975926a 100644
--- a/src/monitor/monitor.h
+++ b/src/monitor/monitor.h
@@ -202,8 +202,7 @@ public slots:
//void slotSetClipProducer(DocClipBase *clip, QPoint zone = QPoint(), bool forceUpdate = false, int position = -1);
void updateClipProducer(Mlt::Producer *prod);
void updateClipProducer(const QString &playlist);
- void openClip(ClipController *controller);
- void openClipZone(ClipController *controller, int in, int out);
+ void slotOpenClip(ClipController *controller, int in = -1, int out = -1);
void refreshMonitor(bool visible);
void refreshMonitor();
void slotSeek(int pos);
diff --git a/src/monitor/recmanager.cpp b/src/monitor/recmanager.cpp
index 76803b0..1075c0e 100644
--- a/src/monitor/recmanager.cpp
+++ b/src/monitor/recmanager.cpp
@@ -369,7 +369,7 @@ void RecManager::slotPreview(bool preview)
m_monitor->updateClipProducer(prod);
}
else {
- m_monitor->openClip(NULL);
+ m_monitor->slotOpenClip(NULL);
}
}
diff --git a/src/project/projectmanager.cpp b/src/project/projectmanager.cpp
index af5cd39..9570948 100644
--- a/src/project/projectmanager.cpp
+++ b/src/project/projectmanager.cpp
@@ -201,7 +201,7 @@ bool ProjectManager::closeCurrentDocument(bool saveChanges, bool quit)
if (!quit && !qApp->isSavingSession()) {
m_autoSaveTimer.stop();
pCore->window()->slotTimelineClipSelected(NULL, false);
- pCore->monitorManager()->clipMonitor()->openClip(NULL);
+ pCore->monitorManager()->clipMonitor()->slotOpenClip(NULL);
delete m_project;
m_project = NULL;
pCore->monitorManager()->setDocument(m_project);
diff --git a/src/renderer.cpp b/src/renderer.cpp
index 5beabc5..4fca72d 100644
--- a/src/renderer.cpp
+++ b/src/renderer.cpp
@@ -102,6 +102,7 @@ Render::Render(Kdenlive::MonitorId rendererName, BinController *binController, G
connect(this, SIGNAL(multiStreamFound(QString,QList<int>,QList<int>,stringMap)), this, SLOT(slotMultiStreamProducerFound(QString,QList<int>,QList<int>,stringMap)));
connect(this, SIGNAL(checkSeeking()), this, SLOT(slotCheckSeeking()));
if (m_name == Kdenlive::ProjectMonitor) {
+ connect(m_binController, SIGNAL(prepareTimelineReplacement(QString)), this, SIGNAL(prepareTimelineReplacement(QString)), Qt::DirectConnection);
connect(m_binController, SIGNAL(replaceTimelineProducer(QString)), this, SIGNAL(replaceTimelineProducer(QString)));
connect(m_binController, SIGNAL(updateTimelineProducer(QString)), this, SIGNAL(updateTimelineProducer(QString)));
connect(m_binController, SIGNAL(createThumb(QDomElement,QString,int)), this, SLOT(getFileProperties(QDomElement,QString,int)));
diff --git a/src/renderer.h b/src/renderer.h
index fe8290c..7757c5c 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -453,6 +453,8 @@ signals:
void activateMonitor(Kdenlive::MonitorId);
void mltFrameReceived(Mlt::Frame *);
void infoProcessingFinished();
+ /** @brief We want to replace a clip with another, but before we need to change clip producer id so that there is no interference*/
+ void prepareTimelineReplacement(const QString &);
public slots:
diff --git a/src/timeline/customtrackview.cpp b/src/timeline/customtrackview.cpp
index 9a17183..01135e7 100644
--- a/src/timeline/customtrackview.cpp
+++ b/src/timeline/customtrackview.cpp
@@ -163,7 +163,7 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, Timeline *timeline, CustomTra
QIcon razorIcon = QIcon::fromTheme("edit-cut");
m_razorCursor = QCursor(razorIcon.pixmap(32, 32));
m_spacerCursor = QCursor(Qt::SplitHCursor);
-
+ connect(m_document->renderer(), SIGNAL(prepareTimelineReplacement(QString)), this, SLOT(slotPrepareTimelineReplacement(QString)), Qt::DirectConnection);
connect(m_document->renderer(), SIGNAL(replaceTimelineProducer(QString)), this, SLOT(slotReplaceTimelineProducer(QString)));
connect(m_document->renderer(), SIGNAL(updateTimelineProducer(QString)), this, SLOT(slotUpdateTimelineProducer(QString)));
connect(m_document->renderer(), SIGNAL(rendererPosition(int)), this, SLOT(setCursorPos(int)));
@@ -7437,6 +7437,13 @@ void CustomTrackView::slotReplaceTimelineProducer(const QString &id)
}
}
+void CustomTrackView::slotPrepareTimelineReplacement(const QString &id)
+{
+ for (int i = 0; i < m_timeline->tracksCount(); i++) {
+ m_timeline->track(i)->replaceId(id);
+ }
+}
+
void CustomTrackView::slotUpdateTimelineProducer(const QString &id)
{
Mlt::Producer *prod = m_document->renderer()->getBinProducer(id);
diff --git a/src/timeline/customtrackview.h b/src/timeline/customtrackview.h
index eb3a1cb..4816994 100644
--- a/src/timeline/customtrackview.h
+++ b/src/timeline/customtrackview.h
@@ -499,6 +499,7 @@ private slots:
void slotGotFilterJobResults(const QString &id, int startPos, int track, stringMap filterParams, stringMap extra);
/** @brief Replace a producer in all tracks (for example when proxying a clip). */
void slotReplaceTimelineProducer(const QString &id);
+ void slotPrepareTimelineReplacement(const QString &id);
/** @brief Update a producer in all tracks (for example when an effect changed). */
void slotUpdateTimelineProducer(const QString &id);
diff --git a/src/timeline/timeline.cpp b/src/timeline/timeline.cpp
index 592d78c..12fa20b 100644
--- a/src/timeline/timeline.cpp
+++ b/src/timeline/timeline.cpp
@@ -760,6 +760,7 @@ void Timeline::adjustTrackHeaders()
int Timeline::addTrack(int ix, Mlt::Playlist &playlist) {
// parse track
int position = 0;
+ double fps = m_doc->fps();
bool locked = playlist.get_int("kdenlive:locked_track") == 1;
for(int i = 0; i < playlist.count(); ++i) {
Mlt::Producer *clip = playlist.get_clip(i);
@@ -771,7 +772,6 @@ int Timeline::addTrack(int ix, Mlt::Playlist &playlist) {
int in = clip->get_in();
int out = clip->get_out();
QString idString = clip->parent().get("id");
- qDebug()<<"***** LOADING: "<<idString<<"\n"<<clip->get("id")<<"\n**********";
if (in >= out || m_invalidProducers.contains(idString)) {
m_documentErrors.append(i18n("Invalid clip removed from track %1 at %2\n", ix, position));
playlist.remove(i);
@@ -796,22 +796,27 @@ int Timeline::addTrack(int ix, Mlt::Playlist &playlist) {
m_doc->renderer()->storeSlowmotionProducer(idString, &clip->parent());
}
id = id.section('_', 0, 0);
+ int length = out - in + 1;
ProjectClip *binclip = m_doc->getBinClip(id);
- if (binclip == NULL) continue;
- double fps = m_doc->fps();
- int length = out - in + 1;
+ if (binclip == NULL) {
+ // Warning, unknown clip found, timeline corruption!!
+
+ //TODO: fix this
+ position += length;
+ continue;
+ }
ItemInfo clipinfo;
clipinfo.startPos = GenTime(position, fps);
clipinfo.endPos = GenTime(position + length, fps);
clipinfo.cropStart = GenTime(in, fps);
clipinfo.cropDuration = GenTime(length, fps);
clipinfo.track = ix;
+ position += length;
qDebug()<<"// Loading clip: "<<idString<<" / SPEED: "<<speed<<"\n++++++++++++++++++++++++";
ClipItem *item = new ClipItem(binclip, clipinfo, fps, speed, strobe, m_trackview->getFrameWidth(), true);
item->updateState(idString);
m_scene->addItem(item);
if (locked) item->setItemLocked(true);
- position += length;
if (speed != 1.0 || strobe > 1) {
QDomElement speedeffect = MainWindow::videoEffects.getEffectByTag(QString(), "speed").cloneNode().toElement();
EffectsList::setParameter(speedeffect, "speed", QString::number((int)(100 * speed + 0.5)));
diff --git a/src/timeline/track.cpp b/src/timeline/track.cpp
index 23ac4a4..08cd54a 100644
--- a/src/timeline/track.cpp
+++ b/src/timeline/track.cpp
@@ -253,6 +253,23 @@ bool Track::needsDuplicate(const QString &service) const
return (service.contains("avformat") || service.contains("consumer") || service.contains("xml"));
}
+void Track::replaceId(const QString &id)
+{
+ QString idForAudioTrack = id + QLatin1Char('_') + m_playlist.get("id") + "_audio";
+ QString idForVideoTrack = id + QLatin1Char('_') + m_playlist.get("id") + "_video";
+ QString idForTrack = id + QLatin1Char('_') + m_playlist.get("id");
+ //TODO: slowmotion
+ for (int i = 0; i < m_playlist.count(); i++) {
+ if (m_playlist.is_blank(i)) continue;
+ Mlt::Producer *p = m_playlist.get_clip(i);
+ QString current = p->parent().get("id");
+ if (current == id || current == idForTrack || current == idForAudioTrack || current == idForVideoTrack) {
+ current.prepend("#");
+ p->parent().set("id", current.toUtf8().constData());
+ }
+ }
+}
+
bool Track::replaceAll(const QString &id, Mlt::Producer *original, Mlt::Producer *videoOnlyProducer)
{
bool found = false;
@@ -273,14 +290,28 @@ bool Track::replaceAll(const QString &id, Mlt::Producer *original, Mlt::Producer
if (m_playlist.is_blank(i)) continue;
Mlt::Producer *p = m_playlist.get_clip(i);
QString current = p->parent().get("id");
+ if (!current.startsWith("#")) {
+ delete p;
+ continue;
+ }
+ current.remove(0, 1);
Mlt::Producer *cut = NULL;
if (idForAudioTrack.isEmpty()) {
if (current == idForTrack) {
// No duplication required
cut = original->cut(p->get_in(), p->get_out());
}
- else continue;
+ else {
+ delete p;
+ continue;
+ }
}
+ qDebug()<<"// CHKG: "<<current<<" = "<<id;
+ if (p->parent().get_int("audio_index") == -1 && current == id) {
+ // No audio - no duplication required
+
+ cut = original->cut(p->get_in(), p->get_out());
+ }
else if (current == idForTrack) {
// Use duplicate
if (trackProducer == NULL) {
diff --git a/src/timeline/track.h b/src/timeline/track.h
index 2bf8c4b..617a198 100644
--- a/src/timeline/track.h
+++ b/src/timeline/track.h
@@ -105,6 +105,8 @@ public:
* @param t is the cut time in playlist
* @return true if success */
bool cut(qreal t);
+ /** @brief prepends a dash to the clip's id to prepare for replacement */
+ void replaceId(const QString &id);
/** @brief replace all occurences of a clip in the track with another resource
* @param id is the clip id
* @param original is the original replacement clip