From 78fe559babbcbaddcc64c6eb6f7e226e78881d52 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Sun, 3 Aug 2008 17:32:42 +0000 Subject: [PATCH] * Several fixes to clip resizing & cutting * Fix indent svn path=/branches/KDE4/; revision=2358 --- src/clipitem.cpp | 10 +- src/customtrackview.cpp | 106 +++++++++++------- src/customtrackview.h | 2 + src/kthumb.cpp | 20 ++-- src/monitor.cpp | 11 +- src/projectlist.cpp | 2 +- src/razorclipcommand.cpp | 3 +- src/razorclipcommand.h | 2 +- src/renderer.cpp | 235 +++++++++++++++++++++++++++++---------- src/renderer.h | 6 +- 10 files changed, 268 insertions(+), 129 deletions(-) diff --git a/src/clipitem.cpp b/src/clipitem.cpp index f2180558..01ddd6e0 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -95,6 +95,7 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) ClipItem::~ClipItem() { if (startThumbTimer) delete startThumbTimer; if (endThumbTimer) delete endThumbTimer; + if (m_timeLine) m_timeLine; } ClipItem *ClipItem::clone(double scale, ItemInfo info) const { @@ -265,7 +266,7 @@ void ClipItem::refreshClip() { } void ClipItem::slotFetchThumbs() { - m_thumbsRequested += 2; + m_thumbsRequested = 2; emit getThumb((int)m_cropStart.frames(m_fps), (int)(m_cropStart + m_cropDuration).frames(m_fps)); } @@ -280,19 +281,20 @@ void ClipItem::slotGetEndThumb() { } void ClipItem::slotThumbReady(int frame, QPixmap pix) { - if (m_thumbsRequested == 0) return; + //if (m_thumbsRequested == 0) return; if (frame == m_cropStart.frames(m_fps)) { m_startPix = pix; QRectF r = boundingRect(); r.setRight(pix.width() + 2); update(r); - } else { + m_thumbsRequested--; + } else if (frame == (m_cropStart + m_cropDuration).frames(m_fps)) { m_endPix = pix; QRectF r = boundingRect(); r.setLeft(r.right() - pix.width() - 2); update(r); + m_thumbsRequested--; } - m_thumbsRequested--; } void ClipItem::slotGotAudioData() { diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 0f2fcdbf..9d9922cd 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -70,7 +70,7 @@ // const int duration = animate ? 1500 : 1; CustomTrackView::CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene, QWidget *parent) - : QGraphicsView(projectscene, parent), m_cursorPos(0), m_dropItem(NULL), m_cursorLine(NULL), m_operationMode(NONE), m_dragItem(NULL), m_visualTip(NULL), m_moveOpMode(NONE), m_animation(NULL), m_projectDuration(0), m_scale(1.0), m_clickPoint(QPoint()), m_document(doc), m_autoScroll(KdenliveSettings::autoscroll()), m_tracksHeight(KdenliveSettings::trackheight()), m_tool(SELECTTOOL), m_dragGuide(NULL), m_findIndex(0), m_menuPosition(QPoint()) { + : QGraphicsView(projectscene, parent), m_cursorPos(0), m_dropItem(NULL), m_cursorLine(NULL), m_operationMode(NONE), m_dragItem(NULL), m_visualTip(NULL), m_moveOpMode(NONE), m_animation(NULL), m_projectDuration(0), m_scale(1.0), m_clickPoint(QPoint()), m_document(doc), m_autoScroll(KdenliveSettings::autoscroll()), m_tracksHeight(KdenliveSettings::trackheight()), m_tool(SELECTTOOL), m_dragGuide(NULL), m_findIndex(0), m_menuPosition(QPoint()), m_blockRefresh(false) { if (doc) m_commandStack = doc->commandStack(); else m_commandStack == NULL; setMouseTracking(true); @@ -258,13 +258,13 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { } if (item && event->buttons() == Qt::NoButton) { - AbstractClipItem *clip = (AbstractClipItem*) item; + AbstractClipItem *clip = static_cast (item); if (m_tool == RAZORTOOL) { // razor tool over a clip, display current frame in monitor - if (item->type() == AVWIDGET) { + if (!m_blockRefresh && item->type() == AVWIDGET) { emit showClipFrame(((ClipItem *) item)->baseClip(), mapToScene(event->pos()).x() / m_scale - (clip->startPos() - clip->cropStart()).frames(m_document->fps())); } - QGraphicsView::mouseMoveEvent(event); + event->accept(); return; } opMode = clip->operationMode(mapToScene(event->pos()), m_scale); @@ -420,7 +420,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { } } // no clip under mouse else if (m_tool == RAZORTOOL) { - QGraphicsView::mouseMoveEvent(event); + event->accept(); return; } else if (opMode == MOVEGUIDE) { m_moveOpMode = opMode; @@ -446,20 +446,24 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { // virtual void CustomTrackView::mousePressEvent(QMouseEvent * event) { m_menuPosition = QPoint(); - activateMonitor(); + m_blockRefresh = true; + if (m_tool != RAZORTOOL) activateMonitor(); m_clickEvent = event->pos(); QList collisionList = items(event->pos()); if (event->button() == Qt::MidButton) { m_document->renderer()->switchPlay(); + m_blockRefresh = false; return; } if (event->modifiers() == Qt::ControlModifier && collisionList.count() == 0) { setDragMode(QGraphicsView::ScrollHandDrag); QGraphicsView::mousePressEvent(event); + m_blockRefresh = false; return; } else if (event->modifiers() == Qt::ShiftModifier && collisionList.count() == 0) { setDragMode(QGraphicsView::RubberBandDrag); QGraphicsView::mousePressEvent(event); + m_blockRefresh = false; return; } else { bool collision = false; @@ -480,18 +484,17 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { QGraphicsItem *item = collisionList.at(i); if (item->type() == AVWIDGET || item->type() == TRANSITIONWIDGET) { if (m_tool == RAZORTOOL) { + m_dragItem = NULL; if (item->type() == TRANSITIONWIDGET) { emit displayMessage(i18n("Cannot cut a transition"), ErrorMessage); + event->accept(); return; } - AbstractClipItem *clip = (AbstractClipItem *) item; - ItemInfo info; - info.startPos = clip->startPos(); - info.endPos = clip->endPos(); - info.track = clip->track(); - RazorClipCommand* command = new RazorClipCommand(this, info, GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()), true); + AbstractClipItem *clip = static_cast (item); + RazorClipCommand* command = new RazorClipCommand(this, clip->info(), GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()), true); m_commandStack->push(command); m_document->setModified(true); + event->accept(); //QGraphicsView::mousePressEvent(event); return; } // select item @@ -525,6 +528,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { m_operationMode = m_dragItem->operationMode(item->mapFromScene(mapToScene(event->pos())), m_scale); if (m_operationMode == KEYFRAME) { m_dragItem->updateSelectedKeyFrame(); + m_blockRefresh = false; return; } else if (m_operationMode == MOVE) setCursor(Qt::ClosedHandCursor); else if (m_operationMode == TRANSITIONSTART) { @@ -576,6 +580,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { if (m_dragItem && m_dragItem->type() == AVWIDGET) emit clipItemSelected((ClipItem*) m_dragItem); else emit clipItemSelected(NULL); } + m_blockRefresh = false; //kDebug()<fps()), info.track); - if (!item) { + if (!item || cutTime >= item->endPos() || cutTime <= item->startPos()) { emit displayMessage(i18n("Cannot find clip to cut"), ErrorMessage); + kDebug() << "///////// ERROR CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25); + m_blockRefresh = false; return; } + m_document->renderer()->mltCutClip(m_tracksList.count() - info.track, cutTime); int cutPos = (int) cutTime.frames(m_document->fps()); ItemInfo newPos; newPos.startPos = cutTime; @@ -819,26 +827,36 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) { item->resizeEnd(cutPos, m_scale); ClipItem *dup = item->clone(m_scale, newPos); scene()->addItem(dup); - m_document->renderer()->mltCutClip(m_tracksList.count() - info.track, cutTime); item->baseClip()->addReference(); m_document->updateClip(item->baseClip()->getId()); + kDebug() << "// CUTTING CLIP dONE"; } else { // uncut clip ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track); ClipItem *dup = getClipItemAt((int) cutTime.frames(m_document->fps()), info.track); if (!item || !dup) { emit displayMessage(i18n("Cannot find clip to uncut"), ErrorMessage); + m_blockRefresh = false; return; } - delete dup; - item->baseClip()->removeReference(); - m_document->updateClip(item->baseClip()->getId()); - item->resizeEnd((int) info.endPos.frames(m_document->fps()), m_scale); - m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, cutTime); - m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - info.track, info.startPos, item->cropStart(), item->cropStart() + info.endPos - info.startPos); + /*kDebug() << "// UNCUTTING CLIPS: " << item->startPos().frames(25) << ", SECOND: " << dup->startPos().frames(25); + kDebug() << "// UNCUTTING CLIPS, SEC END " << dup->endPos().frames(25) << ", CUT: " << cutTime.frames(25); + kDebug() << "// UNCUTTING CLIPS, INFO " << info.endPos.frames(25) << ", start: " << info.startPos.frames(25);*/ + deleteClip(dup->info()); + ItemInfo clipinfo = item->info(); + clipinfo.track = m_tracksList.count() - clipinfo.track; + bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, info.endPos - info.startPos); + if (success) { + item->resizeEnd((int) info.endPos.frames(m_document->fps()), m_scale); + } else + emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } + QTimer::singleShot(3000, this, SLOT(slotEnableRefresh())); } +void CustomTrackView::slotEnableRefresh() { + m_blockRefresh = false; +} void CustomTrackView::slotAddTransitionToSelectedClips(QDomElement transition) { QList itemList = scene()->selectedItems(); @@ -1049,10 +1067,10 @@ void CustomTrackView::checkScrolling() { } void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { + QGraphicsView::mouseReleaseEvent(event); if (event->button() == Qt::MidButton) { return; } - QGraphicsView::mouseReleaseEvent(event); setDragMode(QGraphicsView::NoDrag); if (m_operationMode == MOVEGUIDE) { setCursor(Qt::ArrowCursor); @@ -1069,10 +1087,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { emit transitionItemSelected(NULL); return; } - ItemInfo info; - info.startPos = m_dragItem->startPos(); - info.endPos = m_dragItem->endPos(); - info.track = m_dragItem->track(); + ItemInfo info = m_dragItem->info(); if (m_operationMode == MOVE) { setCursor(Qt::OpenHandCursor); @@ -1148,7 +1163,9 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { } else if (m_operationMode == RESIZESTART && m_dragItem->startPos() != m_dragItemInfo.startPos) { // resize start if (m_dragItem->type() == AVWIDGET) { - bool success = m_document->renderer()->mltResizeClipStart(m_tracksList.count() - m_dragItem->track(), m_dragItem->endPos(), m_dragItem->startPos(), m_dragItemInfo.startPos, m_dragItem->cropStart(), m_dragItem->cropStart() + m_dragItem->endPos() - m_dragItem->startPos()); + ItemInfo resizeinfo = m_dragItemInfo; + resizeinfo.track = m_tracksList.count() - resizeinfo.track; + bool success = m_document->renderer()->mltResizeClipStart(resizeinfo, m_dragItem->startPos() - m_dragItemInfo.startPos); if (success) { updateClipFade((ClipItem *) m_dragItem); ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false); @@ -1168,14 +1185,21 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { } else if (m_operationMode == RESIZEEND && m_dragItem->endPos() != m_dragItemInfo.endPos) { // resize end if (m_dragItem->type() == AVWIDGET) { - ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false); - m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - m_dragItem->track(), m_dragItem->startPos(), m_dragItem->cropStart(), m_dragItem->cropStart() + m_dragItem->endPos() - m_dragItem->startPos()); - m_commandStack->push(command); + ItemInfo resizeinfo = info; + resizeinfo.track = m_tracksList.count() - resizeinfo.track; + bool success = m_document->renderer()->mltResizeClipEnd(resizeinfo, resizeinfo.endPos - resizeinfo.startPos); + if (success) { + ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false); + m_commandStack->push(command); + } else { + m_dragItem->resizeEnd((int) m_dragItemInfo.endPos.frames(m_document->fps()), m_scale); + emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); + } } else if (m_dragItem->type() == TRANSITIONWIDGET) { MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false); m_commandStack->push(command); Transition *transition = (Transition *) m_dragItem; - m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos); +// m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos); } //m_document->renderer()->doRefresh(); } else if (m_operationMode == FADEIN) { @@ -1327,12 +1351,8 @@ void CustomTrackView::cutSelectedClips() { for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { ClipItem *item = (ClipItem *) itemList.at(i); - ItemInfo info; - info.startPos = item->startPos(); - info.endPos = item->endPos(); - if (currentPos > info.startPos && currentPos < info.endPos) { - info.track = item->track(); - RazorClipCommand *command = new RazorClipCommand(this, info, currentPos, true); + if (currentPos > item->startPos() && currentPos < item->endPos()) { + RazorClipCommand *command = new RazorClipCommand(this, item->info(), currentPos, true); m_commandStack->push(command); } } @@ -1460,15 +1480,21 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) { return; } if (resizeClipStart) { - bool success = m_document->renderer()->mltResizeClipStart(m_tracksList.count() - item->track(), item->endPos(), end.startPos, item->startPos(), item->cropStart() + end.startPos - start.startPos, item->cropStart() + end.startPos - start.startPos + item->endPos() - end.startPos); + ItemInfo clipinfo = item->info(); + clipinfo.track = m_tracksList.count() - clipinfo.track; + bool success = m_document->renderer()->mltResizeClipStart(clipinfo, item->startPos() - end.startPos); if (success) { item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale); updateClipFade(item); } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } else { - m_document->renderer()->mltResizeClipEnd(m_tracksList.count() - item->track(), item->startPos(), item->cropStart(), item->cropStart() + end.endPos - item->startPos()); - item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale); - updateClipFade(item, true); + ItemInfo clipinfo = item->info(); + clipinfo.track = m_tracksList.count() - clipinfo.track; + bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, end.endPos - clipinfo.startPos); + if (success) { + item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale); + updateClipFade(item, true); + } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } m_document->renderer()->doRefresh(); } diff --git a/src/customtrackview.h b/src/customtrackview.h index 9f75435a..79ce4e5e 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -182,6 +182,7 @@ private: QList m_selectedClipList; /** Used to get the point in timeline where a context menu was opened */ QPoint m_menuPosition; + bool m_blockRefresh; /** Get the index of the video track that is just below current track */ int getPreviousVideoTrack(int track); @@ -192,6 +193,7 @@ private: private slots: void slotRefreshGuides(); + void slotEnableRefresh(); signals: void cursorMoved(int, int); diff --git a/src/kthumb.cpp b/src/kthumb.cpp index b43098b7..f6cfc7c4 100644 --- a/src/kthumb.cpp +++ b/src/kthumb.cpp @@ -20,6 +20,11 @@ * * ***************************************************************************/ +#include +#include +#include +#include + #include #include #include @@ -30,19 +35,13 @@ #include -#include -#include - -#include -#include -#include - #include "clipmanager.h" #include "renderer.h" #include "kthumb.h" #include "kdenlivesettings.h" #include "events.h" + void MyThread::init(QObject *parent, KUrl url, QString target, double frame, double frameLength, int frequency, int channels, int arrayWidth) { stop_me = false; m_parent = parent; @@ -159,11 +158,7 @@ QPixmap KThumb::getImage(KUrl url, int width, int height) { } void KThumb::extractImage(int frame, int frame2) { - if (m_url.isEmpty()) return; - if (m_producer == NULL) return; - /*char *tmp = Render::decodedString(""); - Mlt::Producer producer(*m_profile, "westley-xml", tmp); - delete[] tmp;*/ + if (m_url.isEmpty() || !KdenliveSettings::videothumbnails() || m_producer == NULL) return; int twidth = (int)(KdenliveSettings::trackheight() * m_dar); if (m_producer->is_blank()) { @@ -223,7 +218,6 @@ QPixmap KThumb::getImage(QDomElement xml, int frame, int width, int height) { //static QPixmap KThumb::getFrame(Mlt::Producer producer, int framepos, int width, int height) { - producer.seek(framepos); Mlt::Frame *frame = producer.get_frame(); mlt_image_format format = mlt_image_yuv422; diff --git a/src/monitor.cpp b/src/monitor.cpp index 45405e31..0048c04a 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -304,13 +304,12 @@ void Monitor::slotSetXml(DocClipBase *clip, const int position) { if (!clip) return; if (clip != m_currentClip || m_currentClip->producer() == NULL) { m_currentClip = clip; - render->setProducer(clip->producer(), 0); - m_ruler->slotNewValue(0); + render->setProducer(clip->producer(), position); + //m_ruler->slotNewValue(0); //adjustRulerSize(clip->producer()->get_playtime()); - m_timePos->setText("00:00:00:00"); - m_position = 0; - } - if (position != -1) render->seek(GenTime(position, render->fps())); + //m_timePos->setText("00:00:00:00"); + m_position = position; + } else if (position != -1) render->seek(GenTime(position, render->fps())); } void Monitor::slotOpenFile(const QString &file) { diff --git a/src/projectlist.cpp b/src/projectlist.cpp index b8f9c76d..7ccd5da7 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -306,7 +306,7 @@ void ProjectList::slotAddClip(QUrl givenUrl, QString group) { if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!!  NO CMD STK"; KUrl::List list; if (givenUrl.isEmpty()) { - list = KFileDialog::getOpenUrls(KUrl("kfiledialog:///clipfolder"), "application/vnd.kde.kdenlive application/vnd.westley.scenelist application/flv application/vnd.rn-realmedia video/x-dv video/x-msvideo video/mpeg video/x-ms-wmv audio/mpeg audio/x-mp3 audio/x-wav application/ogg video/mp4 video/quicktime image/gif image/jpeg image/png image/x-bmp image/svg+xml image/tiff image/x-xcf-gimp image/x-vnd.adobe.photoshop image/x-pcx image/x-exr\n*.m2t *.mts|HDV video\n*.dv|DV video"); + list = KFileDialog::getOpenUrls(KUrl("kfiledialog:///clipfolder"), "application/vnd.kde.kdenlive application/vnd.westley.scenelist application/flv application/vnd.rn-realmedia video/x-dv video/x-msvideo video/mpeg video/x-ms-wmv audio/mpeg audio/x-mp3 audio/x-wav application/ogg video/mp4 video/quicktime image/gif image/jpeg image/png image/x-bmp image/svg+xml image/tiff image/x-xcf-gimp image/x-vnd.adobe.photoshop image/x-pcx image/x-exr\n*.m2t *.mts|HDV video\n*.dv|DV video", this); } else list.append(givenUrl); if (list.isEmpty()) return; diff --git a/src/razorclipcommand.cpp b/src/razorclipcommand.cpp index c7fd0745..75fb9d8b 100644 --- a/src/razorclipcommand.cpp +++ b/src/razorclipcommand.cpp @@ -22,11 +22,10 @@ #include "razorclipcommand.h" #include "customtrackview.h" -RazorClipCommand::RazorClipCommand(CustomTrackView *view, const ItemInfo info, const GenTime cutTime, bool doIt) : m_view(view), m_info(info), m_cutTime(cutTime), m_doIt(doIt) { +RazorClipCommand::RazorClipCommand(CustomTrackView *view, const ItemInfo info, const GenTime cutTime, bool doIt, QUndoCommand * parent) : QUndoCommand(parent), m_view(view), m_info(info), m_cutTime(cutTime), m_doIt(doIt) { setText(i18n("Razor clip")); } - // virtual void RazorClipCommand::undo() { // kDebug()<<"---- undoing action"; diff --git a/src/razorclipcommand.h b/src/razorclipcommand.h index 09b37364..c9ca1a31 100644 --- a/src/razorclipcommand.h +++ b/src/razorclipcommand.h @@ -32,7 +32,7 @@ class CustomTrackView; class RazorClipCommand : public QUndoCommand { public: - RazorClipCommand(CustomTrackView *view, const ItemInfo info, const GenTime cutTime, bool doIt); + RazorClipCommand(CustomTrackView *view, const ItemInfo info, const GenTime cutTime, bool doIt, QUndoCommand * parent = 0); virtual void undo(); virtual void redo(); diff --git a/src/renderer.cpp b/src/renderer.cpp index 44ff8d23..9d6e20d5 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -51,6 +51,8 @@ extern "C" { #define ENABLE_FFMPEG_CODEC_DESCRIPTION 1 #endif + + static void consumer_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr) { // detect if the producer has finished playing. Is there a better way to do it ? if (self->m_isBlocked) return; @@ -710,7 +712,6 @@ void Render::setProducer(Mlt::Producer *producer, int position) { if (producer) m_mltProducer = new Mlt::Producer(producer->get_producer()); else m_mltProducer = new Mlt::Producer(); if (!m_mltProducer || !m_mltProducer->is_valid()) kDebug() << " WARNING - - - - -INVALID PLAYLIST: "; - m_mltProducer->optimise(); m_fps = m_mltProducer->get_fps(); connectPlaylist(); @@ -1061,7 +1062,6 @@ void Render::sendSeekCommand(GenTime time) { return; //kDebug()<<"////////// KDENLIVE SEEK: "<<(int) (time.frames(m_fps)); m_mltProducer->seek((int)(time.frames(m_fps))); - m_mltConsumer->set("refresh", 1); refresh(); } @@ -1248,20 +1248,21 @@ void Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pr Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); Mlt::Producer *clip = prod->cut(info.cropStart.frames(m_fps), (info.endPos - info.startPos).frames(m_fps) - 1); - trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *clip, 1); + int newIndex = trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *clip, 1); if (QString(prod->get("transparency")).toInt() == 1) mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt()); mlt_service_unlock(service.get_service()); - if (info.track != 0) mltCheckLength(); + if (info.track != 0 && (newIndex + 1 == trackPlaylist.count())) mltCheckLength(); //tractor.multitrack()->refresh(); //tractor.refresh(); } void Render::mltCutClip(int track, GenTime position) { + m_isBlocked = true; Mlt::Service service(m_mltProducer->parent().get_service()); @@ -1270,21 +1271,64 @@ void Render::mltCutClip(int track, GenTime position) { 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); + + + /* // Display playlist info + kDebug()<<"//////////// BEFORE"; + for (int i = 0; i < trackPlaylist.count(); i++) { + int blankStart = trackPlaylist.clip_start(i); + int blankDuration = trackPlaylist.clip_length(i) - 1; + QString blk; + if (trackPlaylist.is_blank(i)) blk = "(blank)"; + kDebug()<<"CLIP "<get_service()); Mlt::Service dupService(clip->get_service()); int ct = 0; Mlt::Filter *filter = clipService.filter(ct); while (filter) { - Mlt::Filter *dup = new Mlt::Filter(filter->get_filter()); - dupService.attach(*dup); + if (filter->get("kdenlive_id") != "") { + kDebug() << "++ ADDING FILTER: " << filter->get("kdenlive_id"); + Mlt::Filter *dup = new Mlt::Filter(filter->get_filter()); + dup->set("kdenlive_ix", filter->get("kdenlive_ix")); + dup->set("kdenlive_id", filter->get("kdenlive_id")); + dupService.attach(*dup); + } ct++; filter = clipService.filter(ct); } + mlt_service_unlock(service.get_service()); + + /* // Display playlist info + kDebug()<<"//////////// AFTER"; + for (int i = 0; i < trackPlaylist.count(); i++) { + int blankStart = trackPlaylist.clip_start(i); + int blankDuration = trackPlaylist.clip_length(i) - 1; + QString blk; + if (trackPlaylist.is_blank(i)) blk = "(blank)"; + kDebug()<<"CLIP "<parent().get_service()); if (service.type() != tractor_type) kWarning() << "// TRACTOR PROBLEM"; @@ -1305,14 +1347,41 @@ void Render::mltRemoveClip(int track, GenTime position) { 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)); + + /* // Display playlist info + kDebug()<<"//// BEFORE"; + for (int i = 0; i < trackPlaylist.count(); i++) { + int blankStart = trackPlaylist.clip_start(i); + int blankDuration = trackPlaylist.clip_length(i) - 1; + QString blk; + if (trackPlaylist.is_blank(i)) blk = "(blank)"; + kDebug()<<"CLIP "< clipIndex) mltCheckLength(); m_isBlocked = false; + return true; } int Render::mltChangeClipSpeed(ItemInfo info, double speed, Mlt::Producer *prod) { @@ -1406,7 +1475,7 @@ bool Render::mltRemoveEffect(int track, GenTime position, QString index, bool do int ct = 0; Mlt::Filter *filter = clipService.filter(ct); while (filter) { - if (index == "-1" || filter->get("kdenlive_ix") == index) {// && filter->get("kdenlive_id") == id) { + if ((index == "-1" && filter->get("kdenlive_id") != "") || filter->get("kdenlive_ix") == index) {// && filter->get("kdenlive_id") == id) { if (clipService.detach(*filter) == 0) success = true; kDebug() << " / / / DLEETED EFFECT: " << ct; } else ct++; @@ -1653,46 +1722,81 @@ void Render::mltMoveEffect(int track, GenTime position, int oldPos, int newPos) refresh(); } -void Render::mltResizeClipEnd(int track, GenTime pos, GenTime in, GenTime out) { +bool Render::mltResizeClipEnd(ItemInfo info, GenTime clipDuration) { m_isBlocked = true; Mlt::Service service(m_mltProducer->parent().get_service()); Mlt::Tractor tractor(service); - Mlt::Producer trackProducer(tractor.track(track)); + Mlt::Producer trackProducer(tractor.track(info.track)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); - if (trackPlaylist.is_blank_at((int) pos.frames(m_fps) + 1)) + + /* // Display playlist info + kDebug()<<"//////////// BEFORE RESIZE"; + for (int i = 0; i < trackPlaylist.count(); i++) { + int blankStart = trackPlaylist.clip_start(i); + int blankDuration = trackPlaylist.clip_length(i) - 1; + QString blk; + if (trackPlaylist.is_blank(i)) blk = "(blank)"; + kDebug()<<"CLIP "<get_in(); int previousDuration = trackPlaylist.clip_length(clipIndex) - 1; - int newDuration = (int) out.frames(m_fps) - 1; - trackPlaylist.resize_clip(clipIndex, (int) in.frames(m_fps), newDuration); - trackPlaylist.consolidate_blanks(0); - if (previousDuration < newDuration) { + int newDuration = (int) clipDuration.frames(m_fps) - 1; + trackPlaylist.resize_clip(clipIndex, previousStart, newDuration + previousStart); + //trackPlaylist.consolidate_blanks(0); + // skip to next clip + clipIndex++; + int diff = newDuration - previousDuration; + kDebug() << "//////// RESIZE CLIP: " << clipIndex << "( pos: " << info.startPos.frames(25) << "), DIFF: " << diff << ", CURRENT DUR: " << previousDuration << ", NEW DUR: " << newDuration; + if (diff > 0) { // 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); + if (trackPlaylist.is_blank(clipIndex)) { + int blankStart = trackPlaylist.clip_start(clipIndex); + int blankDuration = trackPlaylist.clip_length(clipIndex) - 1; + if (diff - blankDuration == 1) { + trackPlaylist.remove(clipIndex); + } else trackPlaylist.resize_clip(clipIndex, blankStart, blankStart + blankDuration - diff); + } else { + kDebug() << "/// RESIZE ERROR, NXT CLIP IS NOT BLK: " << clipIndex; } - } else trackPlaylist.insert_blank(clipIndex + 1, previousDuration - newDuration - 1); + } else trackPlaylist.insert_blank(clipIndex, 0 - diff - 1); trackPlaylist.consolidate_blanks(0); + /* // Display playlist info + kDebug()<<"//////////// AFTER RESIZE"; + for (int i = 0; i < trackPlaylist.count(); i++) { + int blankStart = trackPlaylist.clip_start(i); + int blankDuration = trackPlaylist.clip_length(i) - 1; + QString blk; + if (trackPlaylist.is_blank(i)) blk = "(blank)"; + kDebug()<<"CLIP "<refresh(); //tractor.refresh(); - if (track != 0) mltCheckLength(); + if (info.track != 0 && clipIndex == trackPlaylist.count()) mltCheckLength(); if (QString(clip->parent().get("transparency")).toInt() == 1) { //mltResizeTransparency(previousStart, previousStart, previousStart + newDuration, track, QString(clip->parent().get("id")).toInt()); - mltDeleteTransparency(previousStart, track, QString(clip->parent().get("id")).toInt()); - ItemInfo info; - info.startPos = pos; - info.endPos = pos + out - in; - info.track = track; - mltAddClipTransparency(info, info.track - 1, QString(clip->parent().get("id")).toInt()); + mltDeleteTransparency(info.startPos.frames(m_fps), info.track, QString(clip->parent().get("id")).toInt()); + ItemInfo transpinfo; + transpinfo.startPos = info.startPos; + transpinfo.endPos = info.startPos + clipDuration; + transpinfo.track = info.track; + mltAddClipTransparency(transpinfo, info.track - 1, QString(clip->parent().get("id")).toInt()); } m_isBlocked = false; + return true; } void Render::mltChangeTrackState(int track, bool mute, bool blind) { @@ -1713,47 +1817,55 @@ void Render::mltChangeTrackState(int track, bool mute, bool blind) { refresh(); } -bool Render::mltResizeClipStart(int track, GenTime pos, GenTime moveEnd, GenTime moveStart, GenTime in, GenTime out) { +bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) { Mlt::Service service(m_mltProducer->parent().get_service()); - int moveFrame = (int)(moveEnd - moveStart).frames(m_fps); + int moveFrame = (int) diff.frames(m_fps); Mlt::Tractor tractor(service); - Mlt::Producer trackProducer(tractor.track(track)); + Mlt::Producer trackProducer(tractor.track(info.track)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); - if (trackPlaylist.is_blank_at((int) pos.frames(m_fps) - 1)) { + if (trackPlaylist.is_blank_at(info.startPos.frames(m_fps))) { kDebug() << "//////// ERROR RSIZING BLANK CLIP!!!!!!!!!!!"; return false; } - int clipIndex = trackPlaylist.get_clip_index_at((int) pos.frames(m_fps) - 1); - int previousStart = trackPlaylist.clip_start(clipIndex); + int clipIndex = trackPlaylist.get_clip_index_at(info.startPos.frames(m_fps)); + /*int previousStart = trackPlaylist.clip_start(clipIndex); + int previousDuration = trackPlaylist.clip_length(clipIndex) - 1;*/ //kDebug() << " ** RESIZING CLIP START:" << clipIndex << " on track:" << track << ", mid pos: " << pos.frames(25) << ", moving: " << moveFrame << ", in: " << in.frames(25) << ", out: " << out.frames(25); Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex); if (clip == NULL) { + kDebug() << "//////// ERROR RSIZING NULL CLIP!!!!!!!!!!!"; return false; } + m_mltConsumer->set("refresh", 0); + int previousStart = clip->get_in(); + int previousDuration = trackPlaylist.clip_length(clipIndex) - 1; m_isBlocked = true; - trackPlaylist.resize_clip(clipIndex, (int) in.frames(m_fps), (int) out.frames(m_fps)); + kDebug() << "RESIZE, old start: " << previousStart << ", PREV DUR: " << previousDuration << ", DIFF: " << moveFrame; + trackPlaylist.resize_clip(clipIndex, previousStart + moveFrame, previousStart + previousDuration); 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 midpos = info.startPos.frames(m_fps) + moveFrame - 1; + int blankIndex = clipIndex - 1; int blankLength = trackPlaylist.clip_length(blankIndex); - - kDebug() << " + resizing blank: " << blankIndex << ", Mid: " << midpos << ", Length: " << blankLength << ", SIZE DIFF: " << moveFrame; - + kDebug() << " + resizing blank length " << blankLength << ", SIZE DIFF: " << moveFrame; + if (! trackPlaylist.is_blank(blankIndex)) { + kDebug() << "WARNING, CLIP TO RESIZE IS NOT BLANK"; + } if (blankLength + moveFrame == 0) trackPlaylist.remove(blankIndex); else trackPlaylist.resize_clip(blankIndex, 0, blankLength + moveFrame - 1); } trackPlaylist.consolidate_blanks(0); if (QString(clip->parent().get("transparency")).toInt() == 1) { //mltResizeTransparency(previousStart, (int) moveEnd.frames(m_fps), (int) (moveEnd + out - in).frames(m_fps), track, QString(clip->parent().get("id")).toInt()); - mltDeleteTransparency(previousStart, track, QString(clip->parent().get("id")).toInt()); - ItemInfo info; - info.startPos = moveEnd; - info.endPos = moveEnd + out - in; - info.track = track; - mltAddClipTransparency(info, info.track - 1, QString(clip->parent().get("id")).toInt()); + mltDeleteTransparency(info.startPos.frames(m_fps), info.track, QString(clip->parent().get("id")).toInt()); + ItemInfo transpinfo; + transpinfo.startPos = info.startPos + diff; + transpinfo.endPos = info.startPos + diff + (info.endPos - info.startPos); + transpinfo.track = info.track; + mltAddClipTransparency(transpinfo, info.track - 1, QString(clip->parent().get("id")).toInt()); } m_isBlocked = false; + m_mltConsumer->set("refresh", 1); return true; } @@ -1774,6 +1886,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn Mlt::Producer trackProducer(tractor.track(startTrack)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); int clipIndex = trackPlaylist.get_clip_index_at(moveStart + 1); + bool checkLength = false; if (endTrack == startTrack) { //mlt_service_lock(service.get_service()); Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex)); @@ -1787,10 +1900,11 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn return false; } else { trackPlaylist.consolidate_blanks(0); - trackPlaylist.insert_at(moveEnd, clipProducer, 1); + 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 { @@ -1805,15 +1919,18 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex)); trackPlaylist.consolidate_blanks(0); destTrackPlaylist.consolidate_blanks(1); - destTrackPlaylist.insert_at(moveEnd, clipProducer, 1); + int newIndex = destTrackPlaylist.insert_at(moveEnd, clipProducer, 1); destTrackPlaylist.consolidate_blanks(0); if (QString(clipProducer.parent().get("transparency")).toInt() == 1) { kDebug() << "//////// moving clip transparency"; mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt()); } + if (clipIndex > trackPlaylist.count()) checkLength = true; + else if (newIndex + 1 == destTrackPlaylist.count()) checkLength = true; } } - mltCheckLength(); + + if (checkLength) mltCheckLength(); mlt_service_unlock(m_mltConsumer->get_service()); m_isBlocked = false; m_mltConsumer->set("refresh", 1); diff --git a/src/renderer.h b/src/renderer.h index b85f9065..b0a1cc38 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -151,11 +151,11 @@ Q_OBJECT public: void mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *prod); void mltUpdateClip(ItemInfo info, QDomElement element, Mlt::Producer *prod); void mltCutClip(int track, GenTime position); - void mltResizeClipEnd(int track, GenTime pos, GenTime in, GenTime out); - bool mltResizeClipStart(int track, GenTime pos, GenTime moveEnd, GenTime moveStart, GenTime in, GenTime out); + bool mltResizeClipEnd(ItemInfo info, GenTime clipDuration); + bool mltResizeClipStart(ItemInfo info, GenTime diff); bool mltMoveClip(int startTrack, int endTrack, GenTime pos, GenTime moveStart); bool mltMoveClip(int startTrack, int endTrack, int pos, int moveStart); - void mltRemoveClip(int track, GenTime position); + bool mltRemoveClip(int track, GenTime position); bool mltRemoveEffect(int track, GenTime position, QString index, bool doRefresh = true); bool mltAddEffect(int track, GenTime position, QMap args, bool doRefresh = true); bool mltEditEffect(int track, GenTime position, QMap args); -- 2.39.2