From 4e64f0a97a9e38f8ec2b5cfd925b8067b6b700f4 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Tue, 2 Dec 2008 18:43:48 +0000 Subject: [PATCH] Add / remove track now seems to work, still a few crashes if project monitor was not started svn path=/branches/KDE4/; revision=2747 --- src/customtrackview.cpp | 22 ++++---- src/customtrackview.h | 2 +- src/docclipbase.cpp | 13 +++-- src/moveclipcommand.cpp | 6 +-- src/moveclipcommand.h | 3 +- src/renderer.cpp | 108 ++++++++++++++++++++++++++++++---------- src/renderer.h | 5 +- 7 files changed, 111 insertions(+), 48 deletions(-) diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 393b9719..9259a573 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -796,7 +796,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) { endInfo.startPos = d.startPos(); endInfo.endPos = m_dragItem->endPos() + (endInfo.startPos - startInfo.startPos); endInfo.track = m_dragItem->track(); - MoveClipCommand *command = new MoveClipCommand(this, startInfo, endInfo, false, true); + MoveClipCommand *command = new MoveClipCommand(this, startInfo, endInfo, true); m_commandStack->push(command); } else { //TODO: move transition @@ -1346,8 +1346,10 @@ void CustomTrackView::addTrack(TrackInfo type, int ix) { if (item->type() == AVWIDGET) { ClipItem *clip = static_cast (item); // We add a move clip command so that we get the correct producer for new track number - /*if (clip->clipType() == AV || clip->clipType() == AUDIO) - moveClip(clipinfo, clipinfo, true);*/ + if (clip->clipType() == AV || clip->clipType() == AUDIO) { + m_document->renderer()->mltUpdateClipProducer((int)(m_scene->m_tracksList.count() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), clip->baseClip()->producer(clipinfo.track)); + kDebug() << "// UPDATING CLIP TO TRACK PROD: " << clipinfo.track; + } } else if (item->type() == TRANSITIONWIDGET) { Transition *tr = static_cast (item); int track = tr->transitionEndTrack(); @@ -1402,8 +1404,8 @@ void CustomTrackView::removeTrack(int ix) { ItemInfo clipinfo = clip->info(); kDebug() << "// CLIP TRK IS: " << clipinfo.track; // We add a move clip command so that we get the correct producer for new track number - /*if (clip->clipType() == AV || clip->clipType() == AUDIO) - moveClip(clipinfo, clipinfo, true);*/ + if (clip->clipType() == AV || clip->clipType() == AUDIO) + m_document->renderer()->mltUpdateClipProducer((int)(m_scene->m_tracksList.count() - clipinfo.track), clipinfo.startPos.frames(m_document->fps()), clip->baseClip()->producer(clipinfo.track)); } else if (children.at(i)->type() == TRANSITIONWIDGET) { Transition *tr = static_cast (children.at(i)); tr->updateItem(); @@ -1625,7 +1627,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { } } else { // undo last move and emit error message - MoveClipCommand *command = new MoveClipCommand(this, info, m_dragItemInfo, false, true); + MoveClipCommand *command = new MoveClipCommand(this, info, m_dragItemInfo, true); m_commandStack->push(command); emit displayMessage(i18n("Cannot move clip to position %1seconds", QString::number(m_dragItemInfo.startPos.seconds(), 'g', 2)), ErrorMessage); } @@ -1978,7 +1980,7 @@ Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) { return getTransitionItemAt(framepos, track); } -void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end, bool forceProducer) { +void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) { ClipItem *item = getClipItemAt((int) start.startPos.frames(m_document->fps()) + 1, start.track); if (!item) { emit displayMessage(i18n("Cannot move clip at time: %1s on track %2", QString::number(start.startPos.seconds(), 'g', 2), start.track), ErrorMessage); @@ -1987,7 +1989,7 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end, bool fo } //kDebug() << "----------------  Move CLIP FROM: " << startPos.x() << ", END:" << endPos.x() << ",TRACKS: " << startPos.y() << " TO " << endPos.y(); - bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - start.track), (int)(m_scene->m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()), item->baseClip()->producer(end.track), forceProducer); + bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - start.track), (int)(m_scene->m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps()), item->baseClip()->producer(end.track)); if (success) { item->setPos((int) end.startPos.frames(m_document->fps()), (int)(end.track * m_tracksHeight + 1)); if (item->baseClip()->isTransparent()) { @@ -2715,6 +2717,7 @@ void CustomTrackView::slotInsertTrack(int ix) { info.isBlind = false; } addTimelineTrack(ix, info); + m_document->setModified(true); /*AddTrackCommand* command = new AddTrackCommand(this, ix, info, true, true); m_commandStack->push(command);*/ } @@ -2726,6 +2729,7 @@ void CustomTrackView::slotDeleteTrack(int ix) { if (ok) { TrackInfo info = m_scene->m_tracksList.at(m_scene->m_tracksList.count() - ix); deleteTimelineTrack(ix, info); + m_document->setModified(true); /*AddTrackCommand* command = new AddTrackCommand(this, ix, info, false, true); m_commandStack->push(command);*/ } @@ -2757,7 +2761,7 @@ void CustomTrackView::deleteTimelineTrack(int ix, TrackInfo trackinfo) { for (int i = 0; i < selection.count(); i++) { if (selection.at(i)->type() == AVWIDGET) { ClipItem *item = static_cast (selection.at(i)); - new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), false, false, deleteTrack); + new AddTimelineClipCommand(this, item->xml(), item->clipProducer(), item->info(), item->effectList(), false, true, deleteTrack); m_scene->removeItem(item); delete item; item = NULL; diff --git a/src/customtrackview.h b/src/customtrackview.h index a07d4b8b..a95a15b5 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -52,7 +52,7 @@ public: void removeTrack(int ix); int cursorPos(); void checkAutoScroll(); - void moveClip(const ItemInfo start, const ItemInfo end, bool forceProducer); + void moveClip(const ItemInfo start, const ItemInfo end); /** move transition, startPos = (old start, old end), endPos = (new start, new end) */ void moveTransition(const ItemInfo start, const ItemInfo end); void resizeClip(const ItemInfo start, const ItemInfo end); diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index af567b60..5dc1b0f4 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -251,7 +251,7 @@ const QPixmap & DocClipBase::thumbnail() const { } void DocClipBase::updateAudioThumbnail(QMap > data) { - kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************"; + //kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************"; audioFrameChache = data; m_audioThumbCreated = true; emit gotAudioData(); @@ -371,25 +371,28 @@ QString DocClipBase::markerComment(GenTime t) { void DocClipBase::setProducer(Mlt::Producer *producer) { if (producer == NULL) return; QString id = producer->get("id"); - kDebug() << "// SET PRODUCER: " << id; if (id.contains('_')) { // this is a subtrack producer, insert it at correct place int pos = id.section('_', 1, 1).toInt(); - kDebug() << "// POS = " << pos << ", MAX: " << m_baseTrackProducers.count(); if (pos >= m_baseTrackProducers.count()) { while (m_baseTrackProducers.count() - 1 < pos) { m_baseTrackProducers.append(NULL); } } - kDebug() << "// POS = " << pos << ", NEW MAX: " << m_baseTrackProducers.count(); if (m_baseTrackProducers.at(pos) == NULL) m_baseTrackProducers[pos] = producer; - } else m_baseTrackProducers.append(producer); + } else { + if (m_baseTrackProducers.isEmpty()) m_baseTrackProducers.append(producer); + else if (m_baseTrackProducers.at(0) == NULL) m_baseTrackProducers[0] = producer; + } //m_clipProducer = producer; //m_clipProducer->set("transparency", m_properties.value("transparency").toInt()); if (m_thumbProd && !m_thumbProd->hasProducer()) m_thumbProd->setProducer(producer); } Mlt::Producer *DocClipBase::producer(int track) { + for (int i = 0; i < m_baseTrackProducers.count(); i++) { + if (m_baseTrackProducers.at(i)) kDebug() << "// PROD: " << i << ", ID: " << m_baseTrackProducers.at(i)->get("id"); + } if (track == -1 || (m_clipType != AUDIO && m_clipType != AV)) { if (m_baseTrackProducers.count() == 0) return NULL; int i; diff --git a/src/moveclipcommand.cpp b/src/moveclipcommand.cpp index 1cc459bb..5d9f91c7 100644 --- a/src/moveclipcommand.cpp +++ b/src/moveclipcommand.cpp @@ -21,7 +21,7 @@ #include "moveclipcommand.h" #include "customtrackview.h" -MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool forceProducer, bool doIt, QUndoCommand * parent) : QUndoCommand(parent), m_view(view), m_startPos(start), m_endPos(end), m_forceProducer(forceProducer), m_doIt(doIt) { +MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool doIt, QUndoCommand * parent) : QUndoCommand(parent), m_view(view), m_startPos(start), m_endPos(end), m_doIt(doIt) { setText(i18n("Move clip")); } @@ -30,13 +30,13 @@ MoveClipCommand::MoveClipCommand(CustomTrackView *view, const ItemInfo start, co void MoveClipCommand::undo() { // kDebug()<<"---- undoing action"; m_doIt = true; - m_view->moveClip(m_endPos, m_startPos, m_forceProducer); + m_view->moveClip(m_endPos, m_startPos); } // virtual void MoveClipCommand::redo() { kDebug() << "---- redoing action"; if (m_doIt) - m_view->moveClip(m_startPos, m_endPos, m_forceProducer); + m_view->moveClip(m_startPos, m_endPos); m_doIt = true; } diff --git a/src/moveclipcommand.h b/src/moveclipcommand.h index 6c785a8c..b1803ca4 100644 --- a/src/moveclipcommand.h +++ b/src/moveclipcommand.h @@ -32,7 +32,7 @@ class CustomTrackView; class MoveClipCommand : public QUndoCommand { public: - MoveClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool forceProducer, bool doIt, QUndoCommand * parent = 0); + MoveClipCommand(CustomTrackView *view, const ItemInfo start, const ItemInfo end, bool doIt, QUndoCommand * parent = 0); virtual void undo(); virtual void redo(); @@ -41,7 +41,6 @@ private: const ItemInfo m_startPos; const ItemInfo m_endPos; bool m_doIt; - bool m_forceProducer; }; #endif diff --git a/src/renderer.cpp b/src/renderer.cpp index bcd0d595..37011c5e 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -2099,12 +2099,52 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) { return true; } -bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd, Mlt::Producer *prod, bool forceProducer) { - return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps), prod, forceProducer); +bool Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd, Mlt::Producer *prod) { + return mltMoveClip(startTrack, endTrack, (int) moveStart.frames(m_fps), (int) moveEnd.frames(m_fps), prod); } -bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd, Mlt::Producer *prod, bool forceProducer) { +void Render::mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod) { + kDebug() << "NEW PROD ID: " << prod->get("id"); + m_mltConsumer->set("refresh", 0); + kDebug() << "// TRYING TO UPDATE CLIP at: " << pos << ", TK: " << track; + mlt_service_lock(m_mltConsumer->get_service()); + Mlt::Service service(m_mltProducer->parent().get_service()); + if (service.type() != tractor_type) kWarning() << "// TRACTOR PROBLEM"; + + Mlt::Tractor tractor(service); + Mlt::Producer trackProducer(tractor.track(track)); + Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); + int clipIndex = trackPlaylist.get_clip_index_at(pos + 1); + Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex)); + if (clipProducer.is_blank()) { + kDebug() << "// ERROR UPDATING CLIP PROD"; + mlt_service_unlock(m_mltConsumer->get_service()); + m_isBlocked = false; + return; + } + Mlt::Producer *clip = prod->cut(clipProducer.get_in(), clipProducer.get_out()); + + // move all effects to the correct producer + Mlt::Service clipService(clipProducer.get_service()); + Mlt::Service newClipService(clip->get_service()); + + int ct = 0; + Mlt::Filter *filter = clipService.filter(ct); + while (filter) { + if (filter->get("kdenlive_ix") != 0) { + clipService.detach(*filter); + newClipService.attach(*filter); + } else ct++; + filter = clipService.filter(ct); + } + + trackPlaylist.insert_at(pos, clip, 1); + mlt_service_unlock(m_mltConsumer->get_service()); + m_isBlocked = false; +} + +bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd, Mlt::Producer *prod) { m_isBlocked = true; m_mltConsumer->set("refresh", 0); @@ -2121,30 +2161,20 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn if (endTrack == startTrack) { //mlt_service_lock(service.get_service()); Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex)); - if (forceProducer) { - if (clipProducer.is_blank()) { - kDebug() << "// ERROR RESTTING CLIP PROD: " << moveEnd << ", TRK: " << startTrack; - mlt_service_unlock(m_mltConsumer->get_service()); - m_isBlocked = false; - return false; - } - trackPlaylist.insert(clipProducer, moveEnd, clipProducer.get_in(), clipProducer.get_out()); + if (!trackPlaylist.is_blank_at(moveEnd) || clipProducer.is_blank()) { + // error, destination is not empty + //int ix = trackPlaylist.get_clip_index_at(moveEnd); + kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd; + mlt_service_unlock(m_mltConsumer->get_service()); + m_isBlocked = false; + return false; } else { - if (!trackPlaylist.is_blank_at(moveEnd) || clipProducer.is_blank()) { - // error, destination is not empty - //int ix = trackPlaylist.get_clip_index_at(moveEnd); - kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd; - mlt_service_unlock(m_mltConsumer->get_service()); - m_isBlocked = false; - return false; - } else { - trackPlaylist.consolidate_blanks(0); - int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1); - /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) { - mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt()); - }*/ - if (newIndex + 1 == trackPlaylist.count()) checkLength = true; - } + trackPlaylist.consolidate_blanks(0); + int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1); + /*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) { + mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt()); + }*/ + if (newIndex + 1 == trackPlaylist.count()) checkLength = true; } //mlt_service_unlock(service.get_service()); } else { @@ -2669,8 +2699,34 @@ void Render::mltInsertTrack(int ix) { void Render::mltDeleteTrack(int ix) { QDomDocument doc; doc.setContent(sceneList(), false); + int tracksCount = doc.elementsByTagName("track").count() - 1; QDomNode track = doc.elementsByTagName("track").at(ix); QDomNode tractor = doc.elementsByTagName("tractor").at(0); + QDomNodeList transitions = doc.elementsByTagName("transition"); + for (int i = 0; i < transitions.count(); i++) { + QDomElement e = transitions.at(i).toElement(); + QDomNodeList props = e.elementsByTagName("property"); + QMap mappedProps; + for (int j = 0; j < props.count(); j++) { + QDomElement f = props.at(j).toElement(); + mappedProps.insert(f.attribute("name"), f.firstChild().nodeValue()); + } + if (mappedProps.value("mlt_service") == "mix" && mappedProps.value("b_track").toInt() == tracksCount) { + tractor.removeChild(transitions.at(i)); + } else if (mappedProps.value("mlt_service") != "mix" && mappedProps.value("b_track").toInt() >= ix) { + // Transition needs to be moved + int a_track = mappedProps.value("a_track").toInt(); + int b_track = mappedProps.value("b_track").toInt(); + if (a_track > 0) a_track --; + if (b_track > 0) b_track --; + for (int j = 0; j < props.count(); j++) { + QDomElement f = props.at(j).toElement(); + if (f.attribute("name") == "a_track") f.firstChild().setNodeValue(QString::number(a_track)); + else if (f.attribute("name") == "b_track") f.firstChild().setNodeValue(QString::number(b_track)); + } + + } + } tractor.removeChild(track); setSceneList(doc.toString(), m_framePosition); return; diff --git a/src/renderer.h b/src/renderer.h index cb5dcd2d..1d741826 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -154,8 +154,8 @@ Q_OBJECT public: int mltGetSpaceLength(const GenTime pos, int track); bool mltResizeClipEnd(ItemInfo info, GenTime clipDuration); bool mltResizeClipStart(ItemInfo info, GenTime diff); - bool mltMoveClip(int startTrack, int endTrack, GenTime pos, GenTime moveStart, Mlt::Producer *prod, bool forceProducer = false); - bool mltMoveClip(int startTrack, int endTrack, int pos, int moveStart, Mlt::Producer *prod, bool forceProducer = false); + bool mltMoveClip(int startTrack, int endTrack, GenTime pos, GenTime moveStart, Mlt::Producer *prod); + bool mltMoveClip(int startTrack, int endTrack, int pos, int moveStart, Mlt::Producer *prod); bool mltRemoveClip(int track, GenTime position); bool mltRemoveEffect(int track, GenTime position, QString index, bool doRefresh = true); bool mltAddEffect(int track, GenTime position, QHash args, bool doRefresh = true); @@ -173,6 +173,7 @@ Q_OBJECT public: void mltResizeTransparency(int oldStart, int newStart, int newEnd, int track, int id); void mltInsertTrack(int ix); void mltDeleteTrack(int ix); + void mltUpdateClipProducer(int track, int pos, Mlt::Producer *prod); /** Change speed of a clip in playlist. To do this, we create a new "framebuffer" producer. This new producer must have its "resource" param set to: video.mpg?0.6 where video.mpg is the path -- 2.39.2