Frei0rColoradjWidget::Frei0rColoradjWidget(Mlt::Filter filter, bool setDefaults, QWidget *parent) : QWidget(parent), ui(new Ui::Frei0rColoradjWidget), m_filter(filter) { ui->setupUi(this); ui->keepLumaCheckBox->hide(); m_defaultAction = 0.5; m_defaultLuma = false; m_defaultRGB = QColor::fromRgbF(0.5, 0.5, 0.5); if (setDefaults) { ui->modeComboBox->setCurrentIndex(2 * m_defaultAction); ui->keepLumaCheckBox->setChecked(m_defaultLuma); ui->wheel->setColor(m_defaultRGB); m_filter.set(kParamAction, m_defaultAction); m_filter.set(kParamKeepLuma, m_defaultLuma? 1 : 0); m_filter.set(kParamRed, m_defaultRGB.redF()); m_filter.set(kParamGreen, m_defaultRGB.greenF()); m_filter.set(kParamBlue, m_defaultRGB.blueF()); ui->preset->saveDefaultPreset(m_filter); } else { ui->modeComboBox->setCurrentIndex(2 * filter.get_double(kParamAction)); ui->keepLumaCheckBox->setChecked(filter.get_int(kParamKeepLuma)); ui->wheel->setColor(QColor::fromRgbF(filter.get_double(kParamRed), filter.get_double(kParamGreen), filter.get_double(kParamBlue))); } ui->preset->loadPresets(); m_filter.set(kParamLumaFormula, (MLT.profile().colorspace() == 709? kLumaFormula709 : kLumaFormula601)); }
void AttachedFiltersModel::add(QmlMetadata* meta) { if (!meta->allowMultiple()) { for (int i = 0; i < m_metaList.count(); i++) { const QmlMetadata* attachedMeta = m_metaList[i]; if (attachedMeta && meta->uniqueId() == attachedMeta->uniqueId()) { emit duplicateAddFailed(i); return; } } } int insertIndex = -1; int mltIndex = -1; Mlt::Filter* filter = new Mlt::Filter(MLT.profile(), meta->mlt_service().toUtf8().constData()); if (filter->is_valid()) { if (!meta->objectName().isEmpty()) filter->set(kShotcutFilterProperty, meta->objectName().toUtf8().constData()); // Put the filter after the last filter that is greater than or equal // in sort order. insertIndex = 0; for (int i = m_metaList.count() - 1; i >= 0; i--) { if (!sortIsLess(m_metaList[i], meta)) { insertIndex = i + 1; break; } } // Calculate the MLT index for the new filter. if (m_mltIndexMap.count() == 0) { mltIndex = m_producer->filter_count(); } else if (insertIndex == 0) { mltIndex = m_mltIndexMap[0]; } else { mltIndex = m_mltIndexMap[insertIndex -1] + 1; } beginInsertRows(QModelIndex(), insertIndex, insertIndex); if (MLT.isSeekable()) MLT.pause(); m_event->block(); m_producer->attach(*filter); m_producer->move_filter(m_producer->filter_count() - 1, mltIndex); m_event->unblock(); // Adjust MLT index map for indices that just changed. for (int i = 0; i < m_mltIndexMap.count(); i++) { if (m_mltIndexMap[i] >= mltIndex) { m_mltIndexMap[i] = m_mltIndexMap[i] + 1; } } m_mltIndexMap.insert(insertIndex, mltIndex); m_metaList.insert(insertIndex, meta); endInsertRows(); emit changed(); } else qWarning() << "Failed to load filter" << meta->mlt_service(); delete filter; }
bool EffectManager::enableEffects(const QList <int> &effectIndexes, bool disable, bool rememberState) { int ct = 0; bool success = false; Mlt::Filter *filter = m_producer.filter(ct); while (filter) { if (effectIndexes.isEmpty() || effectIndexes.contains(filter->get_int("kdenlive_ix"))) { //m_producer.lock(); if (rememberState) { if (disable && filter->get_int("disable") == 0) { filter->set("auto_disable", 1); filter->set("disable", (int) disable); } else if (!disable && filter->get_int("auto_disable") == 1) { filter->set("disable", (char*) NULL); filter->set("auto_disable", (char*) NULL); } } else { filter->set("disable", (int) disable); } success = true; //m_producer.unlock(); } delete filter; ct++; filter = m_producer.filter(ct); } return success; }
void AttachedFiltersModel::remove(int row) { Mlt::Filter* filter = filterForRow(row); if (filter && filter->is_valid()) { beginRemoveRows(QModelIndex(), row, row); MLT.pause(); m_producer->detach(*filter); m_rows--; endRemoveRows(); emit changed(); } delete filter; }
bool AttachedFiltersModel::setData(const QModelIndex& index, const QVariant& , int role) { if (role == Qt::CheckStateRole) { Mlt::Filter* filter = getFilter(index.row()); if (filter && filter->is_valid()) { filter->set("disable", !filter->get_int("disable")); emit changed(); emit dataChanged(createIndex(index.row(), 0), createIndex(index.row(), 0)); } delete filter; return true; } return false; }
void AttachedFiltersModel::calculateRows() { m_rows =-0; if (MLT.isPlaylist()) return; if (m_producer && m_producer->is_valid()) { int n = m_producer->filter_count(); while (n--) { Mlt::Filter* filter = m_producer->filter(n); if (filter && filter->is_valid() && !filter->get_int("_loader")) m_rows++; delete filter; } } }
bool AttachedFiltersModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (role == Qt::CheckStateRole) { Mlt::Filter* filter = filterForRow(index.row()); if (filter && filter->is_valid()) { double speed = MLT.producer()->get_speed(); MLT.pause(); filter->set("disable", !filter->get_int("disable")); MLT.play(speed); emit changed(); emit dataChanged(createIndex(index.row(), 0), createIndex(index.row(), 0)); } delete filter; return true; } return false; }
Mlt::Filter *AttachedFiltersModel::add(const QString& mlt_service, const QString& shotcutName) { Mlt::Filter* filter = new Mlt::Filter(MLT.profile(), mlt_service.toUtf8().constData()); if (filter->is_valid()) { if (!shotcutName.isEmpty()) filter->set("shotcut:filter", shotcutName.toUtf8().constData()); int count = rowCount(); beginInsertRows(QModelIndex(), count, count); MLT.pause(); m_producer->attach(*filter); m_rows++; endInsertRows(); emit changed(); } else qWarning() << "Failed to load filter" << mlt_service; return filter; }
void BinController::duplicateFilters(Mlt::Producer original, Mlt::Producer clone) { Mlt::Service clipService(original.get_service()); Mlt::Service dupService(clone.get_service()); //delete original; //delete clone; int ct = 0; Mlt::Filter *filter = clipService.filter(ct); while (filter) { // Only duplicate Kdenlive filters, and skip the fade in effects //fprintf(stderr, "CHKNG FILTER: %s\n", filter->get("kdenlive_id")); if (filter->is_valid()/* && strcmp(filter->get("kdenlive_id"), "") && strcmp(filter->get("kdenlive_id"), "fadein") && strcmp(filter->get("kdenlive_id"), "fade_from_black")*/) { // looks like there is no easy way to duplicate a filter, // so we will create a new one and duplicate its properties Mlt::Filter *dup = new Mlt::Filter(*original.profile(), filter->get("mlt_service")); if (dup && dup->is_valid()) { Mlt::Properties entries(filter->get_properties()); for (int i = 0; i < entries.count(); ++i) { dup->set(entries.get_name(i), entries.get(i)); } dupService.attach(*dup); } } ct++; filter = clipService.filter(ct); } }
QVariant AttachedFiltersModel::data(const QModelIndex &index, int role) const { if ( !m_producer || !m_producer->is_valid() || index.row() >= m_producer->filter_count()) return QVariant(); switch (role ) { case Qt::DisplayRole: { QVariant result; Mlt::Filter* filter = filterForRow(index.row()); if (filter && filter->is_valid()) { // Relabel by QML UI QmlMetadata* meta = MAIN.filtersDock()->qmlMetadataForService(filter); if (meta) result = meta->name(); // Fallback is raw mlt_service name else if (filter->get("mlt_service")) result = QString::fromUtf8(filter->get("mlt_service")); } // Relabel for widgets UIs if (result == "movit.blur" || result == "boxblur") result = tr("Blur"); else if (result == "movit.lift_gamma_gain" || result == "frei0r.coloradj_RGB") result = tr("Color Grading"); else if (result == "crop") result = tr("Crop"); else if (result == "movit.glow" || result == "frei0r.glow") result = tr("Glow"); else if (result == "movit.mirror" || result == "mirror") result = tr("Mirror"); else if (result == "webvfx") result = tr("Overlay HTML"); else if (result == "movit.sharpen" || result == "frei0r.sharpness") result = tr("Sharpen"); else if (result == "movit.white_balance" || result == "frei0r.colgate") result = tr("White Balance"); else if (result == "sox" && filter->get("use_peak")) result = tr("Normalize"); delete filter; return result; } case Qt::CheckStateRole: { Mlt::Filter* filter = filterForRow(index.row()); QVariant result = Qt::Unchecked; if (filter && filter->is_valid() && !filter->get_int("disable")) result = Qt::Checked; delete filter; return result; } break; default: break; } return QVariant(); }
void AttachedFiltersModel::reset(Mlt::Producer* producer) { beginResetModel(); m_event.reset(); if (producer && producer->is_valid()) m_producer.reset(new Mlt::Producer(producer)); else if (MLT.isClip()) m_producer.reset(new Mlt::Producer(MLT.producer())); else m_producer.reset(); m_metaList.clear(); m_mltIndexMap.clear(); if (m_producer && m_producer->is_valid()) { Mlt::Event* event = m_producer->listen("service-changed", this, (mlt_listener)AttachedFiltersModel::producerChanged); m_event.reset(event); int count = m_producer->filter_count(); for (int i = 0; i < count; i++) { Mlt::Filter* filter = m_producer->filter(i); if (filter && filter->is_valid() && !filter->get_int("_loader")) { QmlMetadata* newMeta = MAIN.filterController()->metadataForService(filter); int newIndex = m_metaList.count(); for (int j = newIndex - 1; j >= 0; j--) { const QmlMetadata* prevMeta = m_metaList[j]; if (sortIsLess(prevMeta, newMeta)) { newIndex = j; } else { break; } } m_metaList.insert(newIndex, newMeta); m_mltIndexMap.insert(newIndex, i); } delete filter; } } endResetModel(); emit trackTitleChanged(); emit isProducerSelectedChanged(); emit readyChanged(); }
int AttachedFiltersModel::indexForRow(int row) const { int result = -1; if (m_producer && m_producer->is_valid()) { int count = m_producer->filter_count(); int j = 0; for (int i = 0; i < count; i++) { Mlt::Filter* filter = m_producer->filter(i); if (filter && filter->is_valid() && !filter->get_int("_loader")) { if (j == row) { result = i; break; } j++; } delete filter; } } return result; }
MovitColorFilter::MovitColorFilter(Mlt::Filter filter, bool setDefaults, QWidget *parent) : QWidget(parent), ui(new Ui::MovitColorFilter), m_filter(filter) { ui->setupUi(this); Mlt::Filter f(MLT.profile(), "movit.lift_gamma_gain"); m_liftDefault = QColor::fromRgbF(f.get_double("lift_r"), f.get_double("lift_g"), f.get_double("lift_b")); m_gammaDefault = QColor::fromRgbF(f.get_double("gamma_r") / GAMMA_FACTOR, f.get_double("gamma_g") / GAMMA_FACTOR, f.get_double("gamma_b") / GAMMA_FACTOR); m_gainDefault = QColor::fromRgbF(f.get_double("gain_r") / GAIN_FACTOR, f.get_double("gain_g") / GAIN_FACTOR, f.get_double("gain_b") / GAIN_FACTOR); if (setDefaults) { ui->liftWheel->setColor(m_liftDefault); ui->gammaWheel->setColor(m_gammaDefault); ui->gainWheel->setColor(m_gainDefault); ui->preset->saveDefaultPreset(m_filter); } else { ui->liftWheel->setColor(QColor::fromRgbF(filter.get_double("lift_r"), filter.get_double("lift_g"), filter.get_double("lift_b"))); ui->gammaWheel->setColor(QColor::fromRgbF(filter.get_double("gamma_r") / GAMMA_FACTOR, filter.get_double("gamma_g") / GAMMA_FACTOR, filter.get_double("gamma_b") / GAMMA_FACTOR)); ui->gainWheel->setColor(QColor::fromRgbF(filter.get_double("gain_r") / GAIN_FACTOR, filter.get_double("gain_g") / GAIN_FACTOR, filter.get_double("gain_b") / GAIN_FACTOR)); } ui->preset->loadPresets(); }
bool EffectManager::removeEffect(int effectIndex, bool updateIndex) { m_producer.lock(); int ct = 0; bool success = false; Mlt::Filter *filter = m_producer.filter(ct); QList <Mlt::Filter *> filters; while (filter) { filters << filter; if ((effectIndex == -1 && strcmp(filter->get("kdenlive_id"), "")) || filter->get_int("kdenlive_ix") == effectIndex) { if (m_producer.detach(*filter) == 0) { success = true; } } else if (updateIndex) { // Adjust the other effects index if (filter->get_int("kdenlive_ix") > effectIndex) filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") - 1); ct++; } else ct++; filter = m_producer.filter(ct); } m_producer.unlock(); qDeleteAll(filters); return success; }
QVariant AttachedFiltersModel::data(const QModelIndex &index, int role) const { if ( !m_producer || !m_producer->is_valid() || index.row() >= m_producer->filter_count()) return QVariant(); switch (role ) { case Qt::DisplayRole: { QVariant result; const QmlMetadata* meta = m_metaList[index.row()]; if (meta) { result = meta->name(); } else { // Fallback is raw mlt_service name Mlt::Filter* filter = getFilter(index.row()); if (filter && filter->is_valid() && filter->get("mlt_service")) { result = QString::fromUtf8(filter->get("mlt_service")); } delete filter; } return result; } case Qt::CheckStateRole: { Mlt::Filter* filter = getFilter(index.row()); QVariant result = Qt::Unchecked; if (filter && filter->is_valid() && !filter->get_int("disable")) result = Qt::Checked; delete filter; return result; } break; case TypeDisplayRole: { QVariant result; const QmlMetadata* meta = m_metaList[index.row()]; if (meta && meta->isAudio()) { result = tr("Audio"); } else if (meta && meta->needsGPU()) { result = tr("GPU"); } else { result = tr("Video"); } return result; } break; default: break; } return QVariant(); }
WebvfxFilter::WebvfxFilter(Mlt::Filter filter, QWidget *parent) : QWidget(parent), ui(new Ui::WebvfxFilter), m_filter(filter) { ui->setupUi(this); QString resource = filter.get("resource"); if (resource.startsWith("plain:")) resource.remove(0, 6); ui->fileLabel->setText(QFileInfo(resource).fileName()); ui->fileLabel->setToolTip(resource); if (resource.isEmpty()) { ui->editButton->setDisabled(true); ui->reloadButton->setDisabled(true); } else { ui->newButton->setDisabled(true); ui->openButton->setDisabled(true); } m_filter.set_in_and_out(0, MLT.producer()->get_playtime() - 1); }
QVariant AttachedFiltersModel::data(const QModelIndex &index, int role) const { if ( !m_producer || !m_producer->is_valid() || index.row() >= m_producer->filter_count()) return QVariant(); switch (role ) { case Qt::DisplayRole: { QVariant result; Mlt::Filter* filter = filterForRow(index.row()); if (filter && filter->is_valid()) { // Relabel by QML UI QmlMetadata* meta = MAIN.filtersDock()->qmlMetadataForService(filter); if (meta) result = meta->name(); // Fallback is raw mlt_service name else if (filter->get("mlt_service")) result = QString::fromUtf8(filter->get("mlt_service")); } // Relabel for widgets UIs if (result == "movit.mirror" || result == "mirror") result = tr("Mirror"); delete filter; return result; } case Qt::CheckStateRole: { Mlt::Filter* filter = filterForRow(index.row()); QVariant result = Qt::Unchecked; if (filter && filter->is_valid() && !filter->get_int("disable")) result = Qt::Checked; delete filter; return result; } break; default: break; } return QVariant(); }
bool EffectManager::doAddFilter(EffectsParameterList params, int duration) { // create filter QString tag = params.paramValue(QStringLiteral("tag")); QLocale locale; ////qDebug() << " / / INSERTING EFFECT: " << tag << ", REGI: " << region; QString kfr = params.paramValue(QStringLiteral("keyframes")); if (!kfr.isEmpty()) { QStringList keyFrames = kfr.split(';', QString::SkipEmptyParts); char *starttag = qstrdup(params.paramValue(QStringLiteral("starttag"), QStringLiteral("start")).toUtf8().constData()); char *endtag = qstrdup(params.paramValue(QStringLiteral("endtag"), QStringLiteral("end")).toUtf8().constData()); ////qDebug() << "// ADDING KEYFRAME TAGS: " << starttag << ", " << endtag; //double max = params.paramValue("max").toDouble(); double min = params.paramValue(QStringLiteral("min")).toDouble(); double factor = params.paramValue(QStringLiteral("factor"), QStringLiteral("1")).toDouble(); double paramOffset = params.paramValue(QStringLiteral("offset"), QStringLiteral("0")).toDouble(); params.removeParam(QStringLiteral("starttag")); params.removeParam(QStringLiteral("endtag")); params.removeParam(QStringLiteral("keyframes")); params.removeParam(QStringLiteral("min")); params.removeParam(QStringLiteral("max")); params.removeParam(QStringLiteral("factor")); params.removeParam(QStringLiteral("offset")); // Special case, only one keyframe, means we want a constant value if (keyFrames.count() == 1) { Mlt::Filter *filter = new Mlt::Filter(*m_producer.profile(), qstrdup(tag.toUtf8().constData())); if (filter && filter->is_valid()) { filter->set("kdenlive_id", qstrdup(params.paramValue(QStringLiteral("id")).toUtf8().constData())); int x1 = keyFrames.at(0).section('=', 0, 0).toInt(); double y1 = keyFrames.at(0).section('=', 1, 1).toDouble(); for (int j = 0; j < params.count(); ++j) { filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData()); } filter->set("in", x1); ////qDebug() << "// ADDING KEYFRAME vals: " << min<<" / "<<max<<", "<<y1<<", factor: "<<factor; filter->set(starttag, locale.toString(((min + y1) - paramOffset) / factor).toUtf8().data()); m_producer.attach(*filter); delete filter; } else { delete[] starttag; delete[] endtag; //qDebug() << "filter is NULL"; m_producer.unlock(); return false; } } else for (int i = 0; i < keyFrames.size() - 1; ++i) { Mlt::Filter *filter = new Mlt::Filter(*m_producer.profile(), qstrdup(tag.toUtf8().constData())); if (filter && filter->is_valid()) { filter->set("kdenlive_id", qstrdup(params.paramValue(QStringLiteral("id")).toUtf8().constData())); int x1 = keyFrames.at(i).section('=', 0, 0).toInt(); double y1 = keyFrames.at(i).section('=', 1, 1).toDouble(); int x2 = keyFrames.at(i + 1).section('=', 0, 0).toInt(); double y2 = keyFrames.at(i + 1).section('=', 1, 1).toDouble(); if (x2 == -1) x2 = duration; // non-overlapping sections if (i > 0) { y1 += (y2 - y1) / (x2 - x1); ++x1; } for (int j = 0; j < params.count(); ++j) { filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData()); } filter->set("in", x1); filter->set("out", x2); ////qDebug() << "// ADDING KEYFRAME vals: " << min<<" / "<<max<<", "<<y1<<", factor: "<<factor; filter->set(starttag, locale.toString(((min + y1) - paramOffset) / factor).toUtf8().data()); filter->set(endtag, locale.toString(((min + y2) - paramOffset) / factor).toUtf8().data()); m_producer.attach(*filter); delete filter; } else { delete[] starttag; delete[] endtag; //qDebug() << "filter is NULL"; m_producer.unlock(); return false; } } delete[] starttag; delete[] endtag; } else { Mlt::Filter *filter; QString prefix; filter = new Mlt::Filter(*m_producer.profile(), qstrdup(tag.toUtf8().constData())); if (filter && filter->is_valid()) { filter->set("kdenlive_id", qstrdup(params.paramValue(QStringLiteral("id")).toUtf8().constData())); } else { //qDebug() << "filter is NULL"; m_producer.unlock(); return false; } params.removeParam(QStringLiteral("kdenlive_id")); if (params.paramValue(QStringLiteral("kdenlive:sync_in_out")) == QLatin1String("1")) { // This effect must sync in / out with parent clip //params.removeParam(QStringLiteral("_sync_in_out")); filter->set_in_and_out(m_producer.get_int("in"), m_producer.get_int("out")); } for (int j = 0; j < params.count(); ++j) { filter->set((prefix + params.at(j).name()).toUtf8().constData(), params.at(j).value().toUtf8().constData()); } if (tag == QLatin1String("sox")) { QString effectArgs = params.paramValue(QStringLiteral("id")).section('_', 1); params.removeParam(QStringLiteral("id")); params.removeParam(QStringLiteral("kdenlive_ix")); params.removeParam(QStringLiteral("tag")); params.removeParam(QStringLiteral("disable")); params.removeParam(QStringLiteral("region")); for (int j = 0; j < params.count(); ++j) { effectArgs.append(' ' + params.at(j).value()); } ////qDebug() << "SOX EFFECTS: " << effectArgs.simplified(); filter->set("effect", effectArgs.simplified().toUtf8().constData()); } // attach filter to the clip m_producer.attach(*filter); delete filter; } return true; }
bool EffectManager::moveEffect(int oldPos, int newPos) { int ct = 0; QList <Mlt::Filter *> filtersList; QList <Mlt::Filter *> toDelete; Mlt::Filter *filter = m_producer.filter(ct); if (newPos > oldPos) { bool found = false; while (filter) { toDelete << filter; if (!found && filter->get_int("kdenlive_ix") == oldPos) { filter->set("kdenlive_ix", newPos); filtersList.append(filter); m_producer.detach(*filter); filter = m_producer.filter(ct); while (filter && filter->get_int("kdenlive_ix") <= newPos) { filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") - 1); ct++; filter = m_producer.filter(ct); } found = true; } if (filter && filter->get_int("kdenlive_ix") > newPos) { filtersList.append(filter); m_producer.detach(*filter); } else ct++; filter = m_producer.filter(ct); } } else { while (filter) { toDelete << filter; if (filter->get_int("kdenlive_ix") == oldPos) { filter->set("kdenlive_ix", newPos); filtersList.append(filter); m_producer.detach(*filter); } else ct++; filter = m_producer.filter(ct); } ct = 0; filter = m_producer.filter(ct); while (filter) { toDelete << filter; int pos = filter->get_int("kdenlive_ix"); if (pos >= newPos) { if (pos < oldPos) filter->set("kdenlive_ix", pos + 1); filtersList.append(filter); m_producer.detach(*filter); } else ct++; filter = m_producer.filter(ct); } } for (int i = 0; i < filtersList.count(); ++i) { m_producer.attach(*(filtersList.at(i))); } qDeleteAll(toDelete); //TODO: check for success return true; }
bool EffectManager::editEffect(EffectsParameterList params, int duration, bool replaceEffect) { int index = params.paramValue(QStringLiteral("kdenlive_ix")).toInt(); QString tag = params.paramValue(QStringLiteral("tag")); if (!params.paramValue(QStringLiteral("keyframes")).isEmpty() || replaceEffect || tag.startsWith(QLatin1String("ladspa")) || tag == QLatin1String("sox") || tag == QLatin1String("autotrack_rectangle")) { // This is a keyframe effect, to edit it, we remove it and re-add it. if (removeEffect(index, false)) { return addEffect(params, duration); } } // find filter int ct = 0; Mlt::Filter *filter = m_producer.filter(ct); while (filter) { if (filter->get_int("kdenlive_ix") == index) { break; } delete filter; ct++; filter = m_producer.filter(ct); } if (!filter) { qDebug() << "WARINIG, FILTER FOR EDITING NOT FOUND, ADDING IT! " << index << ", " << tag; // filter was not found, it was probably a disabled filter, so add it to the correct place... bool success = addEffect(params, duration); return success; } ct = 0; QString ser = filter->get("mlt_service"); QList <Mlt::Filter *> filtersList; m_producer.lock(); if (ser != tag) { // Effect service changes, delete effect and re-add it m_producer.detach(*filter); delete filter; // Delete all effects after deleted one filter = m_producer.filter(ct); while (filter) { if (filter->get_int("kdenlive_ix") > index) { filtersList.append(filter); m_producer.detach(*filter); } else ct++; delete filter; filter = m_producer.filter(ct); } // re-add filter doAddFilter(params, duration); m_producer.unlock(); return true; } if (params.hasParam(QStringLiteral("kdenlive:sync_in_out"))) { if (params.paramValue(QStringLiteral("kdenlive:sync_in_out")) == QLatin1String("1")) { // This effect must sync in / out with parent clip //params.removeParam(QStringLiteral("sync_in_out")); Mlt::Producer prod(m_producer); filter->set_in_and_out(prod.get_in(), prod.get_out()); } else { // Reset in/out properties filter->set("in", (char*)NULL); filter->set("out", (char*)NULL); } } for (int j = 0; j < params.count(); ++j) { filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData()); } for (int j = 0; j < filtersList.count(); ++j) { m_producer.attach(*(filtersList.at(j))); } qDeleteAll(filtersList); m_producer.unlock(); delete filter; return true; }
bool EffectManager::addEffect(EffectsParameterList params, int duration) { bool updateIndex = false; const int filter_ix = params.paramValue(QStringLiteral("kdenlive_ix")).toInt(); int ct = 0; QList <Mlt::Filter *> filters; m_producer.lock(); Mlt::Filter *filter = m_producer.filter(ct); while (filter) { filters << filter; if (filter->get_int("kdenlive_ix") == filter_ix) { // A filter at that position already existed, so we will increase all indexes later updateIndex = true; break; } ct++; filter = m_producer.filter(ct); } if (params.paramValue(QStringLiteral("id")) == QLatin1String("speed")) { // special case, speed effect is not really inserted, we just update the other effects index (kdenlive_ix) ct = 0; filter = m_producer.filter(ct); while (filter) { filters << filter; if (filter->get_int("kdenlive_ix") >= filter_ix) { if (updateIndex) filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") + 1); } ct++; filter = m_producer.filter(ct); } m_producer.unlock(); qDeleteAll(filters); return true; } // temporarily remove all effects after insert point QList <Mlt::Filter *> filtersList; ct = 0; filter = m_producer.filter(ct); while (filter) { if (filter->get_int("kdenlive_ix") >= filter_ix) { filtersList.append(filter); m_producer.detach(*filter); } else ct++; filter = m_producer.filter(ct); } // Add new filter bool success = doAddFilter(params, duration); // re-add following filters for (int i = 0; i < filtersList.count(); ++i) { Mlt::Filter *filter = filtersList.at(i); if (updateIndex) filter->set("kdenlive_ix", filter->get_int("kdenlive_ix") + 1); m_producer.attach(*filter); } m_producer.unlock(); qDeleteAll(filters); qDeleteAll(filtersList); return success; }