gain.xml
fade_from_black.xml
fade_to_black.xml
+speed.xml
DESTINATION ${DATA_INSTALL_DIR}/kdenlive/effects)
<!DOCTYPE kpartgui>
-<effect tag="framebuffer">
+<effect tag="framebuffer" id="speed" type="video" unique="1">
<name>Speed</name>
- <description>Make clip play faster slowly</description>
+ <description>Make clip play faster or slower</description>
<author>Jean-Baptiste Mardelle</author>
- <properties id="speed" tag="framebuffer"/>
- <parameter type="constant" name="_speed" max="300" min="1" default="100" factor="100">
+ <parameter type="constant" name="speed" max="1000" min="1" default="100" factor="100" suffix="%">
<name>Speed</name>
</parameter>
<parameter type="constant" name="strobe" max="100" min="1" default="1">
#include <KLocale>
-ChangeSpeedCommand::ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, const QString &clipId, QUndoCommand * parent) :
+ChangeSpeedCommand::ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, int old_strobe, int new_strobe, const QString &clipId, QUndoCommand * parent) :
QUndoCommand(parent),
m_view(view),
m_clipInfo(info),
m_clipId(clipId),
m_old_speed(old_speed),
- m_new_speed(new_speed)
+ m_new_speed(new_speed),
+ m_old_strobe(old_strobe),
+ m_new_strobe(new_strobe)
{
setText(i18n("Adjust clip length"));
}
// virtual
void ChangeSpeedCommand::undo()
{
- m_view->doChangeClipSpeed(m_clipInfo, m_old_speed, m_new_speed, m_clipId);
+ m_view->doChangeClipSpeed(m_clipInfo, m_old_speed, m_new_speed, m_old_strobe, m_clipId);
}
// virtual
void ChangeSpeedCommand::redo()
{
- m_view->doChangeClipSpeed(m_clipInfo, m_new_speed, m_old_speed, m_clipId);
+ m_view->doChangeClipSpeed(m_clipInfo, m_new_speed, m_old_speed, m_new_strobe, m_clipId);
}
class ChangeSpeedCommand : public QUndoCommand
{
public:
- ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, const QString &clipId, QUndoCommand * parent = 0);
+ ChangeSpeedCommand(CustomTrackView *view, ItemInfo info, double old_speed, double new_speed, int old_strobe, int new_strobe, const QString &clipId, QUndoCommand * parent = 0);
virtual void undo();
virtual void redo();
QString m_clipId;
double m_old_speed;
double m_new_speed;
+ int m_old_strobe;
+ int m_new_strobe;
};
#endif
#include <QGraphicsScene>
#include <QMimeData>
-ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, bool generateThumbs) :
+ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, bool generateThumbs) :
AbstractClipItem(info, QRectF(), fps),
m_clip(clip),
m_startFade(0),
m_startPix(QPixmap()),
m_endPix(QPixmap()),
m_hasThumbs(false),
- m_startThumbTimer(NULL),
- m_endThumbTimer(NULL),
m_selectedEffect(-1),
m_timeLine(0),
m_startThumbRequested(false),
m_endThumbRequested(false),
//m_hover(false),
m_speed(speed),
+ m_strobe(strobe),
m_framePixelWidth(0)
{
setZValue(2);
if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW || m_clipType == PLAYLIST) {
setBrush(QColor(141, 166, 215));
m_hasThumbs = true;
- m_startThumbTimer = new QTimer(this);
- m_startThumbTimer->setSingleShot(true);
- connect(m_startThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetStartThumb()));
- m_endThumbTimer = new QTimer(this);
- m_endThumbTimer->setSingleShot(true);
- connect(m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb()));
+ m_startThumbTimer.setSingleShot(true);
+ connect(&m_startThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetStartThumb()));
+ m_endThumbTimer.setSingleShot(true);
+ connect(&m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb()));
connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int)));
//connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(getVideoThumbs(int, int)));
disconnect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
disconnect(m_clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData()));
}
- delete m_startThumbTimer;
- delete m_endThumbTimer;
delete m_timeLine;
}
ClipItem *ClipItem::clone(ItemInfo info) const
{
- ClipItem *duplicate = new ClipItem(m_clip, info, m_fps, m_speed);
+ ClipItem *duplicate = new ClipItem(m_clip, info, m_fps, m_speed, m_strobe);
if (m_clipType == IMAGE || m_clipType == TEXT) duplicate->slotSetStartThumb(m_startPix);
else {
if (info.cropStart == m_cropStart) duplicate->slotSetStartThumb(m_startPix);
{
QDomElement xml = m_clip->toXML();
if (m_speed != 1.0) xml.setAttribute("speed", m_speed);
+ if (m_strobe > 1) xml.setAttribute("strobe", m_strobe);
if (m_audioOnly) xml.setAttribute("audio_only", 1);
else if (m_videoOnly) xml.setAttribute("video_only", 1);
return xml;
checkEffectsKeyframesPos(previous, cropStart().frames(m_fps), true);
if (m_hasThumbs && KdenliveSettings::videothumbnails()) {
/*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/
- m_startThumbTimer->start(150);
+ m_startThumbTimer.start(150);
}
}
}
if (updateKeyFrames) checkEffectsKeyframesPos(previous, (cropStart() + cropDuration()).frames(m_fps), false);
if (m_hasThumbs && KdenliveSettings::videothumbnails()) {
/*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/
- m_endThumbTimer->start(150);
+ m_endThumbTimer.start(150);
}
}
}
return m_speed;
}
-void ClipItem::setSpeed(const double speed)
+int ClipItem::strobe() const
+{
+ return m_strobe;
+}
+
+void ClipItem::setSpeed(const double speed, const int strobe)
{
m_speed = speed;
+ m_strobe = strobe;
if (m_speed == 1.0) m_clipName = baseClip()->name();
else m_clipName = baseClip()->name() + " - " + QString::number(speed * 100, 'f', 0) + '%';
//update();
Q_OBJECT
public:
- ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, bool generateThumbs = true);
+ ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, int strobe, bool generateThumbs = true);
virtual ~ ClipItem();
virtual void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QString keyframes(const int index);
void setKeyframes(const int ix, const QString keyframes);
void setEffectList(const EffectsList effectList);
- void setSpeed(const double speed);
+ void setSpeed(const double speed, int strobe);
double speed() const;
+ int strobe() const;
GenTime maxDuration() const;
GenTime cropStart() const;
GenTime endPos() const;
QPixmap m_startPix;
QPixmap m_endPix;
bool m_hasThumbs;
- QTimer *m_startThumbTimer;
- QTimer *m_endThumbTimer;
+ QTimer m_startThumbTimer;
+ QTimer m_endThumbTimer;
int m_selectedEffect;
QTimeLine *m_timeLine;
bool m_endThumbRequested;
//bool m_hover;
double m_speed;
+ int m_strobe;
EffectsList m_effectList;
QList <Transition*> m_transitionsList;
ClipManager::~ClipManager()
{
+ kDebug() << "\n\n 2222222222222222222222222 CLOSE CM 22222222222";
qDeleteAll(m_clipList);
}
KMimeType::Ptr type = KMimeType::findByUrl(file);
if (type->name().startsWith("image/")) {
prod.setAttribute("type", (int) IMAGE);
- prod.setAttribute("in", "0");
+ prod.setAttribute("in", 0);
prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()) - 1);
+ } else if (type->name() == "application/x-kdenlivetitle") {
+ // opening a title file
+ QDomDocument txtdoc("titledocument");
+ QFile txtfile(file.path());
+ if (txtfile.open(QIODevice::ReadOnly) && txtdoc.setContent(&txtfile)) {
+ txtfile.close();
+ prod.setAttribute("type", (int) TEXT);
+ prod.setAttribute("resource", QString());
+ prod.setAttribute("xmldata", txtdoc.toString());
+ GenTime outPos(txtdoc.documentElement().attribute("out").toDouble() / 1000.0);
+ prod.setAttribute("transparency", 1);
+ prod.setAttribute("in", 0);
+ int out = (int) outPos.frames(m_doc->fps());
+ if (out > 0) prod.setAttribute("out", out);
+ } else txtfile.close();
}
new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true, addClips);
}
prod.setAttribute("type", (int) IMAGE);
prod.setAttribute("in", "0");
prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()) - 1);
+ } else if (type->name() == "application/x-kdenlivetitle") {
+ // opening a title file
+ QDomDocument txtdoc("titledocument");
+ QFile txtfile(url.path());
+ if (txtfile.open(QIODevice::ReadOnly) && txtdoc.setContent(&txtfile)) {
+ txtfile.close();
+ prod.setAttribute("type", (int) TEXT);
+ prod.setAttribute("resource", QString());
+ prod.setAttribute("xmldata", txtdoc.toString());
+ GenTime outPos(txtdoc.documentElement().attribute("out").toDouble() / 1000.0);
+ prod.setAttribute("transparency", 1);
+ prod.setAttribute("in", 0);
+ int out = (int) outPos.frames(m_doc->fps());
+ if (out > 0) prod.setAttribute("out", out);
+ } else txtfile.close();
}
AddClipCommand *command = new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true);
m_doc->commandStack()->push(command);
-void ClipManager::slotAddTextClipFile(const QString titleName, const QString imagePath, const QString xml, const QString group, const QString &groupId)
+void ClipManager::slotAddTextClipFile(const QString titleName, int out, const QString xml, const QString group, const QString &groupId)
{
QDomDocument doc;
QDomElement prod = doc.createElement("producer");
doc.appendChild(prod);
- prod.setAttribute("resource", imagePath);
+ //prod.setAttribute("resource", imagePath);
prod.setAttribute("name", titleName);
prod.setAttribute("xmldata", xml);
uint id = m_clipIdCounter++;
prod.setAttribute("type", (int) TEXT);
prod.setAttribute("transparency", "1");
prod.setAttribute("in", "0");
- prod.setAttribute("out", m_doc->getFramePos(KdenliveSettings::image_duration()) - 1);
+ prod.setAttribute("out", out);
AddClipCommand *command = new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true);
m_doc->commandStack()->push(command);
}
void deleteClip(const QString &clipId);
void slotAddClipFile(const KUrl url, const QString group, const QString &groupId);
void slotAddClipList(const KUrl::List urls, const QString group, const QString &groupId);
- void slotAddTextClipFile(const QString titleName, const QString imagePath, const QString xml, const QString group, const QString &groupId);
+ void slotAddTextClipFile(const QString titleName, int out, const QString xml, const QString group, const QString &groupId);
void slotAddTextTemplateClip(QString titleName, const QString imagePath, const KUrl path, const QString group, const QString &groupId);
void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const QString &groupId);
void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, const bool fade, const QString &luma_duration, const QString &luma_file, const int softness, const QString group, const QString &groupId);
m_animation(NULL),
m_clickPoint(),
m_autoScroll(KdenliveSettings::autoscroll()),
- m_changeSpeedAction(NULL),
m_pasteEffectsAction(NULL),
m_ungroupAction(NULL),
m_scrollOffset(0),
m_clipTypeGroup = clipTypeGroup;
QList <QAction *> list = m_timelineContextClipMenu->actions();
for (int i = 0; i < list.count(); i++) {
- if (list.at(i)->data().toString() == "change_speed") m_changeSpeedAction = list.at(i);
- else if (list.at(i)->data().toString() == "paste_effects") m_pasteEffectsAction = list.at(i);
+ if (list.at(i)->data().toString() == "paste_effects") m_pasteEffectsAction = list.at(i);
else if (list.at(i)->data().toString() == "ungroup_clip") m_ungroupAction = list.at(i);
}
return;
} else {
if (m_visualTip) {
+ m_animationTimer->stop();
delete m_animation;
m_animation = NULL;
- m_animationTimer->stop();
delete m_visualTip;
m_visualTip = NULL;
}
setCursor(Qt::SplitHCursor);
} else {
if (m_visualTip) {
- delete m_animation;
m_animationTimer->stop();
+ delete m_animation;
m_animation = NULL;
delete m_visualTip;
m_visualTip = NULL;
groupSelectedItems();
ClipItem *clip = static_cast <ClipItem *>(m_dragItem);
updateClipTypeActions(dragGroup == NULL ? clip : NULL);
- m_changeSpeedAction->setEnabled(clip->clipType() == AV || clip->clipType() == VIDEO);
m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
}
m_editGuide->setEnabled(m_dragGuide != NULL);
if (clip == NULL) m_timelineContextMenu->popup(pos);
else if (group != NULL) {
- m_changeSpeedAction->setEnabled(false);
m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
m_ungroupAction->setEnabled(true);
updateClipTypeActions(NULL);
if (clip->type() == AVWIDGET) {
ClipItem *item = static_cast <ClipItem*>(clip);
updateClipTypeActions(item);
- m_changeSpeedAction->setEnabled(item->clipType() == AV || item->clipType() == VIDEO);
m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
m_timelineContextClipMenu->popup(pos);
} else if (clip->type() == TRANSITIONWIDGET) m_timelineContextTransitionMenu->popup(pos);
info.cropStart = GenTime(list.at(1).toInt(), m_document->fps());
info.endPos = GenTime(list.at(2).toInt() - list.at(1).toInt(), m_document->fps());
info.track = (int)(1 / m_tracksHeight);
- ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0);
+ ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1);
m_selectionGroup->addToGroup(item);
item->setFlags(QGraphicsItem::ItemIsSelectable);
//TODO: check if we do not overlap another clip when first dropping in timeline
info.startPos = start;
info.endPos = info.startPos + clip->duration();
info.track = (int)(1 / m_tracksHeight);
- ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, false);
+ ClipItem *item = new ClipItem(clip, info, m_document->fps(), 1.0, 1, false);
start += clip->duration();
offsetList.append(start);
m_selectionGroup->addToGroup(item);
{
ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_document->tracksCount() - track);
if (clip) {
+ // Special case: speed effect
+ if (effect.attribute("id") == "speed") {
+ if (clip->clipType() != VIDEO && clip->clipType() != AV && clip->clipType() != PLAYLIST) {
+ emit displayMessage(i18n("Problem adding effect to clip"), ErrorMessage);
+ return;
+ }
+ ItemInfo info = clip->info();
+ double speed = EffectsList::parameter(effect, "speed").toDouble() / 100.0;
+ int strobe = EffectsList::parameter(effect, "strobe").toInt();
+ if (strobe == 0) strobe = 1;
+ doChangeClipSpeed(info, speed, 1.0, strobe, clip->baseClip()->getId());
+ clip->addEffect(effect);
+ emit clipItemSelected(clip);
+ return;
+ }
+
if (!m_document->renderer()->mltAddEffect(track, pos, clip->addEffect(effect)))
emit displayMessage(i18n("Problem adding effect to clip"), ErrorMessage);
emit clipItemSelected(clip);
void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect)
{
QString index = effect.attribute("kdenlive_ix");
+ // Special case: speed effect
+ if (effect.attribute("id") == "speed") {
+ ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_document->tracksCount() - track);
+ if (clip) {
+ ItemInfo info = clip->info();
+ doChangeClipSpeed(info, 1.0, clip->speed(), 1, clip->baseClip()->getId());
+ clip->deleteEffect(index);
+ emit clipItemSelected(clip);
+ return;
+ }
+ }
if (!m_document->renderer()->mltRemoveEffect(track, pos, index, true) && effect.attribute("disabled") != "1") {
kDebug() << "// ERROR REMOV EFFECT: " << index << ", DISABLE: " << effect.attribute("disabled");
emit displayMessage(i18n("Problem deleting effect"), ErrorMessage);
{
ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_document->tracksCount() - track);
if (clip) {
+
+
+ // Special case: speed effect
+ if (effect.attribute("id") == "speed") {
+ ItemInfo info = clip->info();
+ double speed = EffectsList::parameter(effect, "speed").toDouble() / 100.0;
+ int strobe = EffectsList::parameter(effect, "strobe").toInt();
+ if (strobe == 0) strobe = 1;
+ doChangeClipSpeed(info, speed, clip->speed(), strobe, clip->baseClip()->getId());
+ clip->setEffectAt(ix, effect);
+ if (ix == clip->selectedEffectIndex()) {
+ clip->setSelectedEffect(ix);
+ }
+ return;
+ }
+
+
+
+
EffectsParameterList effectParams = clip->getEffectArgs(effect);
if (effect.attribute("tag") == "ladspa") {
// Update the ladspa affect file
{
QDomElement effect = clip->effectAt(effectPos);
QDomElement oldEffect = effect.cloneNode().toElement();
+
+ if (effect.attribute("id") == "speed") {
+ if (clip) {
+ ItemInfo info = clip->info();
+ effect.setAttribute("disabled", disable);
+ if (disable) doChangeClipSpeed(info, 1.0, clip->speed(), 1, clip->baseClip()->getId());
+ else {
+ double speed = EffectsList::parameter(effect, "speed").toDouble() / 100.0;
+ int strobe = EffectsList::parameter(effect, "strobe").toInt();
+ if (strobe == 0) strobe = 1;
+ doChangeClipSpeed(info, speed, 1.0, strobe, clip->baseClip()->getId());
+ }
+ return;
+ }
+ }
effect.setAttribute("disabled", disable);
EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, true);
m_commandStack->push(command);
bool isLocked = m_document->trackInfoAt(tracknumber).isLocked;
if (isLocked) item->setItemLocked(true);
- if (item->baseClip()->isTransparent() && getTransitionItemAtStart(info.startPos, info.track) == NULL) {
+ /*if (item->baseClip()->isTransparent() && getTransitionItemAtStart(info.startPos, info.track) == NULL) {
// add transparency transition
- new AddTransitionCommand(this, info, getPreviousVideoTrack(info.track), MainWindow::transitions.getEffectByTag("composite", "composite"), false, true, addCommand);
- }
+ QDomElement trans = MainWindow::transitions.getEffectByTag("composite", "composite").cloneNode().toElement();
+ new AddTransitionCommand(this, info, getPreviousVideoTrack(info.track), trans, false, true, addCommand);
+ }*/
info.track = m_document->tracksCount() - item->track();
m_document->renderer()->mltInsertClip(info, item->xml(), item->baseClip()->producer(item->track()));
item->setSelected(true);
}
m_commandStack->push(addCommand);
setDocumentModified();
- m_changeSpeedAction->setEnabled(hasVideoClip);
m_pasteEffectsAction->setEnabled(m_copiedItems.count() == 1);
if (items.count() > 1) groupSelectedItems(true);
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
} else QGraphicsView::dropEvent(event);
setFocus();
}
else if (item->isVideoOnly()) prod = item->baseClip()->videoProducer();
else prod = item->baseClip()->producer(m_dragItemInfo.track);
bool success = m_document->renderer()->mltMoveClip((int)(m_document->tracksCount() - m_dragItemInfo.track), (int)(m_document->tracksCount() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps())), prod);
+
if (success) {
kDebug() << "// get trans info";
int tracknumber = m_document->tracksCount() - item->track() - 1;
double speed = (double) percent / 100.0;
if (item->speed() != speed && (item->clipType() == VIDEO || item->clipType() == AV)) {
count++;
- new ChangeSpeedCommand(this, info, item->speed(), speed, item->clipProducer(), changeSelected);
+ //new ChangeSpeedCommand(this, info, item->speed(), speed, item->clipProducer(), changeSelected);
}
}
}
else delete changeSelected;
}
-void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, const QString &id)
+void CustomTrackView::doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, int strobe, const QString &id)
{
DocClipBase *baseclip = m_document->clipManager()->getClipById(id);
ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()), info.track);
return;
}
info.track = m_document->tracksCount() - item->track();
- int endPos = m_document->renderer()->mltChangeClipSpeed(info, speed, oldspeed, baseclip->producer());
+ int endPos = m_document->renderer()->mltChangeClipSpeed(info, speed, oldspeed, strobe, baseclip->producer());
if (endPos >= 0) {
- item->setSpeed(speed);
+ item->setSpeed(speed, strobe);
item->updateRectGeometry();
if (item->cropDuration().frames(m_document->fps()) > endPos)
item->AbstractClipItem::resizeEnd(info.startPos.frames(m_document->fps()) + endPos, speed);
emit displayMessage(i18n("No clip copied"), ErrorMessage);
return;
}
- ClipItem *item = new ClipItem(baseclip, info, m_document->fps(), xml.attribute("speed", "1").toDouble());
+ ClipItem *item = new ClipItem(baseclip, info, m_document->fps(), xml.attribute("speed", "1").toDouble(), xml.attribute("strobe", "1").toInt());
item->setEffectList(effects);
if (xml.hasAttribute("audio_only")) item->setAudioOnly(true);
else if (xml.hasAttribute("video_only")) item->setVideoOnly(true);
void clipStart();
void clipEnd();
void changeClipSpeed();
- void doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, const QString &id);
+ void doChangeClipSpeed(ItemInfo info, const double speed, const double oldspeed, int strobe, const QString &id);
void setDocumentModified();
void setInPoint();
void setOutPoint();
QMenu *m_timelineContextClipMenu;
QMenu *m_timelineContextTransitionMenu;
QAction *m_autoTransition;
- QAction *m_changeSpeedAction;
QAction *m_pasteEffectsAction;
QAction *m_ungroupAction;
QAction *m_editGuide;
DocClipBase::~DocClipBase()
{
+ kDebug() << "CLIP " << m_id << " DELETED******************************";
delete m_thumbProd;
if (m_audioTimer) {
m_audioTimer->stop();
delete m_audioTimer;
}
+ /*kDebug() <<" * * *CNT "<<m_baseTrackProducers.count();
+ if (m_baseTrackProducers.count() > 0) kDebug()<<"YOYO: "<<m_baseTrackProducers.at(0)->get_out()<<", CUT: "<<m_baseTrackProducers.at(0)->is_cut();*/
qDeleteAll(m_baseTrackProducers);
m_baseTrackProducers.clear();
qDeleteAll(m_audioTrackProducers);
char *tmp = (char *) qstrdup(value.toUtf8().data());
setProducerProperty("colour", tmp);
delete[] tmp;
- } else if (key == "xmldata") {
+ } else if (key == "templatetext") {
+ char *tmp = (char *) qstrdup(value.toUtf8().data());
+ setProducerProperty("templatetext", tmp);
+ delete[] tmp;
setProducerProperty("force_reload", 1);
+ } else if (key == "xmldata") {
+ char *tmp = (char *) qstrdup(value.toUtf8().data());
+ setProducerProperty("xmldata", tmp);
+ delete[] tmp;
+ //setProducerProperty("force_reload", 1);
} else if (key == "force_aspect_ratio") {
if (value.isEmpty()) {
m_properties.remove("force_aspect_ratio");
if (pa.attribute("max").startsWith('%')) {
max = (int) ProfilesDialog::getStringEval(m_profile, pa.attribute("max"));
} else max = pa.attribute("max").toInt();
- createSliderItem(paramName, (int)(value.toDouble() + 0.5) , min, max);
+ createSliderItem(paramName, (int)(value.toDouble() + 0.5) , min, max, pa.attribute("suffix", QString()));
delete toFillin;
toFillin = NULL;
} else if (type == "list") {
emit parameterChanged(oldparam, m_params);
}
-void EffectStackEdit::createSliderItem(const QString& name, int val , int min, int max)
+void EffectStackEdit::createSliderItem(const QString& name, int val , int min, int max, const QString suffix)
{
QWidget* toFillin = new QWidget;
Constval *ctval = new Constval;
ctval->setupUi(toFillin);
ctval->horizontalSlider->setMinimum(min);
ctval->horizontalSlider->setMaximum(max);
+ if (!suffix.isEmpty()) ctval->spinBox->setSuffix(suffix);
ctval->spinBox->setMinimum(min);
ctval->spinBox->setMaximum(max);
ctval->horizontalSlider->setPageStep((int)(max - min) / 10);
QList<UiItem*> m_uiItems;
QDomElement m_params;
QMap<QString, void*> m_valueItems;
- void createSliderItem(const QString& name, int val , int min, int max);
+ void createSliderItem(const QString& name, int val , int min, int max, const QString);
wipeInfo getWipeInfo(QString value);
QString getWipeString(wipeInfo info);
MltVideoProfile m_profile;
void Geometryval::slotAddFrame(int pos)
{
- if (pos == -1) pos = m_ui.spinPos->value();
+ if (pos = -1) pos = m_ui.spinPos->value();
Mlt::GeometryItem item;
item.frame(pos);
item.x(m_paramRect->pos().x());
KdenliveDoc::~KdenliveDoc()
{
+ m_autoSaveTimer->stop();
delete m_commandStack;
+ kDebug() << "// DEL CLP MAN";
delete m_clipManager;
+ kDebug() << "// DEL CLP MAN done";
delete m_autoSaveTimer;
if (m_autosave) {
if (!m_autosave->fileName().isEmpty()) m_autosave->remove();
if (elem.attribute("type").toInt() == SLIDESHOW) {
extension = KUrl(path).fileName();
path = KUrl(path).directory();
- } else if (elem.attribute("type").toInt() == TEXT && QFile::exists(path) == false) {
+ } /*else if (elem.attribute("type").toInt() == TEXT && QFile::exists(path) == false) {
kDebug() << "// TITLE: " << elem.attribute("name") << " Preview file: " << elem.attribute("resource") << " DOES NOT EXIST";
QString titlename = elem.attribute("name");
QString titleresource;
elem.setAttribute("resource", titleresource);
setNewClipResource(clipId, titleresource);
delete dia_ui;
- }
+ }*/
if (path.isEmpty() == false && QFile::exists(path) == false && elem.attribute("type").toInt() != TEXT && !elem.hasAttribute("placeholder")) {
kDebug() << "// FOUND MISSING CLIP: " << path << ", TYPE: " << elem.attribute("type").toInt();
{
QString titlesFolder = projectFolder().path(KUrl::AddTrailingSlash) + "titles/";
KStandardDirs::makeDir(titlesFolder);
- TitleWidget *dia_ui = new TitleWidget(templatePath, titlesFolder, m_render, kapp->activeWindow());
+ TitleWidget *dia_ui = new TitleWidget(templatePath, m_timecode, titlesFolder, m_render, kapp->activeWindow());
if (dia_ui->exec() == QDialog::Accepted) {
- QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder());
+ /*QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder());
QImage pix = dia_ui->renderedPixmap();
- pix.save(titleInfo.at(1));
+ pix.save(titleInfo.at(1));*/
//dia_ui->saveTitle(path + ".kdenlivetitle");
- m_clipManager->slotAddTextClipFile(titleInfo.at(0), titleInfo.at(1), dia_ui->xml().toString(), group, groupId);
+ m_clipManager->slotAddTextClipFile(i18n("Title clip"), dia_ui->duration(), dia_ui->xml().toString(), group, groupId);
setModified(true);
emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
}
QStringList titleInfo = TitleWidget::getFreeTitleInfo(projectFolder(), true);
- TitleWidget *dia_ui = new TitleWidget(path, titlesFolder, m_render, kapp->activeWindow());
+ //TODO: rewrite with new title system (just set resource)
+ /*TitleWidget *dia_ui = new TitleWidget(path, titlesFolder, m_render, kapp->activeWindow());
QImage pix = dia_ui->renderedPixmap();
pix.save(titleInfo.at(1));
delete dia_ui;
m_clipManager->slotAddTextTemplateClip(titleInfo.at(0), titleInfo.at(1), path, group, groupId);
- setModified(true);
+ setModified(true);*/
emit selectLastAddedClip(QString::number(m_clipManager->lastClipId()));
}
<Menu name="timeline" ><text>Timeline</text>
<Action name="cut_timeline_clip" />
<Action name="delete_timeline_clip" />
- <Action name="change_clip_speed" />
<Menu name="guide_menu" ><text>Guides</text>
<Action name="add_guide" />
<Action name="edit_guide" />
m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));
m_timelineContextClipMenu->addAction(actionCollection()->action("delete_timeline_clip"));
- m_timelineContextClipMenu->addAction(actionCollection()->action("change_clip_speed"));
m_timelineContextClipMenu->addAction(actionCollection()->action("group_clip"));
m_timelineContextClipMenu->addAction(actionCollection()->action("ungroup_clip"));
m_timelineContextClipMenu->addAction(actionCollection()->action("cut_timeline_clip"));
void MainWindow::queryQuit()
{
- kDebug() << "----- SAVING CONFUIG";
- if (queryClose()) {
- Mlt::Factory::close();
- kapp->quit();
- }
+ delete m_effectStack;
+ delete m_activeTimeline;
+ delete m_projectMonitor;
+ kDebug() << "// DEL MON 1 done";
+ delete m_clipMonitor;
+ kDebug() << "// DEL MON 2 done";
+ delete m_activeDocument;
+ Mlt::Factory::close();
+ qApp->quit();
+ /*
+ if (queryClose()) {
+ Mlt::Factory::close();
+ kapp->quit();
+ }*/
}
//virtual
collection->addAction("delete_timeline_clip", deleteTimelineClip);
connect(deleteTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotDeleteTimelineClip()));
- KAction* editTimelineClipSpeed = new KAction(i18n("Change Clip Speed"), this);
+ /*KAction* editTimelineClipSpeed = new KAction(i18n("Change Clip Speed"), this);
collection->addAction("change_clip_speed", editTimelineClipSpeed);
editTimelineClipSpeed->setData("change_speed");
- connect(editTimelineClipSpeed, SIGNAL(triggered(bool)), this, SLOT(slotChangeClipSpeed()));
+ connect(editTimelineClipSpeed, SIGNAL(triggered(bool)), this, SLOT(slotChangeClipSpeed()));*/
KAction *stickTransition = collection->addAction("auto_transition");
stickTransition->setData(QString("auto"));
}
}
-void MainWindow::slotChangeClipSpeed()
-{
- if (m_activeTimeline) {
- m_activeTimeline->projectView()->changeClipSpeed();
- }
-}
-
void MainWindow::slotAddClipMarker()
{
DocClipBase *clip = NULL;
return;
}
QString path = clip->getProperty("resource");
- TitleWidget *dia_ui = new TitleWidget(KUrl(), titlepath, m_projectMonitor->render, this);
+ TitleWidget *dia_ui = new TitleWidget(KUrl(), m_activeDocument->timecode(), titlepath, m_projectMonitor->render, this);
QDomDocument doc;
doc.setContent(clip->getProperty("xmldata"));
dia_ui->setXml(doc);
QRect rect = dia_ui->renderedRect();
QMap <QString, QString> newprops;
newprops.insert("xmldata", dia_ui->xml().toString());
+ newprops.insert("out", QString::number(dia_ui->duration()));
newprops.insert("frame_size", QString::number(rect.width()) + 'x' + QString::number(rect.height()));
EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), newprops, true);
m_activeDocument->commandStack()->push(command);
void slotPaste();
void slotPasteEffects();
void slotReloadEffects();
- void slotChangeClipSpeed();
void slotAdjustClipMonitor();
void slotAdjustProjectMonitor();
<sub-class-of type="video/mlt-playlist"/>
<glob pattern="*.kdenlive"/>
</mime-type>
+ <mime-type type="application/x-kdenlivetitle">
+ <comment>Kdenlive video title</comment>
+ <sub-class-of type="application/xml"/>
+ <glob pattern="*.kdenlivetitle"/>
+ </mime-type>
</mime-info>
delete m_timePos;
delete m_overlay;
delete m_monitorRefresh;
+ delete render;
}
QString Monitor::name() const
ProjectItem *item = getItemById(id);
if (item) {
slotUpdateClipProperties(item, properties);
- if (properties.contains("colour") || properties.contains("resource") || properties.contains("xmldata") || properties.contains("force_aspect_ratio")) {
+ if (properties.contains("colour") || properties.contains("resource") || properties.contains("xmldata") || properties.contains("force_aspect_ratio") || properties.contains("templatetext")) {
slotRefreshClipThumbnail(item);
emit refreshClip();
}
{
if (!clip) return;
if (!clip->isGroup()) clip->setProperties(properties);
- if (properties.contains("xmldata")) regenerateTemplateImage(clip);
+ //if (properties.contains("xmldata")) regenerateTemplateImage(clip);
if (properties.contains("name")) {
m_listView->blockSignals(true);
clip->setText(1, properties.value("name"));
oldprops["description"] = clip->referencedClip()->getProperty("description");
newprops["description"] = item->text(2);
- if (clip->clipType() == TEXT && !clip->referencedClip()->getProperty("xmltemplate").isEmpty()) {
+ if (clip->clipType() == TEXT && !clip->referencedClip()->getProperty("xmldata").isEmpty()) {
// This is a text template clip, update the image
- oldprops.insert("xmldata", clip->referencedClip()->getProperty("xmldata"));
- newprops.insert("xmldata", generateTemplateXml(clip->referencedClip()->getProperty("xmltemplate"), item->text(2)).toString());
+ /*oldprops.insert("xmldata", clip->referencedClip()->getProperty("xmldata"));
+ newprops.insert("xmldata", generateTemplateXml(clip->referencedClip()->getProperty("xmltemplate"), item->text(2)).toString());*/
+ oldprops.insert("templatetext", clip->referencedClip()->getProperty("templatetext"));
+ newprops.insert("templatetext", item->text(2));
}
slotUpdateClipProperties(clip->clipId(), newprops);
ProjectItem *item = static_cast <ProjectItem *>(*it);
if (!item->isGroup()) {
DocClipBase *clip = item->referencedClip();
- if (clip->clipType() == TEXT && !QFile::exists(clip->fileURL().path())) {
+ /*if (clip->clipType() == TEXT && !QFile::exists(clip->fileURL().path())) {
// regenerate text clip image if required
TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this);
QDomDocument doc;
QImage pix = dia_ui->renderedPixmap();
pix.save(clip->fileURL().path());
delete dia_ui;
- }
+ }*/
if (item->referencedClip()->producer() == NULL) {
if (clip->isPlaceHolder() == false) requestClipInfo(clip->toXML(), clip->getId());
KUrl::List list;
if (givenList.isEmpty()) {
// Build list of mime types
- QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mlt-playlist" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
+ QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "application/x-kdenlivetitle" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mlt-playlist" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
QString allExtensions;
foreach(const QString& mimeType, mimeTypes) {
void ProjectList::regenerateTemplate(ProjectItem *clip)
{
+ //TODO: remove this unused method, only force_reload is necessary
// Generate image for template clip
- const QString comment = clip->referencedClip()->getProperty("description");
- const QString path = clip->referencedClip()->getProperty("xmltemplate");
+ /*const QString comment = clip->referencedClip()->getProperty("description");
+ const QString path = clip->referencedClip()->getProperty("resource");
QDomDocument doc = generateTemplateXml(path, comment);
TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this);
dia_ui->setXml(doc);
QImage pix = dia_ui->renderedPixmap();
pix.save(clip->clipUrl().path());
- delete dia_ui;
+ delete dia_ui;*/
clip->referencedClip()->producer()->set("force_reload", 1);
}
void ProjectList::regenerateTemplateImage(ProjectItem *clip)
{
+ //TODO: remove this unused method
// Generate image for template clip
- TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this);
+ /*TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this);
QDomDocument doc;
doc.setContent(clip->referencedClip()->getProperty("xmldata"));
dia_ui->setXml(doc);
QImage pix = dia_ui->renderedPixmap();
pix.save(clip->clipUrl().path());
- delete dia_ui;
+ delete dia_ui;*/
}
QDomDocument ProjectList::generateTemplateXml(QString path, const QString &replaceString)
}
}
emit addClip(event->mimeData()->urls(), groupName, groupId);
+ event->setDropAction(Qt::CopyAction);
+ event->accept();
+ return;
} else if (event->mimeData()->hasFormat("kdenlive/producerslist")) {
ProjectItem *item = static_cast <ProjectItem *>(itemAt(event->pos()));
if (item) {
drag->setMimeData(mimeData);
drag->setPixmap(clickItem->icon(0).pixmap(iconSize()));
drag->setHotSpot(QPoint(0, 50));
- drag->exec(Qt::MoveAction);
+ drag->exec();
}
//event->accept();
}
// virtual
void ProjectListView::dragMoveEvent(QDragMoveEvent * event)
{
- event->setDropAction(Qt::IgnoreAction);
- event->setDropAction(Qt::MoveAction);
+ //event->setDropAction(Qt::MoveAction);
if (event->mimeData()->hasText()) {
event->acceptProposedAction();
}
m_winid(winid)
{
kDebug() << "////////// USING PROFILE: " << (char*)KdenliveSettings::current_profile().toUtf8().data();
- m_refreshTimer = new QTimer(this);
- connect(m_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
/*if (rendererName == "project") m_monitorId = 10000;
else m_monitorId = 10001;*/
- m_osdTimer = new QTimer(this);
- connect(m_osdTimer, SIGNAL(timeout()), this, SLOT(slotOsdTimeout()));
+ /*m_osdTimer = new QTimer(this);
+ connect(m_osdTimer, SIGNAL(timeout()), this, SLOT(slotOsdTimeout()));*/
buildConsumer();
void Render::closeMlt()
{
- delete m_osdTimer;
- delete m_refreshTimer;
+ //delete m_osdTimer;
+
+ Mlt::Service service(m_mltProducer->get_service());
+ if (service.type() == tractor_type) {
+ Mlt::Tractor tractor(service);
+ int trackNb = tractor.count();
+
+ while (trackNb > 1) {
+ Mlt::Producer trackProducer(tractor.track(trackNb - 1));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+ trackPlaylist.clear();
+ trackNb--;
+ }
+ }
+
+ kDebug() << "// // // CLOSE RENDERER";
delete m_mltConsumer;
delete m_mltProducer;
delete m_blackClip;
{
KUrl url = KUrl(xml.attribute("resource", QString()));
Mlt::Producer *producer = NULL;
- if (xml.attribute("type").toInt() == TEXT && !QFile::exists(url.path())) {
+ /*if (xml.attribute("type").toInt() == TEXT && !QFile::exists(url.path())) {
emit replyGetFileProperties(clipId, producer, QMap < QString, QString >(), QMap < QString, QString >(), replaceProducer);
return;
- }
+ }*/
if (xml.attribute("type").toInt() == COLOR) {
char *tmp = decodedString("colour:" + xml.attribute("colour"));
producer = new Mlt::Producer(*m_mltProfile, 0, tmp);
delete[] tmp;
+ } else if (xml.attribute("type").toInt() == TEXT) {
+ char *tmp = decodedString("kdenlivetitle:" + xml.attribute("resource"));
+ producer = new Mlt::Producer(*m_mltProfile, 0, tmp);
+ delete[] tmp;
+ if (xml.hasAttribute("xmldata")) {
+ char *tmp = decodedString(xml.attribute("xmldata"));
+ producer->set("xmldata", tmp);
+ delete[] tmp;
+ }
} else if (url.isEmpty()) {
QDomDocument doc;
QDomElement mlt = doc.createElement("mlt");
tmppath = decodedString(desc);
Mlt::Playlist list;
list.insert_at(0, prod, 0);
+ delete prod;
list.set("title", tmppath);
delete[] tmppath;
xmlConsumer.connect(list);
if (m_mltProducer->attach(*m_osdInfo) == 1) kDebug()<<"////// error attaching filter";
}*/
refresh();
- m_osdTimer->setSingleShot(2500);
+ //m_osdTimer->setSingleShot(2500);
}
void Render::slotOsdTimeout()
refresh();
}
-void Render::askForRefresh()
-{
- // Use a Timer so that we don't refresh too much
- m_refreshTimer->start(300);
-}
-
void Render::doRefresh()
{
// Use a Timer so that we don't refresh too much
{
if (!m_mltProducer || m_isBlocked)
return;
- m_refreshTimer->stop();
if (m_mltConsumer) {
m_mltConsumer->set("refresh", 1);
}
Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
//kDebug()<<"/// INSERT cLIP: "<<info.cropStart.frames(m_fps)<<", "<<info.startPos.frames(m_fps)<<"-"<<info.endPos.frames(m_fps);
- if (element.attribute("speed", "1.0").toDouble() != 1.0) {
+ if (element.attribute("speed", "1.0").toDouble() != 1.0 || element.attribute("strobe", "1").toInt() > 1) {
// We want a slowmotion producer
double speed = element.attribute("speed", "1.0").toDouble();
+ int strobe = element.attribute("strobe", "1").toInt();
QString url = QString::fromUtf8(prod->get("resource"));
url.append('?' + QString::number(speed));
+ if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
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);
+ if (strobe > 1) slowprod->set("strobe", strobe);
delete[] tmp;
QString id = prod->get("id");
if (id.contains('_')) id = id.section('_', 0, 0);
QString producerid = "slowmotion:" + id + ':' + QString::number(speed);
+ if (strobe > 1) producerid.append(':' + QString::number(strobe));
tmp = decodedString(producerid);
slowprod->set("id", tmp);
delete[] tmp;
}
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);
-
+ int newIndex = trackPlaylist.insert_at((int) info.startPos.frames(m_fps), clip, 1);
+ delete clip;
/*if (QString(prod->get("transparency")).toInt() == 1)
mltAddClipTransparency(info, info.track - 1, QString(prod->get("id")).toInt());*/
}
Mlt::Service clipService(original->get_service());
Mlt::Service dupService(clip->get_service());
+ delete original;
+ delete clip;
int ct = 0;
Mlt::Filter *filter = clipService.filter(ct);
while (filter) {
}
//kDebug()<<"//// Deleting at: "<< (int) position.frames(m_fps) <<" --------------------------------------";
m_isBlocked = true;
- trackPlaylist.replace_with_blank(clipIndex);
+ Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
+ delete clip;
trackPlaylist.consolidate_blanks(0);
/*if (QString(clip.parent().get("transparency")).toInt() == 1)
mltDeleteTransparency((int) position.frames(m_fps), track, QString(clip.parent().get("id")).toInt());*/
if (!trackPlaylist.is_blank(clipIndex)) clipIndex --;
if (!trackPlaylist.is_blank(clipIndex)) kDebug() << "//// ERROR TRYING TO DELETE SPACE FROM " << insertPos;
int position = trackPlaylist.clip_start(clipIndex);
- int blankDuration = trackPlaylist.clip_length(clipIndex) - 1;
+ int blankDuration = trackPlaylist.clip_length(clipIndex);
diff = -diff;
- if (blankDuration - diff == 1)
+ if (blankDuration - diff == 0)
trackPlaylist.remove(clipIndex);
- else trackPlaylist.remove_region(position, diff - 1);
+ else trackPlaylist.remove_region(position, diff);
}
trackPlaylist.consolidate_blanks(0);
}
if (!trackPlaylist.is_blank(clipIndex)) clipIndex --;
if (!trackPlaylist.is_blank(clipIndex)) kDebug() << "//// ERROR TRYING TO DELETE SPACE FROM " << insertPos;
int position = trackPlaylist.clip_start(clipIndex);
- int blankDuration = trackPlaylist.clip_length(clipIndex) - 1;
- if (diff + blankDuration == 1)
+ int blankDuration = trackPlaylist.clip_length(clipIndex);
+ if (diff + blankDuration == 0)
trackPlaylist.remove(clipIndex);
- else trackPlaylist.remove_region(position, - diff - 1);
+ else trackPlaylist.remove_region(position, - diff);
}
trackPlaylist.consolidate_blanks(0);
}
}
}
-int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod)
+int Render::mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, int strobe, Mlt::Producer *prod)
{
m_isBlocked = true;
int newLength = 0;
QString serv = clipparent.get("mlt_service");
QString id = clipparent.get("id");
//kDebug() << "CLIP SERVICE: " << serv;
- if (serv == "avformat" && speed != 1.0) {
+ if (serv == "avformat" && (speed != 1.0 || strobe > 1)) {
mlt_service_lock(service.get_service());
QString url = QString::fromUtf8(clipparent.get("resource"));
url.append('?' + QString::number(speed));
+ if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
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);
+ if (strobe > 1) slowprod->set("strobe", strobe);
delete[] tmp;
QString producerid = "slowmotion:" + id + ':' + QString::number(speed);
+ if (strobe > 1) producerid.append(':' + QString::number(strobe));
tmp = decodedString(producerid);
slowprod->set("id", tmp);
delete[] tmp;
m_slowmotionProducers.insert(url, slowprod);
}
- trackPlaylist.replace_with_blank(clipIndex);
+ Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
+ delete clip;
trackPlaylist.consolidate_blanks(0);
// Check that the blank space is long enough for our new duration
clipIndex = trackPlaylist.get_clip_index_at(startPos);
// move all effects to the correct producer
mltPasteEffects(clip, cut);
- trackPlaylist.insert_at(startPos, *cut, 1);
+ trackPlaylist.insert_at(startPos, cut, 1);
+ delete cut;
clipIndex = trackPlaylist.get_clip_index_at(startPos);
newLength = trackPlaylist.clip_length(clipIndex);
mlt_service_unlock(service.get_service());
- } else if (speed == 1.0) {
+ } else if (speed == 1.0 && strobe < 2) {
mlt_service_lock(service.get_service());
- trackPlaylist.replace_with_blank(clipIndex);
+ Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
+ delete clip;
trackPlaylist.consolidate_blanks(0);
// Check that the blank space is long enough for our new duration
// move all effects to the correct producer
mltPasteEffects(clip, cut);
- trackPlaylist.insert_at(startPos, *cut, 1);
+ trackPlaylist.insert_at(startPos, cut, 1);
+ delete cut;
clipIndex = trackPlaylist.get_clip_index_at(startPos);
newLength = trackPlaylist.clip_length(clipIndex);
mlt_service_unlock(service.get_service());
QString url = QString::fromUtf8(clipparent.get("resource"));
url = url.section('?', 0, 0);
url.append('?' + QString::number(speed));
+ if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
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;
+ slowprod->set("strobe", strobe);
QString producerid = "slowmotion:" + id.section(':', 1, 1) + ':' + QString::number(speed);
+ if (strobe > 1) producerid.append(':' + QString::number(strobe));
tmp = decodedString(producerid);
slowprod->set("id", tmp);
delete[] tmp;
m_slowmotionProducers.insert(url, slowprod);
}
- trackPlaylist.replace_with_blank(clipIndex);
+ Mlt::Producer *clip = trackPlaylist.replace_with_blank(clipIndex);
+ delete clip;
trackPlaylist.consolidate_blanks(0);
GenTime oldDuration = GenTime(clipLength, m_fps);
- GenTime newDuration = oldDuration * oldspeed / speed;
+ GenTime newDuration = oldDuration * (oldspeed / speed);
// Check that the blank space is long enough for our new duration
clipIndex = trackPlaylist.get_clip_index_at(startPos);
// move all effects to the correct producer
mltPasteEffects(clip, cut);
- trackPlaylist.insert_at(startPos, *cut, 1);
+ trackPlaylist.insert_at(startPos, cut, 1);
+ delete cut;
clipIndex = trackPlaylist.get_clip_index_at(startPos);
newLength = trackPlaylist.clip_length(clipIndex);
return success;
}
Mlt::Service clipService(clip->get_service());
+ delete clip;
// if (tag.startsWith("ladspa")) tag = "ladspa";
m_isBlocked = true;
int ct = 0;
}
Mlt::Service clipService(clip->get_service());
m_isBlocked = true;
-
+ delete clip;
// temporarily remove all effects after insert point
QList <Mlt::Filter *> filtersList;
const int filter_ix = params.paramValue("kdenlive_ix").toInt();
return false;
}
Mlt::Service clipService(clip->get_service());
+ delete clip;
m_isBlocked = true;
int ct = 0;
Mlt::Filter *filter = clipService.filter(ct);
return;
}
Mlt::Service clipService(clip->get_service());
+ delete clip;
m_isBlocked = true;
int ct = 0;
QList <Mlt::Filter *> filtersList;
// If this is not the last clip in playlist
if (trackPlaylist.is_blank(clipIndex)) {
int blankStart = trackPlaylist.clip_start(clipIndex);
- int blankDuration = trackPlaylist.clip_length(clipIndex) - 1;
+ int blankDuration = trackPlaylist.clip_length(clipIndex);
if (diff > blankDuration) kDebug() << "// ERROR blank clip is not large enough to get back required space!!!";
- if (diff - blankDuration == 1) {
+ if (diff - blankDuration == 0) {
trackPlaylist.remove(clipIndex);
- } else trackPlaylist.remove_region(blankStart, diff - 1);
+ } else trackPlaylist.remove_region(blankStart, diff);
} else {
kDebug() << "/// RESIZE ERROR, NXT CLIP IS NOT BLK: " << clipIndex;
}
Mlt::Producer trackProducer(tractor.track(track));
Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
int clipIndex = trackPlaylist.get_clip_index_at(pos + 1);
- Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
- if (clipProducer.is_blank()) {
+ Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex);
+ if (clipProducer->is_blank()) {
kDebug() << "// ERROR UPDATING CLIP PROD";
+ delete clipProducer;
mlt_service_unlock(m_mltConsumer->get_service());
m_isBlocked--;
return;
}
- Mlt::Producer *clip = prod->cut(clipProducer.get_in(), clipProducer.get_out());
+ Mlt::Producer *clip = prod->cut(clipProducer->get_in(), clipProducer->get_out());
// move all effects to the correct producer
- mltPasteEffects(&clipProducer, clip);
-
+ mltPasteEffects(clipProducer, clip);
trackPlaylist.insert_at(pos, clip, 1);
+ delete clip;
+ delete clipProducer;
mlt_service_unlock(m_mltConsumer->get_service());
m_isBlocked--;
}
kDebug() << "////// LOOKING FOR CLIP TO MOVE, INDEX: " << clipIndex;
bool checkLength = false;
if (endTrack == startTrack) {
- Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
- if (!trackPlaylist.is_blank_at(moveEnd) || clipProducer.is_blank()) {
+ Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex);
+ if (!trackPlaylist.is_blank_at(moveEnd) || clipProducer->is_blank()) {
// error, destination is not empty
if (!trackPlaylist.is_blank_at(moveEnd)) trackPlaylist.insert_at(moveStart, clipProducer, 1);
+ delete clipProducer;
//int ix = trackPlaylist.get_clip_index_at(moveEnd);
kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd;
mlt_service_unlock(service.get_service());
} else {
trackPlaylist.consolidate_blanks(0);
int newIndex = trackPlaylist.insert_at(moveEnd, clipProducer, 1);
+ delete clipProducer;
/*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
mltMoveTransparency(moveStart, moveEnd, startTrack, endTrack, QString(clipProducer.parent().get("id")).toInt());
}*/
m_isBlocked--;
return false;
} else {
- Mlt::Producer clipProducer(trackPlaylist.replace_with_blank(clipIndex));
- if (clipProducer.is_blank()) {
+ Mlt::Producer *clipProducer = trackPlaylist.replace_with_blank(clipIndex);
+ if (clipProducer->is_blank()) {
// error, destination is not empty
//int ix = trackPlaylist.get_clip_index_at(moveEnd);
+ delete clipProducer;
kDebug() << "// ERROR MOVING CLIP TO : " << moveEnd;
mlt_service_unlock(service.get_service());
m_isBlocked--;
destTrackPlaylist.consolidate_blanks(1);
Mlt::Producer *clip;
// check if we are moving a slowmotion producer
- QString serv = clipProducer.parent().get("mlt_service");
- QString currentid = clipProducer.parent().get("id");
+ QString serv = clipProducer->parent().get("mlt_service");
+ QString currentid = clipProducer->parent().get("id");
if (serv == "framebuffer" || currentid.endsWith("_video")) {
- clip = &clipProducer;
+ clip = clipProducer;
} else {
if (prod == NULL) {
// Special case: prod is null when using placeholder clips.
// in that case, use the producer existing in playlist. Note that
// it will bypass the one producer per track logic and might cause
// Sound cracks if clip is moved so that it overlaps another copy of itself
- clip = clipProducer.cut(clipProducer.get_in(), clipProducer.get_out());
- } else clip = prod->cut(clipProducer.get_in(), clipProducer.get_out());
+ clip = clipProducer->cut(clipProducer->get_in(), clipProducer->get_out());
+ } else clip = prod->cut(clipProducer->get_in(), clipProducer->get_out());
}
// move all effects to the correct producer
- mltPasteEffects(&clipProducer, clip);
+ mltPasteEffects(clipProducer, clip);
int newIndex = destTrackPlaylist.insert_at(moveEnd, clip, 1);
+ delete clip;
+ clip = NULL;
+ if (clipProducer) delete clipProducer;
destTrackPlaylist.consolidate_blanks(0);
/*if (QString(clipProducer.parent().get("transparency")).toInt() == 1) {
kDebug() << "//////// moving clip transparency";
if (id.startsWith("slowmotion:") && !nprod->is_blank()) {
// this is a slowmotion producer, add it to the list
QString url = QString::fromUtf8(nprod->get("resource"));
+ int strobe = nprod->get_int("strobe");
+ if (strobe > 1) url.append("&strobe=" + QString::number(strobe));
if (!m_slowmotionProducers.contains(url)) {
m_slowmotionProducers.insert(url, nprod);
}
/** Gives the aspect ratio of the consumer */
double consumerRatio() const;
- void askForRefresh();
void doRefresh();
/** Save current producer frame as image */
to the clip and 0.6 is the speed in percents. The newly created producer will have it's
"id" parameter set to: "slowmotion:parentid:speed", where parentid is the id of the original clip
in the ClipManager list and speed is the current speed */
- int mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, Mlt::Producer *prod);
+ int mltChangeClipSpeed(ItemInfo info, double speed, double oldspeed, int strobe, Mlt::Producer *prod);
QList <Mlt::Producer *> producersList();
void updatePreviewSettings();
Mlt::Producer *m_blackClip;
QString m_activeProfile;
- QTimer *m_refreshTimer;
QTimer *m_osdTimer;
/** A human-readable description of this renderer. */
#include <QKeyEvent>
#include <QPushButton>
#include <QPixmap>
-#include <QTimer>
+
StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) :
QWidget(parent),
m_state(Default),
m_illumination(-64),
m_minTextHeight(-1),
- m_timer(0),
m_closeButton(0)
{
setMinimumHeight(KIconLoader::SizeSmall);
palette.setColor(QPalette::Background, Qt::transparent);
setPalette(palette);
- m_timer = new QTimer(this);
- connect(m_timer, SIGNAL(timeout()), this, SLOT(timerDone()));
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(timerDone()));
m_closeButton = new QPushButton(i18nc("@action:button", "Close"), this);
m_closeButton->hide();
m_illumination = -64;
m_state = Default;
- m_timer->stop();
+ m_timer.stop();
const char* iconName = 0;
QPixmap pixmap;
case ErrorMessage:
iconName = "dialog-warning";
- m_timer->start(100);
+ m_timer.start(100);
m_state = Illuminate;
m_closeButton->hide();
break;
case MltError:
iconName = "dialog-close";
- m_timer->start(100);
+ m_timer.start(100);
m_state = Illuminate;
updateCloseButtonPosition();
m_closeButton->show();
update();
} else {
m_state = Illuminated;
- m_timer->start(1500);
+ m_timer.start(1500);
}
break;
}
// start desaturation
if (m_type != MltError) {
m_state = Desaturate;
- m_timer->start(80);
+ m_timer.start(80);
}
break;
}
if (m_illumination < -128) {
m_illumination = 0;
m_state = Default;
- m_timer->stop();
+ m_timer.stop();
setMessage(QString(), DefaultMessage);
} else {
m_illumination -= 5;
#define STATUSBARMESSAGELABEL_H
-#include <QtCore/QList>
-#include <QtGui/QPixmap>
+#include <QList>
+#include <QPixmap>
+#include <QWidget>
+#include <QTimer>
-#include <QtGui/QWidget>
#include <definitions.h>
class QPaintEvent;
class QResizeEvent;
class QPushButton;
-class QTimer;
/**
* @brief Represents a message text label as part of the status bar.
State m_state;
int m_illumination;
int m_minTextHeight;
- QTimer* m_timer;
+ QTimer m_timer;
QString m_text;
QList<QString> m_pendingMessages;
QPixmap m_pixmap;
}
-bool TitleDocument::saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
+bool TitleDocument::saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double out)
{
if (!m_scene)
return false;
QDomDocument doc = xml(startv, endv);
+ doc.documentElement().setAttribute("out", out);
KTemporaryFile tmpfile;
if (!tmpfile.open()) {
kWarning() << "///// CANNOT CREATE TMP FILE in: " << tmpfile.fileName();
return KIO::NetAccess::upload(tmpfile.fileName(), url, 0);
}
-int TitleDocument::loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
+int TitleDocument::loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double *out)
{
QString tmpfile;
QDomDocument doc;
} else
return -1;
KIO::NetAccess::removeTempFile(tmpfile);
- return loadFromXml(doc, startv, endv);
+ return loadFromXml(doc, startv, endv, out);
}
return -1;
}
-int TitleDocument::loadFromXml(QDomDocument doc, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv)
+int TitleDocument::loadFromXml(QDomDocument doc, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double *out)
{
QDomNodeList titles = doc.elementsByTagName("kdenlivetitle");
+
+ //TODO: get default title duration instead of hardcoded one
+ if (doc.documentElement().hasAttribute("out"))
+ *out = doc.documentElement().attribute("out").toDouble();
+ else
+ *out = 5000;
+
int maxZValue = 0;
if (titles.size()) {
public:
TitleDocument();
void setScene(QGraphicsScene* scene);
- bool saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv);
- int loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv);
+ bool saveDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double out);
+ int loadDocument(const KUrl& url, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double *out);
QDomDocument xml(QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv);
- int loadFromXml(QDomDocument doc, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv);
+ int loadFromXml(QDomDocument doc, QGraphicsPolygonItem* startv, QGraphicsPolygonItem* endv, double *out);
/** \brief Get the background color (incl. alpha) from the document, if possibly
* \returns The background color of the document, inclusive alpha. If none found, returns (0,0,0,0) */
QColor getBackgroundColor();
const int TEXTITEM = 8;
static bool insertingValues = false;
-TitleWidget::TitleWidget(KUrl url, QString projectTitlePath, Render *render, QWidget *parent) :
+TitleWidget::TitleWidget(KUrl url, Timecode tc, QString projectTitlePath, Render *render, QWidget *parent) :
QDialog(parent),
Ui::TitleWidget_UI(),
m_startViewport(NULL),
m_render(render),
m_count(0),
m_unicodeDialog(new UnicodeDialog(UnicodeDialog::InputHex)),
- m_projectTitlePath(projectTitlePath)
+ m_projectTitlePath(projectTitlePath),
+ m_tc(tc)
{
setupUi(this);
setFont(KGlobalSettings::toolBarFont());
m_frameHeight = render->renderHeight();
showToolbars(TITLE_NONE);
+ //TODO: get default title duration instead of hardcoded one
+ title_duration->setText(m_tc.getTimecode(GenTime(5000 / 1000.0), m_render->fps()));
+
connect(kcolorbutton, SIGNAL(clicked()), this, SLOT(slotChangeBackground())) ;
connect(horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(slotChangeBackground())) ;
kDebug() << "// TITLE WIDGWT: " << graphicsView->viewport()->width() << "x" << graphicsView->viewport()->height();
//toolBox->setItemEnabled(2, false);
if (!url.isEmpty()) {
- m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport) + 1;
+ double out;
+ m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport, &out) + 1;
+ title_duration->setText(m_tc.getTimecode(GenTime(out), m_render->fps()));
slotSelectTool();
} else {
slotTextTool();
if (items.at(i)->zValue() > -1000) delete items.at(i);
}
m_scene->clearTextSelection();
- m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport) + 1;
+ double out;
+ m_count = m_titledocument.loadDocument(url, m_startViewport, m_endViewport, &out) + 1;
+ title_duration->setText(m_tc.getTimecode(GenTime(out / 1000.0), m_render->fps()));
insertingValues = true;
startViewportX->setValue(m_startViewport->data(0).toInt());
startViewportY->setValue(m_startViewport->data(1).toInt());
{
if (url.isEmpty()) url = KFileDialog::getSaveUrl(KUrl(m_projectTitlePath), "*.kdenlivetitle", this, i18n("Save Title"));
if (!url.isEmpty()) {
- if (m_titledocument.saveDocument(url, m_startViewport, m_endViewport) == false)
+ if (m_titledocument.saveDocument(url, m_startViewport, m_endViewport, GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).ms()) == false)
KMessageBox::error(this, i18n("Cannot write to file %1", url.path()));
}
}
QDomDocument TitleWidget::xml()
{
QDomDocument doc = m_titledocument.xml(m_startViewport, m_endViewport);
+ doc.documentElement().setAttribute("out", GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).ms());
if (cropImage->isChecked()) {
doc.documentElement().setAttribute("crop", 1);
}
return doc;
}
+int TitleWidget::duration() const
+{
+ return GenTime(m_tc.getFrameCount(title_duration->text(), m_render->fps()), m_render->fps()).frames(m_render->fps());
+}
+
void TitleWidget::setXml(QDomDocument doc)
{
- m_count = m_titledocument.loadFromXml(doc, m_startViewport, m_endViewport);
+ double out;
+ m_count = m_titledocument.loadFromXml(doc, m_startViewport, m_endViewport, &out);
+ kDebug() << "\n\n// TITLE OUT: " << out;
+ title_duration->setText(m_tc.getTimecode(GenTime(out / 1000.0), m_render->fps()));
+ /*if (doc.documentElement().hasAttribute("out")) {
+ GenTime duration = GenTime(doc.documentElement().attribute("out").toDouble() / 1000.0);
+ title_duration->setText(m_tc.getTimecode(duration, m_render->fps()));
+ }
+ else title_duration->setText(m_tc.getTimecode(GenTime(5000), m_render->fps()));*/
+
QDomElement e = doc.documentElement();
cropImage->setChecked(e.hasAttribute("crop"));
m_transformations.clear();
#include "renderer.h"
#include "graphicsscenerectmove.h"
#include "unicodedialog.h"
+#include "timecode.h"
#include <QMap>
#include <QSignalMapper>
public:
/** \brief Constructor
* \param projectPath Path to use when user requests loading or saving of titles as .kdenlivetitle documents */
- TitleWidget(KUrl url, QString projectTitlePath, Render *render, QWidget *parent = 0);
+ TitleWidget(KUrl url, Timecode tc, QString projectTitlePath, Render *render, QWidget *parent = 0);
virtual ~TitleWidget();
QDomDocument xml();
void setXml(QDomDocument doc);
*/
const QRect renderedRect();
+ /** \brief Get clip duration. */
+ int duration() const;
+
protected:
virtual void resizeEvent(QResizeEvent * event);
QAction *m_buttonLoad;
QAction *m_unicodeAction;
+
/** \brief Dialog for entering unicode in text fields */
UnicodeDialog *m_unicodeDialog;
/** project path for storing title clips */
QString m_projectTitlePath;
+ Timecode m_tc;
/** See http://doc.trolltech.com/4.5/signalsandslots.html#advanced-signals-and-slots-usage */
QSignalMapper *m_signalMapper;
QString idString = elem.attribute("producer");
QString id = idString;
double speed = 1.0;
+ int strobe = 1;
if (idString.startsWith("slowmotion")) {
id = idString.section(':', 1, 1);
speed = idString.section(':', 2, 2).toDouble();
+ strobe = idString.section(':', 3, 3).toInt();
+ if (strobe == 0) strobe = 1;
} else id = id.section('_', 0, 0);
DocClipBase *clip = m_doc->clipManager()->getClipById(id);
if (clip == NULL) {
clipinfo.cropStart = GenTime(in, 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_doc->fps(), speed, false);
+ ClipItem *item = new ClipItem(clip, clipinfo, m_doc->fps(), speed, strobe, false);
if (idString.endsWith("_video")) item->setVideoOnly(true);
else if (idString.endsWith("_audio")) item->setAudioOnly(true);
m_scene->addItem(item);
if (locked) item->setItemLocked(true);
clip->addReference();
position += (out - in + 1);
+ kDebug() << "/////////\n\n\n" << "CLIP SPEED: " << speed << ", " << strobe << "\n\n\n/////////////////////";
+ if (speed != 1.0 || strobe > 1) {
+ QDomElement speedeffect = MainWindow::videoEffects.getEffectByTag(QString(), "speed").cloneNode().toElement();
+ EffectsList::setParameter(speedeffect, "speed", QString::number((int)(100 * speed + 0.5)));
+ EffectsList::setParameter(speedeffect, "strobe", QString::number(strobe));
+ item->addEffect(speedeffect, false);
+ item->effectsCounter();
+ }
// parse clip effects
QDomNodeList effects = elem.childNodes();