From: Jean-Baptiste Mardelle Date: Sat, 10 May 2008 18:29:44 +0000 (+0000) Subject: * Revert to an easier MLT playlist manipulation now that MLT allows easy transition... X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=3590aa25ac215a03dab029270285190a37bc15ff;p=kdenlive * Revert to an easier MLT playlist manipulation now that MLT allows easy transition removal * Start implementing save/load project svn path=/branches/KDE4/; revision=2175 --- diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index 6feccc28..a47e6a70 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -52,6 +52,8 @@ QList ClipManager::documentClipList() { void ClipManager::addClip(DocClipBase *clip) { m_clipList.append(clip); + int id = clip->getId(); + if (id >= m_clipIdCounter) m_clipIdCounter = id + 1; } void ClipManager::slotDeleteClip(uint clipId) { @@ -78,10 +80,10 @@ DocClipBase *ClipManager::getClipAt(int pos) { } DocClipBase *ClipManager::getClipById(int clipId) { - kDebug() << "++++ CLIP MAN, LOOKING FOR CLIP ID: " << clipId; + //kDebug() << "++++ CLIP MAN, LOOKING FOR CLIP ID: " << clipId; for (int i = 0; i < m_clipList.count(); i++) { if (m_clipList.at(i)->getId() == clipId) { - kDebug() << "++++ CLIP MAN, FOUND FOR CLIP ID: " << clipId; + //kDebug() << "++++ CLIP MAN, FOUND FOR CLIP ID: " << clipId; return m_clipList.at(i); } } diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index 10bf7592..7532f0f9 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -368,6 +368,8 @@ QString DocClipBase::markerComment(GenTime t) { } void DocClipBase::setProperties(QMap properties) { + // changing clip type is not allowed + properties.remove("type"); QMapIterator i(properties); while (i.hasNext()) { i.next(); diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 1fe1bb32..63900522 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -48,7 +48,18 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, MltVideoPro QDomElement infoXml = infoXmlNode.toElement(); QString profilePath = infoXml.attribute("profile"); if (!profilePath.isEmpty()) setProfilePath(profilePath); - } + QDomNodeList producers = infoXmlNode.childNodes(); + QDomElement e; + for (int i = 0; i < producers.count(); i++) { + e = producers.item(i).cloneNode().toElement(); + if (!e.isNull() && e.tagName() == "kdenlive_producer") { + e.setTagName("producer"); + addClip(e, e.attribute("id").toInt()); + } + } + m_document.removeChild(infoXmlNode); + kDebug() << "Reading file: " << url.path() << ", found clips: " << producers.count(); + } else kWarning() << " NO KDENLIVE INFO FOUND IN FILE: " << url.path(); KIO::NetAccess::removeTempFile(tmpFile); } else { KMessageBox::error(parent, KIO::NetAccess::lastErrorString()); @@ -57,49 +68,46 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, MltVideoPro // Creating new document QDomElement westley = m_document.createElement("westley"); m_document.appendChild(westley); - QDomElement doc = m_document.createElement("kdenlivedoc"); - doc.setAttribute("version", "0.6"); - westley.appendChild(doc); - QDomElement props = m_document.createElement("properties"); - doc.setAttribute("width", m_width); - doc.setAttribute("height", m_height); - doc.setAttribute("projectfps", m_fps); - doc.appendChild(props); - - - /*QDomElement westley = m_document.createElement("westley"); - m_document.appendChild(westley);*/ - QDomElement tractor = m_document.createElement("tractor"); tractor.setAttribute("id", "maintractor"); QDomElement multitrack = m_document.createElement("multitrack"); QDomElement playlist = m_document.createElement("playlist"); - QDomElement producer = m_document.createElement("producer"); - /*producer.setAttribute("mlt_service", "colour"); - producer.setAttribute("colour", "red"); - playlist.appendChild(producer);*/ - multitrack.appendChild(playlist); - QDomElement playlist1 = m_document.createElement("playlist"); - playlist1.setAttribute("id", "playlist1"); - playlist1.setAttribute("hide", "video"); - multitrack.appendChild(playlist1); - QDomElement playlist2 = m_document.createElement("playlist"); - playlist2.setAttribute("id", "playlist2"); - playlist2.setAttribute("hide", "video"); - multitrack.appendChild(playlist2); - QDomElement playlist3 = m_document.createElement("playlist"); - multitrack.appendChild(playlist3); - playlist3.setAttribute("id", "playlist3"); - QDomElement playlist4 = m_document.createElement("playlist"); - multitrack.appendChild(playlist4); - playlist4.setAttribute("id", "playlist4"); - QDomElement playlist5 = m_document.createElement("playlist"); - multitrack.appendChild(playlist5); - playlist5.setAttribute("id", "playlist5"); - tractor.appendChild(multitrack); - - for (uint i = 2; i < 6 ; i++) { + playlist.setAttribute("id", "black_track"); + westley.appendChild(playlist); + + + // create playlists + int audiotracks = 2; + int videotracks = 3; + int total = audiotracks + videotracks + 1; + + for (int i = 1; i < total; i++) { + QDomElement playlist = m_document.createElement("playlist"); + playlist.setAttribute("id", "playlist" + QString::number(i)); + westley.appendChild(playlist); + } + + QDomElement track0 = m_document.createElement("track"); + track0.setAttribute("producer", "black_track"); + tractor.appendChild(track0); + + // create audio tracks + for (int i = 1; i < audiotracks + 1; i++) { + QDomElement track = m_document.createElement("track"); + track.setAttribute("producer", "playlist" + QString::number(i)); + track.setAttribute("hide", "video"); + tractor.appendChild(track); + } + + // create video tracks + for (int i = audiotracks + 1; i < total; i++) { + QDomElement track = m_document.createElement("track"); + track.setAttribute("producer", "playlist" + QString::number(i)); + tractor.appendChild(track); + } + + for (uint i = 2; i < total ; i++) { QDomElement transition = m_document.createElement("transition"); transition.setAttribute("in", "0"); //TODO: Make audio mix last for all project duration @@ -111,19 +119,10 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, MltVideoPro transition.setAttribute("internal_added", "237"); tractor.appendChild(transition); } - QDomElement playlistmain = m_document.createElement("playlist"); - playlistmain.setAttribute("id", "playlistmain"); - QDomElement playentry = m_document.createElement("entry"); - playentry.setAttribute("producer", "maintractor"); - playentry.setAttribute("in", "0"); - playentry.setAttribute("out", "15000"); - playlistmain.appendChild(playentry); - doc.appendChild(tractor); - doc.appendChild(playlistmain); - + westley.appendChild(tractor); } m_scenelist = m_document.toString(); - kDebug() << "scenelist" << m_scenelist; + // kDebug() << "scenelist" << m_scenelist; if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(30, true); else m_timecode.setFormat((int) m_fps); } @@ -134,12 +133,20 @@ KdenliveDoc::~KdenliveDoc() { } QDomElement KdenliveDoc::documentInfoXml() { - //QDomDocument doc; - QDomElement addedXml = m_document.createElement("kdenlive"); + QDomDocument doc; + QDomElement e; + QDomElement addedXml = doc.createElement("kdenlive"); addedXml.setAttribute("version", "0.7"); addedXml.setAttribute("profile", profilePath()); - kDebug() << m_document.toString(); - return m_document.documentElement(); + QList list = m_clipManager->documentClipList(); + for (int i = 0; i < list.count(); i++) { + e = list.at(i)->toXML(); + e.setTagName("kdenlive_producer"); + addedXml.appendChild(doc.importNode(e, true)); + } + + //kDebug() << m_document.toString(); + return addedXml; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b9bc5ae2..750920c9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -167,8 +167,8 @@ MainWindow::MainWindow(QWidget *parent) overviewDock = new QDockWidget(i18n("Project Overview"), this); overviewDock->setObjectName("project_overview"); - m_overView = new CustomTrackView(NULL, NULL, this); - overviewDock->setWidget(m_overView); + //m_overView = new CustomTrackView(NULL, NULL, this); + //overviewDock->setWidget(m_overView); addDockWidget(Qt::TopDockWidgetArea, overviewDock); setupActions(); @@ -829,7 +829,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha if (m_commandStack->isClean()) kDebug() << "//////////// UNDO STACK IS CLEAN"; else kDebug() << "//////////// UNDO STACK IS NOT CLEAN*******************"; - m_overView->setScene(trackView->projectScene()); + //m_overView->setScene(trackView->projectScene()); //m_overView->scale(m_overView->width() / trackView->duration(), m_overView->height() / (50 * trackView->tracksNumber())); //m_overView->fitInView(m_overView->itemAt(0, 50), Qt::KeepAspectRatio); diff --git a/src/monitor.cpp b/src/monitor.cpp index 3454e442..86c9cbaa 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -294,9 +294,9 @@ void Monitor::resetProfile(QString prof) { render->resetProfile(prof); } -void Monitor::saveSceneList(QString path, QDomElement e) { +void Monitor::saveSceneList(QString path, QDomElement info) { if (render == NULL) return; - render->saveSceneList(path, e); + render->saveSceneList(path, info); } MonitorRefresh::MonitorRefresh(QWidget* parent): QWidget(parent), m_renderer(NULL) { diff --git a/src/monitor.h b/src/monitor.h index 9e66b71d..cccb6392 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -94,7 +94,7 @@ public slots: void slotRewind(double speed = 0); void slotRewindOneFrame(); void slotForwardOneFrame(); - void saveSceneList(QString path, QDomElement e = QDomElement()); + void saveSceneList(QString path, QDomElement info = QDomElement()); signals: void renderPosition(int); diff --git a/src/renderer.cpp b/src/renderer.cpp index f2fcb0ef..749a45c3 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -597,7 +597,7 @@ QString Render::sceneList() { return result; } -void Render::saveSceneList(QString path, QDomElement addedXml) { +void Render::saveSceneList(QString path, QDomElement kdenliveData) { char *tmppath = decodedString("westley:" + path); Mlt::Consumer westleyConsumer(*m_mltProfile , tmppath); @@ -605,13 +605,17 @@ void Render::saveSceneList(QString path, QDomElement addedXml) { westleyConsumer.set("terminate_on_pause", 1); Mlt::Producer prod(m_mltProducer->get_producer()); westleyConsumer.connect(prod); + //prod.set("title", "kdenlive document"); + //westleyConsumer.listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show); westleyConsumer.start(); - if (!addedXml.isNull()) { + while (!westleyConsumer.is_stopped()) {} + if (!kdenliveData.isNull()) { // add Kdenlive specific tags QFile file(path); QDomDocument doc; - //doc.setContent(&file, false); - doc.appendChild(doc.importNode(addedXml, true)); + doc.setContent(&file, false); + QDomNode wes = doc.elementsByTagName("westley").at(0); + wes.appendChild(doc.importNode(kdenliveData, true)); file.close(); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { kWarning() << "////// ERROR writing to file: " << path; @@ -925,33 +929,22 @@ void Render::exportCurrentFrame(KUrl url, bool notify) { void Render::mltCheckLength(bool reload) { //kDebug()<<"checking track length: "<get_service()); - Mlt::Playlist prod(service); - Mlt::Service service_playlist(prod.get_clip(0)->get_service()); - Mlt::Producer producer_playlist(service_playlist); - - Mlt::Tractor tr(producer_playlist.parent()); - prod.remove(0); - prod.insert(tr, 0); - } - Mlt::Tractor *tractor = getTractor(); + Mlt::Service service(m_mltProducer->get_service()); + Mlt::Tractor tractor(service); - int trackNb = tractor->count(); + int trackNb = tractor.count(); double duration = 0; - double trackDuration = 0; + double trackDuration; if (trackNb == 1) { - Mlt::Producer trackProducer(tractor->track(0)); + Mlt::Producer trackProducer(tractor.track(0)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); duration = Mlt::Producer(trackPlaylist.get_producer()).get_playtime() - 1; - kDebug() << trackNb << " " << duration; m_mltProducer->set("out", duration); - emit durationChanged((int)duration); + emit durationChanged((int) duration); return; } while (trackNb > 1) { - Mlt::Producer trackProducer(tractor->track(trackNb - 1)); + Mlt::Producer trackProducer(tractor.track(trackNb - 1)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); trackDuration = Mlt::Producer(trackPlaylist.get_producer()).get_playtime() - 1; @@ -960,7 +953,7 @@ void Render::mltCheckLength(bool reload) { trackNb--; } - Mlt::Producer blackTrackProducer(tractor->track(0)); + Mlt::Producer blackTrackProducer(tractor.track(0)); Mlt::Playlist blackTrackPlaylist((mlt_playlist) blackTrackProducer.get_service()); double blackDuration = Mlt::Producer(blackTrackPlaylist.get_producer()).get_playtime() - 1; kDebug() << " / / /DURATON FOR TRACK 0 = " << blackDuration; @@ -985,32 +978,8 @@ void Render::mltCheckLength(bool reload) { m_mltProducer->set("out", duration); emit durationChanged((int)duration); } - if (tractor) - delete tractor; -} - -Mlt::Tractor* Render::getTractor() { - Mlt::Service s1(m_mltProducer->get_service()); - Mlt::Playlist pl(s1); - Mlt::Producer srv(pl.get_clip(0)->parent()); - Mlt::Tractor *tractor = new Mlt::Tractor(srv); - return tractor; } -Mlt::Playlist* Render::getPlaylist(int track) { - Mlt::Tractor *tractor = getTractor(); - - if (tractor) { - - Mlt::Producer trackProducer(tractor->track(track)); - Mlt::Service playlistservice(trackProducer.get_service()); - delete tractor; - return new Mlt::Playlist(playlistservice); - - } - return NULL; - -} void Render::mltInsertClip(int track, GenTime position, QDomElement element) { if (!m_mltProducer) { kDebug() << "PLAYLIST NOT INITIALISED //////"; @@ -1021,48 +990,37 @@ void Render::mltInsertClip(int track, GenTime position, QDomElement element) { kDebug() << "PLAYLIST BROKEN, CANNOT INSERT CLIP //////"; return; } - m_isBlocked = true; - // Mlt::Service service(parentProd.get_service()); - //Mlt::Tractor tractor(service); + Mlt::Service service(parentProd.get_service()); + Mlt::Tractor tractor(service); + + Mlt::Producer trackProducer(tractor.track(track)); + Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); QDomDocument doc; doc.appendChild(doc.importNode(element, true)); QString resource = doc.toString(); + char *tmp = decodedString(resource); + Mlt::Producer clip(*m_mltProfile, "westley-xml", tmp); + //clip.set_in_and_out(in.frames(m_fps), out.frames(m_fps)); + delete[] tmp; - kDebug() << "/////// ADDING CLIP TMLNE: " << resource << " ON TRACK: " << track; - //Mlt::Tractor *tractor = getTractor(); - //if (tractor) { - Mlt::Playlist *trackPlaylist = getPlaylist(track); - if (trackPlaylist) { - char *tmp = decodedString(resource); - Mlt::Producer clip(*m_mltProfile, "westley-xml", tmp); - //clip.set_in_and_out(in.frames(m_fps), out.frames(m_fps)); - delete[] tmp; - - trackPlaylist->insert_at((int)position.frames(m_fps), clip, 1); - //tractor->multitrack()->refresh(); - //tractor->refresh(); - if (track != 0) mltCheckLength(); - - - - delete trackPlaylist; - mltSavePlaylist(); - } - //delete tractor; - //} - m_isBlocked = false; + trackPlaylist.insert_at((int) position.frames(m_fps), clip, 1); + if (track != 0) mltCheckLength(); + tractor.multitrack()->refresh(); + tractor.refresh(); } void Render::mltCutClip(int track, GenTime position) { m_isBlocked = true; - Mlt::Playlist *trackPlaylist = getPlaylist(track); - if (trackPlaylist) { - trackPlaylist->split_at((int)position.frames(m_fps)); - trackPlaylist->consolidate_blanks(0); - kDebug() << "/ / / /CUTTING CLIP AT: " << position.frames(m_fps); - delete trackPlaylist; - } + + 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()); + trackPlaylist.split_at((int) position.frames(m_fps)); + trackPlaylist.consolidate_blanks(0); m_isBlocked = false; } @@ -1075,106 +1033,110 @@ void Render::mltUpdateClip(int track, GenTime position, QDomElement element) { void Render::mltRemoveClip(int track, GenTime position) { m_isBlocked = true; - Mlt::Playlist *trackPlaylist = getPlaylist(track); - if (trackPlaylist) { - int clipIndex = trackPlaylist->get_clip_index_at((int)position.frames(m_fps)); - //trackPlaylist.remove(clipIndex); - trackPlaylist->replace_with_blank(clipIndex); - trackPlaylist->consolidate_blanks(0); - if (track != 0) mltCheckLength(); - delete trackPlaylist; - } + + 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((int) position.frames(m_fps)); + trackPlaylist.replace_with_blank(clipIndex); + trackPlaylist.consolidate_blanks(0); + if (track != 0) mltCheckLength(); //emit durationChanged(); m_isBlocked = false; } void Render::mltRemoveEffect(int track, GenTime position, QString index, bool doRefresh) { - Mlt::Playlist *trackPlaylist = getPlaylist(track); - if (trackPlaylist) { - //int clipIndex = trackPlaylist.get_clip_index_at(position.frames(m_fps)); - Mlt::Producer *clip = trackPlaylist->get_clip_at((int)position.frames(m_fps)); - if (!clip) { - kDebug() << " / / / CANNOT FIND CLIP TO REMOVE EFFECT"; - return; - } - m_isBlocked = true; - Mlt::Service clipService(clip->get_service()); -// if (tag.startsWith("ladspa")) tag = "ladspa"; + Mlt::Service service(m_mltProducer->parent().get_service()); - int ct = 0; - Mlt::Filter *filter = clipService.filter(ct); - while (filter) { - if (index == "-1" || filter->get("kdenlive_ix") == index) {// && filter->get("kdenlive_id") == id) { - clipService.detach(*filter); - kDebug() << " / / / DLEETED EFFECT: " << ct; - } else ct++; - filter = clipService.filter(ct); - } - m_isBlocked = false; - if (doRefresh) refresh(); - delete trackPlaylist; + 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(position.frames(m_fps)); + Mlt::Producer *clip = trackPlaylist.get_clip_at((int) position.frames(m_fps)); + if (!clip) { + kDebug() << " / / / CANNOT FIND CLIP TO REMOVE EFFECT"; + return; + } + Mlt::Service clipService(clip->get_service()); +// if (tag.startsWith("ladspa")) tag = "ladspa"; + m_isBlocked = true; + int ct = 0; + Mlt::Filter *filter = clipService.filter(ct); + while (filter) { + if (index == "-1" || filter->get("kdenlive_ix") == index) {// && filter->get("kdenlive_id") == id) { + clipService.detach(*filter); + kDebug() << " / / / DLEETED EFFECT: " << ct; + } else ct++; + filter = clipService.filter(ct); } + m_isBlocked = false; + if (doRefresh) refresh(); } void Render::mltAddEffect(int track, GenTime position, QMap args, bool doRefresh) { - Mlt::Playlist *trackPlaylist = getPlaylist(track); - if (trackPlaylist) { - Mlt::Producer *clip = trackPlaylist->get_clip_at((int)position.frames(m_fps)); + Mlt::Service service(m_mltProducer->parent().get_service()); - if (!clip) { - kDebug() << "********** CANNOT FIND CLIP TO APPLY EFFECT-----------"; - return; - } - Mlt::Service clipService(clip->get_service()); - m_isBlocked = true; - // create filter - QString tag = args.value("tag"); - //kDebug()<<" / / INSERTING EFFECT: "<is_valid()) - filter->set("kdenlive_id", filterId); - else { - kDebug() << "filter is NULL"; - return; - } + Mlt::Tractor tractor(service); + Mlt::Producer trackProducer(tractor.track(track)); + Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); - QMap::Iterator it; - QString keyFrameNumber = "#0"; + Mlt::Producer *clip = trackPlaylist.get_clip_at((int) position.frames(m_fps)); - for (it = args.begin(); it != args.end(); ++it) { - //kDebug()<<" / / INSERTING EFFECT ARGS: "<set("kdenlive_id", filterId); - keyFrameNumber = currentKeyFrameNumber; - } - key = it.key().section(":", 1); - } else key = it.key(); - char *name = decodedString(key); - char *value = decodedString(it.value()); - filter->set(name, value); - delete[] name; - delete[] value; - } - // attach filter to the clip - clipService.attach(*filter); - delete[] filterId; + if (!clip) { + kDebug() << "********** CANNOT FIND CLIP TO APPLY EFFECT-----------"; + return; + } + Mlt::Service clipService(clip->get_service()); + m_isBlocked = true; + // create filter + QString tag = args.value("tag"); + //kDebug()<<" / / INSERTING EFFECT: "<is_valid()) + filter->set("kdenlive_id", filterId); + else { + kDebug() << "filter is NULL"; m_isBlocked = false; - if (doRefresh) refresh(); - delete trackPlaylist; + return; } + QMap::Iterator it; + QString keyFrameNumber = "#0"; + + for (it = args.begin(); it != args.end(); ++it) { + //kDebug()<<" / / INSERTING EFFECT ARGS: "<set("kdenlive_id", filterId); + keyFrameNumber = currentKeyFrameNumber; + } + key = it.key().section(":", 1); + } else key = it.key(); + char *name = decodedString(key); + char *value = decodedString(it.value()); + filter->set(name, value); + delete[] name; + delete[] value; + } + // attach filter to the clip + clipService.attach(*filter); + delete[] filterId; + m_isBlocked = false; + if (doRefresh) refresh(); } void Render::mltEditEffect(int track, GenTime position, QMap args) { @@ -1187,147 +1149,131 @@ void Render::mltEditEffect(int track, GenTime position, QMap mltAddEffect(track, position, args); return; } - m_isBlocked = true; + // create filter + Mlt::Service service(m_mltProducer->parent().get_service()); - Mlt::Playlist *trackPlaylist = getPlaylist(track); + 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(position.frames(m_fps)); - if (trackPlaylist) { - Mlt::Producer *clip = trackPlaylist->get_clip_at((int)position.frames(m_fps)); - if (!clip) { - kDebug() << "WARINIG, CANNOT FIND CLIP ON track: " << track << ", AT POS: " << position.frames(m_fps); - m_isBlocked = false; - return; - } - - Mlt::Service clipService(clip->get_service()); - -// if (tag.startsWith("ladspa")) tag = "ladspa"; - - int ct = 0; - Mlt::Filter *filter = clipService.filter(ct); - while (filter) { - if (filter->get("kdenlive_ix") == index) { - break; - } - ct++; - filter = clipService.filter(ct); + Mlt::Producer *clip = trackPlaylist.get_clip_at((int) position.frames(m_fps)); + if (!clip) { + kDebug() << "WARINIG, CANNOT FIND CLIP ON track: " << track << ", AT POS: " << position.frames(m_fps); + return; + } + Mlt::Service clipService(clip->get_service()); + m_isBlocked = true; + int ct = 0; + Mlt::Filter *filter = clipService.filter(ct); + while (filter) { + if (filter->get("kdenlive_ix") == index) { + break; } + ct++; + filter = clipService.filter(ct); + } - if (!filter) { - kDebug() << "WARINIG, FILTER FOR EDITING NOT FOUND, ADDING IT!!!!!"; - mltAddEffect(track, position, args); - m_isBlocked = false; - return; - } - - for (it = args.begin(); it != args.end(); ++it) { - kDebug() << " / / EDITING EFFECT ARGS: " << it.key() << ": " << it.value(); - char *name = decodedString(it.key()); - char *value = decodedString(it.value()); - filter->set(name, value); - delete[] name; - delete[] value; - } + if (!filter) { + kDebug() << "WARINIG, FILTER FOR EDITING NOT FOUND, ADDING IT!!!!!"; + mltAddEffect(track, position, args); m_isBlocked = false; - refresh(); - delete trackPlaylist; + return; + } + + for (it = args.begin(); it != args.end(); ++it) { + kDebug() << " / / EDITING EFFECT ARGS: " << it.key() << ": " << it.value(); + char *name = decodedString(it.key()); + char *value = decodedString(it.value()); + filter->set(name, value); + delete[] name; + delete[] value; } + m_isBlocked = false; + refresh(); } void Render::mltResizeClipEnd(int track, GenTime pos, GenTime in, GenTime out) { m_isBlocked = true; - Mlt::Playlist *trackPlaylist = getPlaylist(track); - if (trackPlaylist) { - //Mlt::Tractor *tractor = getTractor(); - if (trackPlaylist->is_blank_at((int)pos.frames(m_fps) + 1)) - kDebug() << "//////// ERROR RSIZING BLANK CLIP!!!!!!!!!!!"; - int clipIndex = trackPlaylist->get_clip_index_at((int)pos.frames(m_fps) + 1); - - int previousDuration = trackPlaylist->clip_length(clipIndex) - 1; - int newDuration = (int)(out.frames(m_fps) - 1); - - kDebug() << " ** RESIZING CLIP END:" << clipIndex << " on track:" << track << ", mid pos: " << pos.frames(25) << ", in: " << in.frames(25) << ", out: " << out.frames(25) << ", PREVIOUS duration: " << previousDuration; - trackPlaylist->resize_clip(clipIndex, (int)in.frames(m_fps), newDuration); - trackPlaylist->consolidate_blanks(0); - if (previousDuration < newDuration) { - // clip was made longer, trim next blank if there is one. - if (trackPlaylist->is_blank(clipIndex + 1)) { - trackPlaylist->split(clipIndex + 1, newDuration - previousDuration); - trackPlaylist->remove(clipIndex + 1); - } - } else trackPlaylist->insert_blank(clipIndex + 1, previousDuration - newDuration - 1); - - trackPlaylist->consolidate_blanks(0); - //tractor->multitrack()->refresh(); - //tractor->refresh(); - if (track != 0) mltCheckLength(); - //if (tractor) - // delete tractor; - m_isBlocked = false; - delete trackPlaylist; - } + Mlt::Service service(m_mltProducer->parent().get_service()); + + Mlt::Tractor tractor(service); + Mlt::Producer trackProducer(tractor.track(track)); + Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); + if (trackPlaylist.is_blank_at((int) pos.frames(m_fps) + 1)) + kDebug() << "//////// ERROR RSIZING BLANK CLIP!!!!!!!!!!!"; + int clipIndex = trackPlaylist.get_clip_index_at((int) pos.frames(m_fps) + 1); + + int previousDuration = trackPlaylist.clip_length(clipIndex) - 1; + int newDuration = (int) out.frames(m_fps) - 1; + + kDebug() << " ** RESIZING CLIP END:" << clipIndex << " on track:" << track << ", mid pos: " << pos.frames(25) << ", in: " << in.frames(25) << ", out: " << out.frames(25) << ", PREVIOUS duration: " << previousDuration; + trackPlaylist.resize_clip(clipIndex, (int) in.frames(m_fps), newDuration); + trackPlaylist.consolidate_blanks(0); + if (previousDuration < newDuration) { + // clip was made longer, trim next blank if there is one. + if (trackPlaylist.is_blank(clipIndex + 1)) { + trackPlaylist.split(clipIndex + 1, newDuration - previousDuration); + trackPlaylist.remove(clipIndex + 1); + } + } else trackPlaylist.insert_blank(clipIndex + 1, previousDuration - newDuration - 1); + + trackPlaylist.consolidate_blanks(0); + tractor.multitrack()->refresh(); + tractor.refresh(); + if (track != 0) mltCheckLength(); + m_isBlocked = false; } void Render::mltChangeTrackState(int track, bool mute, bool blind) { - - Mlt::Tractor *tractor = getTractor(); - if (tractor) { - Mlt::Producer trackProducer(tractor->track(track)); - if (mute) { - if (blind) trackProducer.set("hide", 3); - else trackProducer.set("hide", 2); - } else if (blind) { - trackProducer.set("hide", 1); - } else { - trackProducer.set("hide", 0); - } - //tractor->multitrack()->refresh(); - //tractor->refresh(); - //delete tractor; - refresh(); - delete tractor; - + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + Mlt::Producer trackProducer(tractor.track(track)); + Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); + if (mute) { + if (blind) trackProducer.set("hide", 3); + else trackProducer.set("hide", 2); + } else if (blind) { + trackProducer.set("hide", 1); + } else { + trackProducer.set("hide", 0); } + tractor.multitrack()->refresh(); + tractor.refresh(); + refresh(); } void Render::mltResizeClipStart(int track, GenTime pos, GenTime moveEnd, GenTime moveStart, GenTime in, GenTime out) { m_isBlocked = true; - int moveFrame = (int)((moveEnd - moveStart).frames(m_fps)); + Mlt::Service service(m_mltProducer->parent().get_service()); - Mlt::Playlist *trackPlaylist = getPlaylist(track); - if (trackPlaylist) { - if (trackPlaylist->is_blank_at((int)pos.frames(m_fps) - 1)) - kDebug() << "//////// ERROR RSIZING BLANK CLIP!!!!!!!!!!!"; - int clipIndex = trackPlaylist->get_clip_index_at((int)pos.frames(m_fps) - 1); - kDebug() << " ** RESIZING CLIP START:" << clipIndex << " on track:" << track << ", mid pos: " << pos.frames(25) << ", moving: " << moveFrame << ", in: " << in.frames(25) << ", out: " << out.frames(25); + int moveFrame = (int)(moveEnd - moveStart).frames(m_fps); - trackPlaylist->resize_clip(clipIndex, (int) in.frames(m_fps), (int)out.frames(m_fps)); - if (moveFrame > 0) trackPlaylist->insert_blank(clipIndex, moveFrame - 1); - else { - int midpos = (int)moveStart.frames(m_fps) - 1; //+ (moveFrame / 2) - int blankIndex = trackPlaylist->get_clip_index_at(midpos); - int blankLength = trackPlaylist->clip_length(blankIndex); + Mlt::Tractor tractor(service); + Mlt::Producer trackProducer(tractor.track(track)); + Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); + if (trackPlaylist.is_blank_at((int) pos.frames(m_fps) - 1)) + kDebug() << "//////// ERROR RSIZING BLANK CLIP!!!!!!!!!!!"; + int clipIndex = trackPlaylist.get_clip_index_at((int) pos.frames(m_fps) - 1); + kDebug() << " ** RESIZING CLIP START:" << clipIndex << " on track:" << track << ", mid pos: " << pos.frames(25) << ", moving: " << moveFrame << ", in: " << in.frames(25) << ", out: " << out.frames(25); - kDebug() << " + resizing blank: " << blankIndex << ", Mid: " << midpos << ", Length: " << blankLength << ", SIZE DIFF: " << moveFrame; + trackPlaylist.resize_clip(clipIndex, (int) in.frames(m_fps), (int) out.frames(m_fps)); + if (moveFrame > 0) trackPlaylist.insert_blank(clipIndex, moveFrame - 1); + else { + int midpos = (int)moveStart.frames(m_fps) - 1; //+ (moveFrame / 2) + int blankIndex = trackPlaylist.get_clip_index_at(midpos); + int blankLength = trackPlaylist.clip_length(blankIndex); + kDebug() << " + resizing blank: " << blankIndex << ", Mid: " << midpos << ", Length: " << blankLength << ", SIZE DIFF: " << moveFrame; - if (blankLength + moveFrame == 0) trackPlaylist->remove(blankIndex); - else trackPlaylist->resize_clip(blankIndex, 0, blankLength + moveFrame - 1); - } - trackPlaylist->consolidate_blanks(0); - m_isBlocked = false; - kDebug() << "-----------------\n" << "CLIP 0: " << trackPlaylist->clip_start(0) << ", LENGT: " << trackPlaylist->clip_length(0); - kDebug() << "CLIP 1: " << trackPlaylist->clip_start(1) << ", LENGT: " << trackPlaylist->clip_length(1); - kDebug() << "CLIP 2: " << trackPlaylist->clip_start(2) << ", LENGT: " << trackPlaylist->clip_length(2); - kDebug() << "CLIP 3: " << trackPlaylist->clip_start(3) << ", LENGT: " << trackPlaylist->clip_length(3); - kDebug() << "CLIP 4: " << trackPlaylist->clip_start(4) << ", LENGT: " << trackPlaylist->clip_length(4); - - delete trackPlaylist; + if (blankLength + moveFrame == 0) trackPlaylist.remove(blankIndex); + else trackPlaylist.resize_clip(blankIndex, 0, blankLength + moveFrame - 1); } + trackPlaylist.consolidate_blanks(0); + m_isBlocked = false; } void Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTime moveEnd) { @@ -1337,89 +1283,85 @@ void Render::mltMoveClip(int startTrack, int endTrack, GenTime moveStart, GenTim void Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEnd) { m_isBlocked = true; - //m_mltConsumer->set("refresh", 0); - Mlt::Tractor *tractor = getTractor(); - if (tractor) { - Mlt::Producer trackProducer(tractor->track(startTrack)); - Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); - int clipIndex = trackPlaylist.get_clip_index_at(moveStart + 1); - mlt_field field = mlt_tractor_field(tractor->get_tractor()); - mlt_multitrack multitrack = mlt_field_multitrack(field); //mlt_tractor_multitrack(tractor.get_tractor()); - kDebug() << " -- CURRENT MULTIOTRACK HAS: " << mlt_multitrack_count(multitrack) << " tracks";; - mlt_service multiprod = mlt_multitrack_service(multitrack); - - Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex)); - trackPlaylist.consolidate_blanks(1); - mlt_events_block(MLT_PRODUCER_PROPERTIES(trackProducer.get_producer()), NULL); - - if (endTrack == startTrack) { - if (!trackPlaylist.is_blank_at(moveEnd)) { - kWarning() << "// ERROR, CLIP COLLISION----------"; - int ix = trackPlaylist.get_clip_index_at(moveEnd); - kDebug() << "BAD CLIP STARTS AT: " << trackPlaylist.clip_start(ix) << ", LENGT: " << trackPlaylist.clip_length(ix); - } - trackPlaylist.insert_at(moveEnd, clipProducer, 1); - trackPlaylist.consolidate_blanks(0); - } else { - trackPlaylist.consolidate_blanks(0); - Mlt::Producer destTrackProducer(tractor->track(endTrack)); - Mlt::Playlist destTrackPlaylist((mlt_playlist) destTrackProducer.get_service()); - destTrackPlaylist.consolidate_blanks(1); - destTrackPlaylist.insert_at(moveEnd, clipProducer, 1); - destTrackPlaylist.consolidate_blanks(0); - } - mltCheckLength(); - mlt_events_unblock(MLT_PRODUCER_PROPERTIES(trackProducer.get_producer()), NULL); - m_isBlocked = false; - m_mltConsumer->set("refresh", 1); - delete tractor; + m_mltConsumer->set("refresh", 0); + + 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(startTrack)); + Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); + int clipIndex = trackPlaylist.get_clip_index_at(moveStart + 1); + + Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex)); + trackPlaylist.consolidate_blanks(0); + //mlt_events_block( MLT_PRODUCER_PROPERTIES(clipProducer.get_producer()), NULL ); + + if (endTrack == startTrack) { + if (!trackPlaylist.is_blank_at(moveEnd)) { + kWarning() << "// ERROR, CLIP COLLISION----------"; + int ix = trackPlaylist.get_clip_index_at(moveEnd); + kDebug() << "BAD CLIP STARTS AT: " << trackPlaylist.clip_start(ix) << ", LENGT: " << trackPlaylist.clip_length(ix); + } + trackPlaylist.insert_at(moveEnd, clipProducer, 1); + trackPlaylist.consolidate_blanks(0); + } else { + trackPlaylist.consolidate_blanks(0); + Mlt::Producer destTrackProducer(tractor.track(endTrack)); + Mlt::Playlist destTrackPlaylist((mlt_playlist) destTrackProducer.get_service()); + destTrackPlaylist.consolidate_blanks(1); + destTrackPlaylist.insert_at(moveEnd, clipProducer, 1); + destTrackPlaylist.consolidate_blanks(0); } + + mltCheckLength(); + m_isBlocked = false; + m_mltConsumer->set("refresh", 1); + //mlt_events_unblock( MLT_PRODUCER_PROPERTIES(clipProducer.get_producer()), NULL ); } void Render::mltMoveTransition(QString type, int startTrack, int trackOffset, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut) { m_isBlocked = true; - m_mltConsumer->set("refresh", 0); + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + Mlt::Field *field = tractor.field(); - Mlt::Tractor *tractor = getTractor(); - if (tractor) { - Mlt::Tractor newTractor; - mlt_service service = tractor->get_service(); - mlt_service nextservice = mlt_service_get_producer(service); - mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); - QString mlt_type = mlt_properties_get(properties, "mlt_type"); - QString resource = mlt_properties_get(properties, "mlt_service"); - int old_pos = (int)(oldIn.frames(m_fps) + oldOut.frames(m_fps)) / 2; - - int new_in = (int)newIn.frames(m_fps); - int new_out = (int)newOut.frames(m_fps) - 1; - while (mlt_type == "transition") { - mlt_transition tr = (mlt_transition) nextservice; - int currentTrack = mlt_transition_get_b_track(tr); - int currentIn = (int) mlt_transition_get_in(tr); - int currentOut = (int) mlt_transition_get_out(tr); - - //kDebug() << "// OLD IN: " << oldIn.frames(m_fps) << " // OLD OUT: " << oldOut.frames(m_fps) << ", TRACK: " << startTrack << ", CURR TRANS: " <= old_pos) { - //kDebug() << "// FOUND EXISTING TRANS, IN: " << type << resource << currentIn << ", OUT: " << currentOut << ", TRACK: " << currentTrack; - mlt_transition_set_in_and_out(tr, new_in, new_out); - if (trackOffset != 0) { - mlt_properties properties = MLT_TRANSITION_PROPERTIES(tr); - mlt_properties_set_int(properties, "a_track", mlt_transition_get_a_track(tr) + trackOffset); - mlt_properties_set_int(properties, "b_track", mlt_transition_get_b_track(tr) + trackOffset); - //kDebug() << "set new start & end :" << new_in << new_out<< "TR OFFSET: "<set("refresh", 0); + mlt_service serv = m_mltProducer->parent().get_service(); + + mlt_service nextservice = mlt_service_get_producer(serv); + mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); + QString mlt_type = mlt_properties_get(properties, "mlt_type"); + QString resource = mlt_properties_get(properties, "mlt_service"); + int old_pos = (int)(oldIn.frames(m_fps) + oldOut.frames(m_fps)) / 2; + + int new_in = (int)newIn.frames(m_fps); + int new_out = (int)newOut.frames(m_fps) - 1; + + while (mlt_type == "transition") { + mlt_transition tr = (mlt_transition) nextservice; + int currentTrack = mlt_transition_get_b_track(tr); + int currentIn = (int) mlt_transition_get_in(tr); + int currentOut = (int) mlt_transition_get_out(tr); + + if (resource == type && startTrack == currentTrack && currentIn <= old_pos && currentOut >= old_pos) { + mlt_transition_set_in_and_out(tr, new_in, new_out); + if (trackOffset != 0) { + mlt_properties properties = MLT_TRANSITION_PROPERTIES(tr); + mlt_properties_set_int(properties, "a_track", mlt_transition_get_a_track(tr) + trackOffset); + mlt_properties_set_int(properties, "b_track", mlt_transition_get_b_track(tr) + trackOffset); + //kDebug() << "set new start & end :" << new_in << new_out<< "TR OFFSET: "<set("refresh", 1); } @@ -1435,111 +1377,86 @@ void Render::mltUpdateTransition(QString oldTag, QString tag, int a_track, int b void Render::mltUpdateTransitionParams(QString type, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml) { m_isBlocked = true; - m_mltConsumer->set("refresh", 0); - Mlt::Tractor *tractor = getTractor(); - if (tractor) { - Mlt::Tractor newTractor; - mlt_service service = tractor->get_service(); - mlt_service nextservice = mlt_service_get_producer(service); - mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); - QString mlt_type = mlt_properties_get(properties, "mlt_type"); - QString resource = mlt_properties_get(properties, "mlt_service"); - int in_pos = (int) in.frames(m_fps); - int out_pos = (int) out.frames(m_fps); - - while (mlt_type == "transition") { - mlt_transition tr = (mlt_transition) nextservice; - int currentTrack = mlt_transition_get_b_track(tr); - int currentIn = (int) mlt_transition_get_in(tr); - int currentOut = (int) mlt_transition_get_out(tr); - kDebug() << "TRACK: " << b_track << " / " << currentTrack << ", CURR TRANS: " << currentIn << "x" << currentOut << ", LOOKING OFR: " << in_pos << "x" << out_pos; - if (resource == type && b_track == currentTrack && currentIn == in_pos && currentOut == out_pos) { - QMap map = mltGetTransitionParamsFromXml(xml); - QMap::Iterator it; - QString key; - mlt_properties transproperties = MLT_TRANSITION_PROPERTIES(tr); - - for (it = map.begin(); it != map.end(); ++it) { - key = it.key(); - char *name = decodedString(key); - char *value = decodedString(it.value()); - mlt_properties_set(transproperties, name, value); - kDebug() << " ------ UPDATING TRANS PARAM: " << name << ": " << value; - //filter->set("kdenlive_id", id); - delete[] name; - delete[] value; - } - break; + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + Mlt::Field *field = tractor.field(); + + m_mltConsumer->set("refresh", 0); + mlt_service serv = m_mltProducer->parent().get_service(); + + mlt_service nextservice = mlt_service_get_producer(serv); + mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); + QString mlt_type = mlt_properties_get(properties, "mlt_type"); + QString resource = mlt_properties_get(properties, "mlt_service"); + int in_pos = (int) in.frames(m_fps); + int out_pos = (int) out.frames(m_fps); + + while (mlt_type == "transition") { + mlt_transition tr = (mlt_transition) nextservice; + int currentTrack = mlt_transition_get_b_track(tr); + int currentIn = (int) mlt_transition_get_in(tr); + int currentOut = (int) mlt_transition_get_out(tr); + + if (resource == type && b_track == currentTrack && currentIn == in_pos && currentOut == out_pos) { + QMap map = mltGetTransitionParamsFromXml(xml); + QMap::Iterator it; + QString key; + mlt_properties transproperties = MLT_TRANSITION_PROPERTIES(tr); + + for (it = map.begin(); it != map.end(); ++it) { + key = it.key(); + char *name = decodedString(key); + char *value = decodedString(it.value()); + mlt_properties_set(transproperties, name, value); + kDebug() << " ------ UPDATING TRANS PARAM: " << name << ": " << value; + //filter->set("kdenlive_id", id); + delete[] name; + delete[] value; } - nextservice = mlt_service_producer(nextservice); - properties = MLT_SERVICE_PROPERTIES(nextservice); - mlt_type = mlt_properties_get(properties, "mlt_type"); - resource = mlt_properties_get(properties, "mlt_service"); + break; } - m_isBlocked = false; - delete tractor; + nextservice = mlt_service_producer(nextservice); + properties = MLT_SERVICE_PROPERTIES(nextservice); + mlt_type = mlt_properties_get(properties, "mlt_type"); + resource = mlt_properties_get(properties, "mlt_service"); } + m_isBlocked = false; m_mltConsumer->set("refresh", 1); } -void Render::replaceTimelineTractor(Mlt::Tractor t) { - Mlt::Service service(m_mltProducer->get_service()); - Mlt::Playlist prod(service); - Mlt::Service service_playlist(prod.get_clip(0)->get_service()); - prod.remove(0); - prod.insert(t, 0); - kDebug() << "newTractor inserted"; -} - void Render::mltDeleteTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool do_refresh) { - Mlt::Tractor *tractor = getTractor(); - if (tractor) { - Mlt::Tractor newTractor; - mlt_service service = tractor->get_service(); - mlt_service nextservice = mlt_service_get_producer(service); - int old_position = m_mltProducer->position(); - for (int track = 0;track < 10;track++) { - Mlt::Producer *trackprod = tractor->track(track); - if (!trackprod) - continue; - newTractor.multitrack()->connect(*trackprod, track); - } - for (int i = 2;i <= 5;i++) { - Mlt::Transition tr(*m_mltProfile, "mix"); - tr.set("combine", 1); - tr.set("internal_added", 237); - tr.set_in_and_out(0, 15000); - newTractor.plant_transition(tr, 1, i); - } - while (nextservice != NULL) { - mlt_properties prop = MLT_SERVICE_PROPERTIES(nextservice); - //kDebug() << mlt_properties_get(prop, "mlt_type") << mlt_properties_get(prop, "id"); - if (QString(mlt_properties_get(prop, "mlt_type")) == "transition" && QString(mlt_properties_get(prop, "internal_added")) != "237") { - - mlt_transition tr = (mlt_transition) nextservice; - Mlt::Transition transition(tr); - int current_a_track = mlt_transition_get_a_track(tr); - int current_b_track = mlt_transition_get_b_track(tr); - int currentIn = (int) mlt_transition_get_in(tr); - int currentOut = (int) mlt_transition_get_out(tr); - int old_pos = (int)((in.frames(m_fps) + out.frames(m_fps)) / 2); - kDebug() << current_a_track << current_b_track << a_track << b_track << currentIn << currentOut << old_pos << mlt_properties_get(prop, "mlt_service"); - if (current_a_track == a_track && b_track == current_b_track && currentIn <= old_pos && currentOut >= old_pos) { - kDebug() << "removing " << mlt_properties_get(prop, "mlt_service"); - } else - newTractor.plant_transition(transition, current_a_track, current_b_track); - } - nextservice = mlt_service_producer(nextservice); - } + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + Mlt::Field *field = tractor.field(); - replaceTimelineTractor(newTractor); - m_mltProducer->seek(old_position); - delete tractor; - if (do_refresh) refresh(); + m_mltConsumer->set("refresh", 0); + mlt_service serv = m_mltProducer->parent().get_service(); + + mlt_service nextservice = mlt_service_get_producer(serv); + mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); + QString mlt_type = mlt_properties_get(properties, "mlt_type"); + QString resource = mlt_properties_get(properties, "mlt_service"); + int old_pos = (int)((in + out).frames(m_fps) / 2); + + while (mlt_type == "transition") { + mlt_transition tr = (mlt_transition) nextservice; + int currentTrack = mlt_transition_get_b_track(tr); + int currentIn = (int) mlt_transition_get_in(tr); + int currentOut = (int) mlt_transition_get_out(tr); + kDebug() << "// FOUND EXISTING TRANS, IN: " << currentIn << ", OUT: " << currentOut << ", TRACK: " << currentTrack; + + if (resource == tag && b_track == currentTrack && currentIn <= old_pos && currentOut >= old_pos) { + mlt_field_disconnect_service(field->get_field(), nextservice); + break; + } + nextservice = mlt_service_producer(nextservice); + properties = MLT_SERVICE_PROPERTIES(nextservice); + mlt_type = mlt_properties_get(properties, "mlt_type"); + resource = mlt_properties_get(properties, "mlt_service"); } - + m_mltConsumer->set("refresh", 1); } QMap Render::mltGetTransitionParamsFromXml(QDomElement xml) { @@ -1582,40 +1499,36 @@ QMap Render::mltGetTransitionParamsFromXml(QDomElement xml) { void Render::mltAddTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool do_refresh) { //kDebug() << "-- ADDING TRANSITION: " << tag << ", ON TRACKS: " << a_track << ", " << b_track; - QMap map = mltGetTransitionParamsFromXml(xml); - - Mlt::Tractor *tractor = getTractor(); - if (tractor) { - Mlt::Field *field = tractor->field(); - char *transId = decodedString(tag); - Mlt::Transition transition(*m_mltProfile, transId); - if (!transition.get_transition()) { - kDebug() << "NO transition is " << transition.get_transition() << "requested was " << tag << a_track << b_track << in.frames(m_fps) << out.frames(m_fps); - return; - } - transition.set_in_and_out((int) in.frames(m_fps), (int) out.frames(m_fps)); - QMap::Iterator it; - QString key; + QMap args = mltGetTransitionParamsFromXml(xml); - kDebug() << " ------ ADDING TRANSITION PARAMs: " << map.count(); - - for (it = map.begin(); it != map.end(); ++it) { - key = it.key(); - char *name = decodedString(key); - char *value = decodedString(it.value()); - transition.set(name, value); - kDebug() << " ------ ADDING TRANS PARAM: " << name << ": " << value; - //filter->set("kdenlive_id", id); - delete[] name; - delete[] value; - } - // attach filter to the clip - field->plant_transition(transition, a_track, b_track); - delete[] transId; - mltSavePlaylist(); - if (do_refresh) refresh(); - delete tractor; + + Mlt::Service service(m_mltProducer->parent().get_service()); + + Mlt::Tractor tractor(service); + Mlt::Field *field = tractor.field(); + + char *transId = decodedString(tag); + Mlt::Transition *transition = new Mlt::Transition(*m_mltProfile, transId); + transition->set_in_and_out((int) in.frames(m_fps), (int) out.frames(m_fps)); + QMap::Iterator it; + QString key; + + kDebug() << " ------ ADDING TRANSITION PARAMs: " << args.count(); + + for (it = args.begin(); it != args.end(); ++it) { + key = it.key(); + char *name = decodedString(key); + char *value = decodedString(it.value()); + transition->set(name, value); + kDebug() << " ------ ADDING TRANS PARAM: " << name << ": " << value; + //filter->set("kdenlive_id", id); + delete[] name; + delete[] value; } + // attach filter to the clip + field->plant_transition(*transition, a_track, b_track); + delete[] transId; + refresh(); } void Render::mltSavePlaylist() { diff --git a/src/renderer.h b/src/renderer.h index 173ed216..3061a4c2 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -93,7 +93,7 @@ Q_OBJECT public: void setSceneList(QDomDocument list, int position = 0); void setSceneList(QString playlist, int position = 0); QString sceneList(); - void saveSceneList(QString path, QDomElement addedXml = QDomElement()); + void saveSceneList(QString path, QDomElement kdenliveData = QDomElement()); /** Wraps the VEML command of the same name. Tells the renderer to play the current scene at the speed specified, relative to normal @@ -199,9 +199,6 @@ private: // Private attributes & methods void setDescription(const QString & description); void closeMlt(); void mltCheckLength(bool reload = true); - Mlt::Tractor* getTractor(); - Mlt::Playlist* getPlaylist(int track); - void replaceTimelineTractor(Mlt::Tractor t); QMap mltGetTransitionParamsFromXml(QDomElement xml); private slots: // Private slots diff --git a/src/trackview.cpp b/src/trackview.cpp index 940353e6..9c6ba89a 100644 --- a/src/trackview.cpp +++ b/src/trackview.cpp @@ -119,26 +119,37 @@ void TrackView::setDuration(int dur) { void TrackView::parseDocument(QDomDocument doc) { int cursorPos = 0; - kDebug() << "//// DOCUMENT: " << doc.toString(); + //kDebug() << "//// DOCUMENT: " << doc.toString(); QDomNode props = doc.elementsByTagName("properties").item(0); if (!props.isNull()) { cursorPos = props.toElement().attribute("timeline_position").toInt(); } - QDomNodeList tracks = doc.elementsByTagName("playlist"); + QDomNodeList tracks = doc.elementsByTagName("track"); + QDomNodeList playlists = doc.elementsByTagName("playlist"); int duration = 300; m_projectTracks = tracks.count(); int trackduration = 0; + QDomElement e; + QDomElement p; + bool videotrack; kDebug() << "//////////// TIMELINE FOUND: " << m_projectTracks << " tracks"; + int pos = m_projectTracks - 1; for (int i = 0; i < m_projectTracks; i++) { - if (tracks.item(i).toElement().attribute("id") != "playlistmain") { - if (tracks.item(i).toElement().attribute("hide", QString::null) == "video") { - // this is an audio track - trackduration = slotAddAudioTrack(i, tracks.item(i).toElement()); - } else if (!tracks.item(i).toElement().attribute("id", QString::null).isEmpty()) - trackduration = slotAddVideoTrack(i, tracks.item(i).toElement()); + e = tracks.item(i).toElement(); + QString playlist_name = e.attribute("producer"); + if (playlist_name != "black_track" && playlist_name != "playlistmain") { + // find playlist related to this track + p = QDomElement(); + for (int j = 0; j < m_projectTracks; j++) { + p = playlists.item(j).toElement(); + if (p.attribute("id") == playlist_name) break; + } + videotrack = (e.attribute("hide") != "video"); + trackduration = slotAddProjectTrack(pos, p, videotrack); + pos--; kDebug() << " PRO DUR: " << trackduration << ", TRACK DUR: " << duration; if (trackduration > duration) duration = trackduration; - } + } else pos--; } m_trackview->setDuration(duration); slotRebuildTrackHeaders(); @@ -205,47 +216,44 @@ void TrackView::slotRebuildTrackHeaders() { view->headers_container->adjustSize(); } -int TrackView::slotAddAudioTrack(int ix, QDomElement xml) { - kDebug() << "************* ADD AUDIO TRACK " << ix; +int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool videotrack) { TrackInfo info; - info.type = AUDIOTRACK; - info.isMute = false; - info.isBlind = false; - m_trackview->addTrack(info); - //documentTracks.insert(ix, track); - return 0; - //track->show(); -} + if (videotrack) { + info.type = VIDEOTRACK; + info.isMute = false; + info.isBlind = false; + } else { + info.type = AUDIOTRACK; + info.isMute = false; + info.isBlind = false; + } -int TrackView::slotAddVideoTrack(int ix, QDomElement xml) { - TrackInfo info; - info.type = VIDEOTRACK; - info.isMute = false; - info.isBlind = false; m_trackview->addTrack(info); int trackTop = KdenliveSettings::trackheight() * ix; // parse track int position = 0; + for (QDomNode n = xml.firstChild(); !n.isNull(); n = n.nextSibling()) { QDomElement elem = n.toElement(); if (elem.tagName() == "blank") { - position += elem.attribute("length", 0).toInt(); + position += elem.attribute("length").toInt(); } else if (elem.tagName() == "entry") { - int in = elem.attribute("in", 0).toInt(); - int id = elem.attribute("producer", 0).toInt(); + int in = elem.attribute("in").toInt(); + int id = elem.attribute("producer").toInt(); DocClipBase *clip = m_doc->clipManager()->getClipById(id); - int out = elem.attribute("out", 0).toInt(); - - ItemInfo info; - info.startPos = GenTime(position, m_doc->fps()); - info.endPos = GenTime(out, m_doc->fps()); - info.track = ix; - - ClipItem *item = new ClipItem(clip, info, m_scale, m_doc->fps()); - m_scene->addItem(item); - position += out; - + if (clip != NULL) { + int out = elem.attribute("out").toInt(); + + ItemInfo clipinfo; + clipinfo.startPos = GenTime(position, m_doc->fps()); + clipinfo.endPos = GenTime(out, m_doc->fps()); + clipinfo.track = ix; + kDebug() << "// INSERTING CLIP: " << in << "x" << out << ", track: " << ix << ", ID: " << id << ", SCALE: " << m_scale << ", FPS: " << m_doc->fps(); + ClipItem *item = new ClipItem(clip, clipinfo, m_scale, m_doc->fps()); + m_scene->addItem(item); + position += out; + } else kWarning() << "CANNOT INSERT CLIP " << id; //m_clipList.append(clip); } } @@ -253,7 +261,7 @@ int TrackView::slotAddVideoTrack(int ix, QDomElement xml) { //documentTracks.insert(ix, track); - kDebug() << "************* ADD VIDEO TRACK " << ix << ", DURATION: " << position; + kDebug() << "************* ADD DOC TRACK " << ix << ", DURATION: " << position; return position; //track->show(); } diff --git a/src/trackview.h b/src/trackview.h index 2f01be7e..69710743 100644 --- a/src/trackview.h +++ b/src/trackview.h @@ -81,8 +81,7 @@ private: QFrame *m_scrollBox; QVBoxLayout *m_tracksAreaLayout; void parseDocument(QDomDocument doc); - int slotAddAudioTrack(int ix, QDomElement xml); - int slotAddVideoTrack(int ix, QDomElement xml); + int slotAddProjectTrack(int ix, QDomElement xml, bool videotrack); private slots: void setCursorPos(int pos);