From: Jean-Baptiste Mardelle Date: Tue, 13 Jan 2009 09:04:00 +0000 (+0000) Subject: Fix lots of issues with slowmotioned clips (bugs in move, resize, copy, load & save) X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=8d7cacd456e882516c49a552253ca6abe9b40843;p=kdenlive Fix lots of issues with slowmotioned clips (bugs in move, resize, copy, load & save) svn path=/branches/KDE4/; revision=2908 --- diff --git a/src/abstractclipitem.cpp b/src/abstractclipitem.cpp index 9a7ed808..353fd9b9 100644 --- a/src/abstractclipitem.cpp +++ b/src/abstractclipitem.cpp @@ -147,8 +147,8 @@ void AbstractClipItem::resizeEnd(int posx, double speed, bool updateKeyFrames) { kDebug() << "///////// CURRENT: " << startPos().frames(25) << "x" << endPos().frames(25) << ", RECT: " << rect() << "-" << pos(); kDebug() << "///////// COLLISION: " << ((AbstractClipItem *)item)->startPos().frames(25) << "x" << ((AbstractClipItem *)item)->endPos().frames(25) << ", RECT: " << ((AbstractClipItem *)item)->rect() << "-" << item->pos();*/ GenTime diff = ((AbstractClipItem *)item)->startPos() - GenTime(1, m_fps) - startPos(); - m_cropDuration = diff; - setRect(0, 0, m_cropDuration.frames(m_fps) - 0.02, rect().height()); + m_cropDuration = diff * speed; + setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height()); break; } } diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 060327fe..b23b6296 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -40,13 +40,17 @@ #include "kthumb.h" -ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, bool generateThumbs) - : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_startThumbRequested(false), m_endThumbRequested(false), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0), framePixelWidth(0), m_startPix(QPixmap()), m_endPix(QPixmap()) { +ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, bool generateThumbs) + : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_startThumbRequested(false), m_endThumbRequested(false), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(speed), framePixelWidth(0), m_startPix(QPixmap()), m_endPix(QPixmap()) { setZValue(1); setRect(0, 0, (info.endPos - info.startPos).frames(fps) - 0.02, (double)(KdenliveSettings::trackheight() - 2)); setPos(info.startPos.frames(fps), (double)(info.track * KdenliveSettings::trackheight()) + 1); - m_clipName = clip->name(); + if (m_speed == 1.0) m_clipName = clip->name(); + else { + m_clipName = clip->name() + " - " + QString::number(m_speed * 100, 'f', 0) + "%"; + m_cropDuration = m_cropDuration * m_speed; + } m_producer = clip->getId(); m_clipType = clip->clipType(); m_cropStart = info.cropStart; @@ -108,12 +112,12 @@ ClipItem::~ClipItem() { } ClipItem *ClipItem::clone(ItemInfo info) const { - ClipItem *duplicate = new ClipItem(m_clip, info, m_fps); + ClipItem *duplicate = new ClipItem(m_clip, info, m_fps, m_speed); if (info.cropStart == cropStart()) duplicate->slotSetStartThumb(m_startPix); if (info.cropStart + (info.endPos - info.startPos) == m_cropStart + m_cropDuration) duplicate->slotSetEndThumb(m_endPix); kDebug() << "// CLoning clip: " << (info.cropStart + (info.endPos - info.startPos)).frames(m_fps) << ", CURRENT end: " << (cropStart() + duration()).frames(m_fps); duplicate->setEffectList(m_effectList.clone()); - duplicate->setSpeed(m_speed); + //duplicate->setSpeed(m_speed); return duplicate; } @@ -462,7 +466,9 @@ DocClipBase *ClipItem::baseClip() const { } QDomElement ClipItem::xml() const { - return m_clip->toXML(); + QDomElement xml = m_clip->toXML(); + if (m_speed != 1.0) xml.setAttribute("speed", m_speed); + return xml; } int ClipItem::clipType() const { @@ -1046,7 +1052,7 @@ QVariant ClipItem::itemChange(GraphicsItemChange change, const QVariant &value) return pos(); } if (forwardMove) { - offset = qMax(offset, (int)(newPos.x() - (static_cast < AbstractClipItem* >(items.at(i))->startPos() - m_cropDuration).frames(m_fps))); + offset = qMax(offset, (int)(newPos.x() - (static_cast < AbstractClipItem* >(items.at(i))->startPos() - cropDuration()).frames(m_fps))); } else { offset = qMax(offset, (int)((static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps)) - newPos.x())); } diff --git a/src/clipitem.h b/src/clipitem.h index 580cf346..7aa29fec 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -40,7 +40,7 @@ class ClipItem : public AbstractClipItem { Q_OBJECT public: - ClipItem(DocClipBase *clip, ItemInfo info, double fps, bool generateThumbs = true); + ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, bool generateThumbs = true); virtual ~ ClipItem(); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 93b79870..9d6d3ca7 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -896,7 +896,7 @@ void CustomTrackView::dragEnterEvent(QDragEnterEvent * event) { info.cropStart = GenTime(list.at(1).toInt(), m_document->fps()); info.endPos = info.startPos + GenTime(list.at(2).toInt() - list.at(1).toInt(), m_document->fps()); info.track = (int)(pos.y() / m_tracksHeight); - ClipItem *item = new ClipItem(clip, info, m_document->fps()); + ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0); m_selectionGroup->addToGroup(item); //TODO: check if we do not overlap another clip when first dropping in timeline // if (insertPossible(m_selectionGroup, event->pos())) @@ -916,7 +916,7 @@ void CustomTrackView::dragEnterEvent(QDragEnterEvent * event) { info.startPos = GenTime(pos.x(), m_document->fps()); info.endPos = info.startPos + clip->duration(); info.track = (int)(pos.y() / m_tracksHeight); - ClipItem *item = new ClipItem(clip, info, m_document->fps()); + ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0); pos.setX(pos.x() + clip->duration().frames(m_document->fps())); m_selectionGroup->addToGroup(item); } @@ -2162,17 +2162,22 @@ void CustomTrackView::changeClipSpeed() { } QUndoCommand *changeSelected = new QUndoCommand(); changeSelected->setText("Edit clip speed"); + int count = 0; for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { ClipItem *item = static_cast (itemList.at(i)); ItemInfo info = item->info(); - int percent = QInputDialog::getInteger(this, i18n("Edit Clip Speed"), i18n("New speed (percents)"), item->speed() * 100, 1, 300); + bool ok; + int percent = QInputDialog::getInteger(this, i18n("Edit Clip Speed"), i18n("New speed (percents)"), item->speed() * 100, 1, 300, 1, &ok); double speed = (double) percent / 100.0; - if (item->speed() != speed) + if (ok && item->speed() != speed) { + count++; new ChangeSpeedCommand(this, info, item->speed(), speed, item->clipProducer(), true, changeSelected); + } } } - m_commandStack->push(changeSelected); + if (count > 0) m_commandStack->push(changeSelected); + else delete changeSelected; } void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, const QString &id) { @@ -2208,7 +2213,7 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i emit displayMessage(i18n("No clip copied"), ErrorMessage); return; } - ClipItem *item = new ClipItem(baseclip, info, m_document->fps()); + ClipItem *item = new ClipItem(baseclip, info, m_document->fps(), xml.attribute("speed", "1").toDouble()); item->setEffectList(effects); scene()->addItem(item); if (item->baseClip()->isTransparent()) { diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 38f1556e..c4bf7dc3 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -375,7 +375,7 @@ void ProjectList::slotProcessNextClipInQueue() { void ProjectList::slotUpdateClip(const QString &id) { ProjectItem *item = getItemById(id); - item->setData(1, UsageRole, QString::number(item->numReferences())); + if (item) item->setData(1, UsageRole, QString::number(item->numReferences())); } void ProjectList::updateAllClips() { diff --git a/src/renderer.cpp b/src/renderer.cpp index d31b98ff..b42ef96f 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -753,6 +753,7 @@ void Render::setSceneList(QDomDocument list, int position) { void Render::setSceneList(QString playlist, int position) { if (m_winid == -1) return; m_isBlocked = true; + m_slowmotionProducers.clear(); //kWarning() << "////// RENDER, SET SCENE LIST: " << playlist; @@ -811,6 +812,7 @@ void Render::setSceneList(QString playlist, int position) { m_fps = m_mltProducer->get_fps(); kDebug() << "// NEW SCENE LIST DURATION SET TO: " << m_mltProducer->get_playtime(); connectPlaylist(); + fillSlowMotionProducers(); if (position != 0) { //TODO: seek to correct place after opening project. // Needs to be done from another place since it crashes here. @@ -1294,6 +1296,28 @@ void Render::mltInsertClip(ItemInfo info, QDomElement element, Mlt::Producer *pr Mlt::Producer trackProducer(tractor.track(info.track)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); //kDebug()<<"/// INSERT cLIP: "<get("resource"); + url.append("?" + QString::number(speed)); + Mlt::Producer *slowprod = m_slowmotionProducers.value(url); + if (!slowprod || slowprod->get_producer() == NULL) { + char *tmp = decodedString(url); + slowprod = new Mlt::Producer(*m_mltProfile, "framebuffer", tmp); + delete[] tmp; + QString id = prod->get("id"); + if (id.contains('_')) id = id.section('_', 0, 0); + QString producerid = "slowmotion:" + id + ":" + QString::number(speed); + tmp = decodedString(producerid); + slowprod->set("id", tmp); + delete[] tmp; + m_slowmotionProducers.insert(url, slowprod); + } + prod = slowprod; + } + Mlt::Producer *clip = prod->cut((int) info.cropStart.frames(m_fps), (int)(info.endPos - info.startPos + info.cropStart).frames(m_fps) - 1); int newIndex = trackPlaylist.insert_at((int) info.startPos.frames(m_fps), *clip, 1); @@ -2684,6 +2708,32 @@ QList Render::producersList() { return prods; } +void Render::fillSlowMotionProducers() { + Mlt::Service service(m_mltProducer->parent().get_service()); + Mlt::Tractor tractor(service); + + int trackNb = tractor.count(); + for (int t = 1; t < trackNb; t++) { + Mlt::Producer trackProducer(tractor.track(t)); + Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); + int clipNb = trackPlaylist.count(); + for (int i = 0; i < clipNb; i++) { + Mlt::Producer *prod = trackPlaylist.get_clip(i); + Mlt::Producer *nprod = new Mlt::Producer(prod->get_parent()); + if (nprod && !nprod->is_blank()) { + QString id = nprod->get("id"); + if (id.startsWith("slowmotion:")) { + // this is a slowmotion producer, add it to the list + QString url = nprod->get("resource"); + if (!m_slowmotionProducers.contains(url)) { + m_slowmotionProducers.insert(url, nprod); + } + } + } + } + } +} + void Render::mltInsertTrack(int ix, bool videoTrack) { blockSignals(true); m_isBlocked = true; diff --git a/src/renderer.h b/src/renderer.h index 3940b943..d13bf111 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -224,6 +224,7 @@ private: // Private attributes & methods QMap m_slowmotionProducers; void buildConsumer(); void resetZoneMode(); + void fillSlowMotionProducers(); private slots: // Private slots /** refresh monitor display */